diff --git a/extend/.gitignore b/extend/.gitignore deleted file mode 100755 index a3a0c8b..0000000 --- a/extend/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/extend/.htaccess b/extend/.htaccess new file mode 100644 index 0000000..3418e55 --- /dev/null +++ b/extend/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/extend/fast/Auth.php b/extend/fast/Auth.php new file mode 100644 index 0000000..2d7d677 --- /dev/null +++ b/extend/fast/Auth.php @@ -0,0 +1,288 @@ +<?php + +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2011 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: luofei614 <weibo.com/luofei614> +// +---------------------------------------------------------------------- +// | 修改者: anuo (本权限类在原3.2.3的基础上修改过来的) +// +---------------------------------------------------------------------- + +namespace fast; + +use think\Db; +use think\Config; +use think\Session; +use think\Request; +use think\Loader; + +/** + * 权限认证类 + * 功能特性: + * 1,是对规则进行认证,不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。 + * $auth=new Auth(); $auth->check('规则名称','用户id') + * 2,可以同时对多条规则进行认证,并设置多条规则的关系(or或者and) + * $auth=new Auth(); $auth->check('规则1,规则2','用户id','and') + * 第三个参数为and时表示,用户需要同时具有规则1和规则2的权限。 当第三个参数为or时,表示用户值需要具备其中一个条件即可。默认为or + * 3,一个用户可以属于多个用户组(think_auth_group_access表 定义了用户所属用户组)。我们需要设置每个用户组拥有哪些规则(think_auth_group 定义了用户组权限) + * 4,支持规则表达式。 + * 在think_auth_rule 表中定义一条规则,condition字段就可以定义规则表达式。 如定义{score}>5 and {score}<100 + * 表示用户的分数在5-100之间时这条规则才会通过。 + */ +class Auth +{ + + /** + * @var object 对象实例 + */ + protected static $instance; + + /** + * 当前请求实例 + * @var Request + */ + protected $request; + //默认配置 + protected $config = [ + 'auth_on' => 1, // 权限开关 + 'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。 + 'auth_group' => 'auth_group', // 用户组数据表名 + 'auth_group_access' => 'auth_group_access', // 用户-用户组关系表 + 'auth_rule' => 'auth_rule', // 权限规则表 + 'auth_user' => 'user', // 用户信息表 + ]; + + /** + * 类架构函数 + * Auth constructor. + */ + public function __construct() + { + if ($auth = Config::get('auth')) + { + $this->config = array_merge($this->config, $auth); + } + // 初始化request + $this->request = Request::instance(); + } + + /** + * 初始化 + * @access public + * @param array $options 参数 + * @return Auth + */ + public static function instance($options = []) + { + if (is_null(self::$instance)) + { + self::$instance = new static($options); + } + + return self::$instance; + } + + /** + * 检查权限 + * @param $name string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组 + * @param $uid int 认证用户的id + * @param string $relation 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证 + * @param string $mode 执行验证的模式,可分为url,normal + * @return bool 通过验证返回true;失败返回false + */ + public function check($name, $uid, $relation = 'or', $mode = 'url') + { + if (!$this->config['auth_on']) + { + return true; + } + // 获取用户需要验证的所有有效规则列表 + $rulelist = $this->getRuleList($uid); + if (in_array('*', $rulelist)) + return true; + + if (is_string($name)) + { + $name = strtolower($name); + if (strpos($name, ',') !== false) + { + $name = explode(',', $name); + } + else + { + $name = [$name]; + } + } + $list = []; //保存验证通过的规则名 + if ('url' == $mode) + { + $REQUEST = unserialize(strtolower(serialize($this->request->param()))); + } + foreach ($rulelist as $rule) + { + $query = preg_replace('/^.+\?/U', '', $rule); + if ('url' == $mode && $query != $rule) + { + parse_str($query, $param); //解析规则中的param + $intersect = array_intersect_assoc($REQUEST, $param); + $rule = preg_replace('/\?.*$/U', '', $rule); + if (in_array($rule, $name) && $intersect == $param) + { + //如果节点相符且url参数满足 + $list[] = $rule; + } + } + else + { + if (in_array($rule, $name)) + { + $list[] = $rule; + } + } + } + if ('or' == $relation && !empty($list)) + { + return true; + } + $diff = array_diff($name, $list); + if ('and' == $relation && empty($diff)) + { + return true; + } + + return false; + } + + /** + * 根据用户id获取用户组,返回值为数组 + * @param $uid int 用户id + * @return array 用户所属的用户组 array( + * array('uid'=>'用户id','group_id'=>'用户组id','name'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'), + * ...) + */ + public function getGroups($uid) + { + static $groups = []; + if (isset($groups[$uid])) + { + return $groups[$uid]; + } + // 转换表名 + $auth_group_access = Loader::parseName($this->config['auth_group_access'], 1); + $auth_group = Loader::parseName($this->config['auth_group'], 1); + // 执行查询 + $user_groups = Db::view($auth_group_access, 'uid,group_id') + ->view($auth_group, 'id,pid,name,rules', "{$auth_group_access}.group_id={$auth_group}.id", 'LEFT') + ->where("{$auth_group_access}.uid='{$uid}' and {$auth_group}.status='normal'") + ->select(); + $groups[$uid] = $user_groups ? : []; + + return $groups[$uid]; + } + + /** + * 获得权限规则列表 + * @param integer $uid 用户id + * @return array + */ + public function getRuleList($uid) + { + static $_rulelist = []; //保存用户验证通过的权限列表 + if (isset($_rulelist[$uid])) + { + return $_rulelist[$uid]; + } + if (2 == $this->config['auth_type'] && Session::has('_rule_list_' . $uid)) + { + return Session::get('_rule_list_' . $uid); + } + + // 读取用户规则节点 + $ids = $this->getRuleIds($uid); + if (empty($ids)) + { + $_rulelist[$uid] = []; + return []; + } + + // 筛选条件 + $where = [ + 'status' => 'normal' + ]; + if (!in_array('*', $ids)) + { + $where['id'] = ['in', $ids]; + } + //读取用户组所有权限规则 + $rules = Db::name($this->config['auth_rule'])->where($where)->field('id,condition,name,ismenu')->select(); + //循环规则,判断结果。 + $rulelist = []; // + foreach ($rules as $rule) + { + //超级管理员无需验证condition + if (!empty($rule['condition']) && !in_array('*', $ids)) + { + //根据condition进行验证 + $user = $this->getUserInfo($uid); //获取用户信息,一维数组 + $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']); + @(eval('$condition=(' . $command . ');')); + if ($condition) + { + $rulelist[$rule['id']] = strtolower($rule['name']); + } + } + else + { + //只要存在就记录 + $rulelist[$rule['id']] = strtolower($rule['name']); + } + } + $_rulelist[$uid] = $rulelist; + + //登录验证则需要保存规则列表 + if (2 == $this->config['auth_type']) + { + //规则列表结果保存到session + Session::set('_rule_list_' . $uid, $rulelist); + } + return array_unique($rulelist); + } + + public function getRuleIds($uid) + { + //读取用户所属用户组 + $groups = $this->getGroups($uid); + $ids = []; //保存用户所属用户组设置的所有权限规则id + foreach ($groups as $g) + { + $ids = array_merge($ids, explode(',', trim($g['rules'], ','))); + } + $ids = array_unique($ids); + return $ids; + } + + /** + * 获得用户资料 + * @param $uid + * @return mixed + */ + protected function getUserInfo($uid) + { + static $user_info = []; + + $user = Db::name($this->config['auth_user']); + // 获取用户表主键 + $_pk = is_string($user->getPk()) ? $user->getPk() : 'uid'; + if (!isset($user_info[$uid])) + { + $user_info[$uid] = $user->where($_pk, $uid)->find(); + } + + return $user_info[$uid]; + } + +} diff --git a/extend/fast/Date.php b/extend/fast/Date.php new file mode 100644 index 0000000..8e84d04 --- /dev/null +++ b/extend/fast/Date.php @@ -0,0 +1,287 @@ +<?php + +namespace fast; + +/** + * 日期时间处理类 + */ +class Date +{ + + const YEAR = 31536000; + const MONTH = 2592000; + const WEEK = 604800; + const DAY = 86400; + const HOUR = 3600; + const MINUTE = 60; + + /** + * 计算两个时区间相差的时长,单位为秒 + * + * $seconds = self::offset('America/Chicago', 'GMT'); + * + * [!!] A list of time zones that PHP supports can be found at + * <http://php.net/timezones>. + * + * @param string $remote timezone that to find the offset of + * @param string $local timezone used as the baseline + * @param mixed $now UNIX timestamp or date string + * @return integer + */ + public static function offset($remote, $local = NULL, $now = NULL) + { + if ($local === NULL) + { + // Use the default timezone + $local = date_default_timezone_get(); + } + if (is_int($now)) + { + // Convert the timestamp into a string + $now = date(DateTime::RFC2822, $now); + } + // Create timezone objects + $zone_remote = new DateTimeZone($remote); + $zone_local = new DateTimeZone($local); + // Create date objects from timezones + $time_remote = new DateTime($now, $zone_remote); + $time_local = new DateTime($now, $zone_local); + // Find the offset + $offset = $zone_remote->getOffset($time_remote) - $zone_local->getOffset($time_local); + return $offset; + } + + /** + * 计算两个时间戳之间相差的时间 + * + * $span = self::span(60, 182, 'minutes,seconds'); // array('minutes' => 2, 'seconds' => 2) + * $span = self::span(60, 182, 'minutes'); // 2 + * + * @param int $remote timestamp to find the span of + * @param int $local timestamp to use as the baseline + * @param string $output formatting string + * @return string when only a single output is requested + * @return array associative list of all outputs requested + */ + public static function span($remote, $local = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds') + { + // Normalize output + $output = trim(strtolower((string) $output)); + if (!$output) + { + // Invalid output + return FALSE; + } + // Array with the output formats + $output = preg_split('/[^a-z]+/', $output); + // Convert the list of outputs to an associative array + $output = array_combine($output, array_fill(0, count($output), 0)); + // Make the output values into keys + extract(array_flip($output), EXTR_SKIP); + if ($local === NULL) + { + // Calculate the span from the current time + $local = time(); + } + // Calculate timespan (seconds) + $timespan = abs($remote - $local); + if (isset($output['years'])) + { + $timespan -= self::YEAR * ($output['years'] = (int) floor($timespan / self::YEAR)); + } + if (isset($output['months'])) + { + $timespan -= self::MONTH * ($output['months'] = (int) floor($timespan / self::MONTH)); + } + if (isset($output['weeks'])) + { + $timespan -= self::WEEK * ($output['weeks'] = (int) floor($timespan / self::WEEK)); + } + if (isset($output['days'])) + { + $timespan -= self::DAY * ($output['days'] = (int) floor($timespan / self::DAY)); + } + if (isset($output['hours'])) + { + $timespan -= self::HOUR * ($output['hours'] = (int) floor($timespan / self::HOUR)); + } + if (isset($output['minutes'])) + { + $timespan -= self::MINUTE * ($output['minutes'] = (int) floor($timespan / self::MINUTE)); + } + // Seconds ago, 1 + if (isset($output['seconds'])) + { + $output['seconds'] = $timespan; + } + if (count($output) === 1) + { + // Only a single output was requested, return it + return array_pop($output); + } + // Return array + return $output; + } + + /** + * 格式化 UNIX 时间戳为人易读的字符串 + * + * @param int Unix 时间戳 + * @param mixed $local 本地时间 + * + * @return string 格式化的日期字符串 + */ + public static function human($remote, $local = null) + { + $timediff = (is_null($local) || $local ? time() : $local) - $remote; + $chunks = array( + array(60 * 60 * 24 * 365, 'year'), + array(60 * 60 * 24 * 30, 'month'), + array(60 * 60 * 24 * 7, 'week'), + array(60 * 60 * 24, 'day'), + array(60 * 60, 'hour'), + array(60, 'minute'), + array(1, 'second') + ); + + for ($i = 0, $j = count($chunks); $i < $j; $i++) + { + $seconds = $chunks[$i][0]; + $name = $chunks[$i][1]; + if (($count = floor($timediff / $seconds)) != 0) + { + break; + } + } + return __("%d {$name}%s ago", $count, ($count > 1 ? 's' : '')); + } + + /** + * 判断Unix时间是否满足Cron指定的执行条件 + * + * @param string $cron Crontab格式 + * @param string $time 时间,默认为当前时间 + * @return boolean + */ + public static function cron($cron, $time = null) + { + $time = is_null($time) ? time() : $time; + $cron_parts = explode(' ', $cron); + if (count($cron_parts) != 5) + { + return false; + } + list($min, $hour, $day, $mon, $week) = explode(' ', $cron); + $to_check = array('min' => 'i', 'hour' => 'G', 'day' => 'j', 'mon' => 'n', 'week' => 'w'); + $ranges = array( + 'min' => '0-59', + 'hour' => '0-23', + 'day' => '1-31', + 'mon' => '1-12', + 'week' => '0-6', + ); + + foreach ($to_check as $part => $c) + { + $val = $$part; + $values = []; + if (strpos($val, '/') !== false) + { + //Get the range and step + list($range, $steps) = explode('/', $val); + //Now get the start and stop + if ($range == '*') + { + $range = $ranges[$part]; + } + list($start, $stop) = explode('-', $range); + for ($i = $start; $i <= $stop; $i = $i + $steps) + { + $values[] = $i; + } + } + else + { + $k = explode(',', $val); + foreach ($k as $v) + { + if (strpos($v, '-') !== false) + { + list($start, $stop) = explode('-', $v); + + for ($i = $start; $i <= $stop; $i++) + { + $values[] = $i; + } + } + else + { + $values[] = $v; + } + } + } + if (!in_array(date($c, $time), $values) and ( strval($val) != '*')) + { + return false; + } + } + return true; + } + + /** + * 获取一个基于时间偏移的Unix时间戳 + * + * @param string $type 时间类型,默认为day,可选minute,hour,day,week,month,quarter,year + * @param int $offset 时间偏移量 默认为0,正数表示当前type之后,负数表示当前type之前 + * @param string $position 时间的开始或结束,默认为begin,可选前(begin,start,first,front),end + * @param int $year 基准年,默认为null,即以当前年为基准 + * @param int $month 基准月,默认为null,即以当前月为基准 + * @param int $day 基准天,默认为null,即以当前天为基准 + * @param int $hour 基准小时,默认为null,即以当前年小时基准 + * @param int $minute 基准分钟,默认为null,即以当前分钟为基准 + * @return int 处理后的Unix时间戳 + */ + public static function unixtime($type = 'day', $offset = 0, $position = 'begin', $year = null, $month = null, $day = null, $hour = null, $minute = null) + { + $year = is_null($year) ? date('Y') : $year; + $month = is_null($month) ? date('m') : $month; + $day = is_null($day) ? date('d') : $day; + $hour = is_null($hour) ? date('H') : $hour; + $minute = is_null($minute) ? date('i') : $minute; + $position = in_array($position, array('begin', 'start', 'first', 'front')); + + switch ($type) + { + case 'minute': + $time = $position ? mktime($hour, $minute + $offset, 0, $month, $day, $year) : mktime($hour, $minute + $offset, 59, $month, $day, $year); + break; + case 'hour': + $time = $position ? mktime($hour + $offset, 0, 0, $month, $day, $year) : mktime($hour + $offset, 59, 59, $month, $day, $year); + break; + case 'day': + $time = $position ? mktime(0, 0, 0, $month, $day + $offset, $year) : mktime(23, 59, 59, $month, $day + $offset, $year); + break; + case 'week': + $time = $position ? + mktime(0, 0, 0, $month, $day - date("w", mktime(0, 0, 0, $month, $day, $year)) + 1 - 7 * (-$offset), $year) : + mktime(23, 59, 59, $month, $day - date("w", mktime(0, 0, 0, $month, $day, $year)) + 7 - 7 * (-$offset), $year); + break; + case 'month': + $time = $position ? mktime(0, 0, 0, $month + $offset, 1, $year) : mktime(23, 59, 59, $month + $offset, get_month_days($month + $offset, $year), $year); + break; + case 'quarter': + $time = $position ? + mktime(0, 0, 0, 1 + ((ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) - 1) * 3, 1, $year) : + mktime(23, 59, 59, (ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) * 3, get_month_days((ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) * 3, $year), $year); + break; + case 'year': + $time = $position ? mktime(0, 0, 0, 1, 1, $year + $offset) : mktime(23, 59, 59, 12, 31, $year + $offset); + break; + default: + $time = mktime($hour, $minute, 0, $month, $day, $year); + break; + } + return $time; + } + +} diff --git a/extend/fast/Form.php b/extend/fast/Form.php new file mode 100644 index 0000000..af877e2 --- /dev/null +++ b/extend/fast/Form.php @@ -0,0 +1,1201 @@ +<?php + +namespace fast; + +use ArrayAccess; + +/** + * @class Form + * @package fast + * @method mixed token() static token + * @method mixed close() static 关闭一个HTML表单 + * @method mixed setModel(mixed $model) static 设置HTML表单模型 + * @method mixed open(array $options) static 打开一个新的HTML表单 + * @method mixed file(string $name, array $options = array()) static 表单file + * @method mixed reset(string $name, array $options = array()) static 表单reset + * @method mixed password(string $name, array $options = array()) static 表单password + * @method mixed button(string $value = null, array $options = array()) static 表单button + * @method mixed model(mixed $model ,array $options = array()) static 打开一个新的HTML表单模型 + * @method mixed submit(string $value = null, array $options = array()) static 表单submit提交 + * @method mixed text(string $name, string $value = null, array $options = []) static 表单text + * @method mixed label(string $name, string $value = null, array $options = []) static label标签 + * @method mixed url(string $name, string $value = null, array $options = array()) static 表单url + * @method mixed email(string $name, string $value = null, array $options = array()) static 表单email + * @method mixed hidden(string $name, string $value = null, array $options = array()) static 表单hidden + * @method mixed image(string $url, string $name = null, array $attributes = array()) static 表单image提交 + * @method mixed textarea(string $name, string $value = null, array $options = array()) static 表单textarea + * @method mixed checkbox(string $name, string $value = 1, string $checked = null, array $options = array()) static 表单checkbox + * @method mixed radio(string $name, string $value = null, string $checked = null, array $options = array())) static 表单radio + * @method mixed select(string $name, array $list = array(), string $selected = null, array $options = array()) static 表单textarea + * @method mixed selectYear(string $name ,string $begin,string $end, string $selected = null ,array $options = array()) static select年 + * @method mixed selectMonth(string $name ,string $selected = null ,array $options = array() ,string $format = '%m') static select月 + */ +class Form +{ + + public function __construct() + { + + } + + public static function __callStatic($name, $arguments) + { + return call_user_func_array([FormBuilder::instance(), $name], $arguments); + } + +} + +class FormBuilder +{ + + /** + * The CSRF token used by the form builder. + * + * @var string + */ + protected $csrfToken = array('name' => '__token__'); + + /** + * The current model instance for the form. + * + * @var mixed + */ + protected $model; + + /** + * An array of label names we've created. + * + * @var array + */ + protected $labels = array(); + + /** + * The reserved form open attributes. + * + * @var array + */ + protected $reserved = array('method', 'url', 'route', 'action', 'files'); + + /** + * The form methods that should be spoofed, in uppercase. + * + * @var array + */ + protected $spoofedMethods = array('DELETE', 'PATCH', 'PUT'); + + /** + * The types of inputs to not fill values on by default. + * + * @var array + */ + protected $skipValueTypes = array('file', 'password', 'checkbox', 'radio'); + protected static $instance; + + /** + * Create a new form builder instance. + * + * @return void + */ + public function __construct() + { + + } + + public static function instance($options = []) + { + if (is_null(self::$instance)) + { + self::$instance = new static($options); + } + + return self::$instance; + } + + /** + * Open up a new HTML form. + * + * @param array $options + * @return string + */ + public function open(array $options = array()) + { + $method = array_get($options, 'method', 'post'); + + // We need to extract the proper method from the attributes. If the method is + // something other than GET or POST we'll use POST since we will spoof the + // actual method since forms don't support the reserved methods in HTML. + $attributes['method'] = $this->getMethod($method); + + $attributes['action'] = array_get($options, 'action', ''); + + $attributes['accept-charset'] = 'UTF-8'; + + // If the method is PUT, PATCH or DELETE we will need to add a spoofer hidden + // field that will instruct the Symfony request to pretend the method is a + // different method than it actually is, for convenience from the forms. + $append = $this->getAppendage($method); + + if (isset($options['files']) && $options['files']) + { + $options['enctype'] = 'multipart/form-data'; + } + + // Finally we're ready to create the final form HTML field. We will attribute + // format the array of attributes. We will also add on the appendage which + // is used to spoof requests for this PUT, PATCH, etc. methods on forms. + $attributes = array_merge( + $attributes, array_except($options, $this->reserved) + ); + // Finally, we will concatenate all of the attributes into a single string so + // we can build out the final form open statement. We'll also append on an + // extra value for the hidden _method field if it's needed for the form. + $attributes = $this->attributes($attributes); + + return '<form' . $attributes . '>' . $append; + } + + /** + * Create a new model based form builder. + * + * @param mixed $model + * @param array $options + * @return string + */ + public function model($model, array $options = array()) + { + $this->model = $model; + + return $this->open($options); + } + + /** + * Set the model instance on the form builder. + * + * @param mixed $model + * @return void + */ + public function setModel($model) + { + $this->model = $model; + } + + /** + * Close the current form. + * + * @return string + */ + public function close() + { + $this->labels = array(); + + $this->model = null; + + return '</form>'; + } + + /** + * Generate a hidden field with the current CSRF token. + * + * @return string + */ + public function token($name = '__token__', $type = 'md5') + { + if (function_exists('token')) + { + return token($name, $type); + } + + return ''; + } + + /** + * Create a form label element. + * + * @param string $name + * @param string $value + * @param array $options + * @return string + */ + public function label($name, $value = null, $options = array()) + { + $this->labels[] = $name; + + $options = $this->attributes($options); + + $value = e($this->formatLabel($name, $value)); + + return '<label for="' . $name . '"' . $options . '>' . $value . '</label>'; + } + + /** + * Format the label value. + * + * @param string $name + * @param string|null $value + * @return string + */ + protected function formatLabel($name, $value) + { + return $value ? : ucwords(str_replace('_', ' ', $name)); + } + + /** + * Create a form input field. + * + * @param string $type + * @param string $name + * @param string $value + * @param array $options + * @return string + */ + public function input($type, $name, $value = null, $options = array()) + { + if (!isset($options['name'])) + $options['name'] = $name; + + // We will get the appropriate value for the given field. We will look for the + // value in the session for the value in the old input data then we'll look + // in the model instance if one is set. Otherwise we will just use empty. + $id = $this->getIdAttribute($name, $options); + + if (!in_array($type, $this->skipValueTypes)) + { + $value = $this->getValueAttribute($name, $value); + } + + // Once we have the type, value, and ID we can merge them into the rest of the + // attributes array so we can convert them into their HTML attribute format + // when creating the HTML element. Then, we will return the entire input. + $merge = compact('type', 'value', 'id'); + + $options = array_merge($options, $merge); + + return '<input' . $this->attributes($options) . '>'; + } + + /** + * Create a text input field. + * + * @param string $name + * @param string $value + * @param array $options + * @return string + */ + public function text($name, $value = null, $options = array()) + { + return $this->input('text', $name, $value, $options); + } + + /** + * Create a password input field. + * + * @param string $name + * @param array $options + * @return string + */ + public function password($name, $options = array()) + { + return $this->input('password', $name, '', $options); + } + + /** + * Create a hidden input field. + * + * @param string $name + * @param string $value + * @param array $options + * @return string + */ + public function hidden($name, $value = null, $options = array()) + { + return $this->input('hidden', $name, $value, $options); + } + + /** + * Create an e-mail input field. + * + * @param string $name + * @param string $value + * @param array $options + * @return string + */ + public function email($name, $value = null, $options = array()) + { + return $this->input('email', $name, $value, $options); + } + + /** + * Create a url input field. + * + * @param string $name + * @param string $value + * @param array $options + * @return string + */ + public function url($name, $value = null, $options = array()) + { + return $this->input('url', $name, $value, $options); + } + + /** + * Create a file input field. + * + * @param string $name + * @param array $options + * @return string + */ + public function file($name, $options = array()) + { + return $this->input('file', $name, null, $options); + } + + /** + * Create a textarea input field. + * + * @param string $name + * @param string $value + * @param array $options + * @return string + */ + public function textarea($name, $value = null, $options = array()) + { + if (!isset($options['name'])) + $options['name'] = $name; + + // Next we will look for the rows and cols attributes, as each of these are put + // on the textarea element definition. If they are not present, we will just + // assume some sane default values for these attributes for the developer. + $options = $this->setTextAreaSize($options); + + $options['id'] = $this->getIdAttribute($name, $options); + + $value = (string) $this->getValueAttribute($name, $value); + + unset($options['size']); + + // Next we will convert the attributes into a string form. Also we have removed + // the size attribute, as it was merely a short-cut for the rows and cols on + // the element. Then we'll create the final textarea elements HTML for us. + $options = $this->attributes($options); + + return '<textarea' . $options . '>' . e($value) . '</textarea>'; + } + + /** + * Set the text area size on the attributes. + * + * @param array $options + * @return array + */ + protected function setTextAreaSize($options) + { + if (isset($options['size'])) + { + return $this->setQuickTextAreaSize($options); + } + + // If the "size" attribute was not specified, we will just look for the regular + // columns and rows attributes, using sane defaults if these do not exist on + // the attributes array. We'll then return this entire options array back. + $cols = array_get($options, 'cols', 50); + + $rows = array_get($options, 'rows', 10); + + return array_merge($options, compact('cols', 'rows')); + } + + /** + * Set the text area size using the quick "size" attribute. + * + * @param array $options + * @return array + */ + protected function setQuickTextAreaSize($options) + { + $segments = explode('x', $options['size']); + + return array_merge($options, array('cols' => $segments[0], 'rows' => $segments[1])); + } + + /** + * Create a select box field. + * + * @param string $name + * @param array $list + * @param string $selected + * @param array $options + * @return string + */ + public function select($name, $list = array(), $selected = null, $options = array()) + { + // When building a select box the "value" attribute is really the selected one + // so we will use that when checking the model or session for a value which + // should provide a convenient method of re-populating the forms on post. + $selected = $this->getValueAttribute($name, $selected); + + $options['id'] = $this->getIdAttribute($name, $options); + + if (!isset($options['name'])) + $options['name'] = $name; + + // We will simply loop through the options and build an HTML value for each of + // them until we have an array of HTML declarations. Then we will join them + // all together into one single HTML element that can be put on the form. + $html = array(); + + foreach ($list as $value => $display) + { + $html[] = $this->getSelectOption($display, $value, $selected); + } + + // Once we have all of this HTML, we can join this into a single element after + // formatting the attributes into an HTML "attributes" string, then we will + // build out a final select statement, which will contain all the values. + $options = $this->attributes($options); + + $list = implode('', $html); + + return "<select{$options}>{$list}</select>"; + } + + /** + * Create a select range field. + * + * @param string $name + * @param string $begin + * @param string $end + * @param string $selected + * @param array $options + * @return string + */ + public function selectRange($name, $begin, $end, $selected = null, $options = array()) + { + + $range = array_combine($range = range($begin, $end), $range); + + return $this->select($name, $range, $selected, $options); + } + + /** + * Create a select year field. + * + * @param string $name + * @param string $begin + * @param string $end + * @param string $selected + * @param array $options + * @return string + */ + public function selectYear() + { + return call_user_func_array(array($this, 'selectRange'), func_get_args()); + } + + /** + * Create a select month field. + * + * @param string $name + * @param string $selected + * @param array $options + * @param string $format + * @return string + */ + public function selectMonth($name, $selected = null, $options = array(), $format = '%m') + { + $months = array(); + + foreach (range(1, 12) as $month) + { + $months[$month] = strftime($format, mktime(0, 0, 0, $month, 1)); + } + + return $this->select($name, $months, $selected, $options); + } + + /** + * Get the select option for the given value. + * + * @param string $display + * @param string $value + * @param string $selected + * @return string + */ + public function getSelectOption($display, $value, $selected) + { + if (is_array($display)) + { + return $this->optionGroup($display, $value, $selected); + } + + return $this->option($display, $value, $selected); + } + + /** + * Create an option group form element. + * + * @param array $list + * @param string $label + * @param string $selected + * @return string + */ + protected function optionGroup($list, $label, $selected) + { + $html = array(); + + foreach ($list as $value => $display) + { + $html[] = $this->option($display, $value, $selected); + } + + return '<optgroup label="' . e($label) . '">' . implode('', $html) . '</optgroup>'; + } + + /** + * Create a select element option. + * + * @param string $display + * @param string $value + * @param string $selected + * @return string + */ + protected function option($display, $value, $selected) + { + $selected = $this->getSelectedValue($value, $selected); + + $options = array('value' => e($value), 'selected' => $selected); + + return '<option' . $this->attributes($options) . '>' . e($display) . '</option>'; + } + + /** + * Determine if the value is selected. + * + * @param string $value + * @param string $selected + * @return string + */ + protected function getSelectedValue($value, $selected) + { + if (is_array($selected)) + { + return in_array($value, $selected) ? 'selected' : null; + } + + return ((string) $value == (string) $selected) ? 'selected' : null; + } + + /** + * Create a checkbox input field. + * + * @param string $name + * @param mixed $value + * @param bool $checked + * @param array $options + * @return string + */ + public function checkbox($name, $value = 1, $checked = null, $options = array()) + { + return $this->checkable('checkbox', $name, $value, $checked, $options); + } + + /** + * Create a radio button input field. + * + * @param string $name + * @param mixed $value + * @param bool $checked + * @param array $options + * @return string + */ + public function radio($name, $value = null, $checked = null, $options = array()) + { + if (is_null($value)) + $value = $name; + + return $this->checkable('radio', $name, $value, $checked, $options); + } + + /** + * Create a checkable input field. + * + * @param string $type + * @param string $name + * @param mixed $value + * @param bool $checked + * @param array $options + * @return string + */ + protected function checkable($type, $name, $value, $checked, $options) + { + $checked = $this->getCheckedState($type, $name, $value, $checked); + + if ($checked) + $options['checked'] = 'checked'; + + return $this->input($type, $name, $value, $options); + } + + /** + * Get the check state for a checkable input. + * + * @param string $type + * @param string $name + * @param mixed $value + * @param bool $checked + * @return bool + */ + protected function getCheckedState($type, $name, $value, $checked) + { + switch ($type) + { + case 'checkbox': + return $this->getCheckboxCheckedState($name, $value, $checked); + + case 'radio': + return $this->getRadioCheckedState($name, $value, $checked); + + default: + return $this->getValueAttribute($name) == $value; + } + } + + /** + * Get the check state for a checkbox input. + * + * @param string $name + * @param mixed $value + * @param bool $checked + * @return bool + */ + protected function getCheckboxCheckedState($name, $value, $checked) + { + if (isset($this->session) && !$this->oldInputIsEmpty() && is_null($this->old($name))) + return false; + + if ($this->missingOldAndModel($name)) + return $checked; + + $posted = $this->getValueAttribute($name); + + return is_array($posted) ? in_array($value, $posted) : (bool) $posted; + } + + /** + * Get the check state for a radio input. + * + * @param string $name + * @param mixed $value + * @param bool $checked + * @return bool + */ + protected function getRadioCheckedState($name, $value, $checked) + { + if ($this->missingOldAndModel($name)) + return $checked; + + return $this->getValueAttribute($name) == $value; + } + + /** + * Determine if old input or model input exists for a key. + * + * @param string $name + * @return bool + */ + protected function missingOldAndModel($name) + { + return (is_null($this->old($name)) && is_null($this->getModelValueAttribute($name))); + } + + /** + * Create a HTML reset input element. + * + * @param string $value + * @param array $attributes + * @return string + */ + public function reset($value, $attributes = array()) + { + return $this->input('reset', null, $value, $attributes); + } + + /** + * Create a HTML image input element. + * + * @param string $url + * @param string $name + * @param array $attributes + * @return string + */ + public function image($url, $name = null, $attributes = array()) + { + $attributes['src'] = $url; + + return $this->input('image', $name, null, $attributes); + } + + /** + * Create a submit button element. + * + * @param string $value + * @param array $options + * @return string + */ + public function submit($value = null, $options = array()) + { + return $this->input('submit', null, $value, $options); + } + + /** + * Create a button element. + * + * @param string $value + * @param array $options + * @return string + */ + public function button($value = null, $options = array()) + { + if (!array_key_exists('type', $options)) + { + $options['type'] = 'button'; + } + + return '<button' . $this->attributes($options) . '>' . $value . '</button>'; + } + + /** + * Parse the form action method. + * + * @param string $method + * @return string + */ + protected function getMethod($method) + { + $method = strtoupper($method); + + return $method != 'GET' ? 'POST' : $method; + } + + /** + * Get the form action from the options. + * + * @param array $options + * @return string + */ + /* protected function getAction(array $options) + { + // We will also check for a "route" or "action" parameter on the array so that + // developers can easily specify a route or controller action when creating + // a form providing a convenient interface for creating the form actions. + if (isset($options['url'])) + { + return $this->getUrlAction($options['url']); + } + + if (isset($options['route'])) + { + return $this->getRouteAction($options['route']); + } + + // If an action is available, we are attempting to open a form to a controller + // action route. So, we will use the URL generator to get the path to these + // actions and return them from the method. Otherwise, we'll use current. + elseif (isset($options['action'])) + { + return $this->getControllerAction($options['action']); + } + + return $this->url->current(); + } */ + + /** + * Get the action for a "url" option. + * + * @param array|string $options + * @return string + */ + /* protected function getUrlAction($options) + { + if (is_array($options)) + { + return $this->url->to($options[0], array_slice($options, 1)); + } + + return $this->url->to($options); + } */ + + /** + * Get the action for a "route" option. + * + * @param array|string $options + * @return string + */ + /* protected function getRouteAction($options) + { + if (is_array($options)) + { + return $this->url->route($options[0], array_slice($options, 1)); + } + + return $this->url->route($options); + } */ + + /** + * Get the action for an "action" option. + * + * @param array|string $options + * @return string + */ + /* protected function getControllerAction($options) + { + if (is_array($options)) + { + return $this->url->action($options[0], array_slice($options, 1)); + } + + return $this->url->action($options); + } */ + + /** + * Get the form appendage for the given method. + * + * @param string $method + * @return string + */ + protected function getAppendage($method) + { + list($method, $appendage) = array(strtoupper($method), ''); + + // If the HTTP method is in this list of spoofed methods, we will attach the + // method spoofer hidden input to the form. This allows us to use regular + // form to initiate PUT and DELETE requests in addition to the typical. + if (in_array($method, $this->spoofedMethods)) + { + $appendage .= $this->hidden('_method', $method); + } + + + // If the method is something other than GET we will go ahead and attach the + // CSRF token to the form, as this can't hurt and is convenient to simply + // always have available on every form the developers creates for them. + if ($method != 'GET') + { + $appendage .= $this->token(array_get($this->csrfToken, 'name'), array_get($this->csrfToken, 'type')); + } + + return $appendage; + } + + /** + * Get the ID attribute for a field name. + * + * @param string $name + * @param array $attributes + * @return string + */ + public function getIdAttribute($name, $attributes) + { + + if (array_key_exists('id', $attributes)) + { + return $attributes['id']; + } + + if (in_array($name, $this->labels)) + { + return $name; + } + } + + /** + * Get the value that should be assigned to the field. + * + * @param string $name + * @param string $value + * @return string + */ + public function getValueAttribute($name, $value = null) + { + if (is_null($name)) + return $value; + + if (!is_null($this->old($name))) + { + return $this->old($name); + } + + if (!is_null($value)) + return $value; + + if (isset($this->model)) + { + return $this->getModelValueAttribute($name); + } + } + + /** + * Get the model value that should be assigned to the field. + * + * @param string $name + * @return string + */ + protected function getModelValueAttribute($name) + { + if (is_object($this->model)) + { + return object_get($this->model, $this->transformKey($name)); + } + elseif (is_array($this->model)) + { + return array_get($this->model, $this->transformKey($name)); + } + } + + /** + * Get a value from the session's old input. + * + * @param string $name + * @return string + */ + public function old($name) + { + if (isset($this->session)) + { + return $this->session->getOldInput($this->transformKey($name)); + } + } + + /** + * Determine if the old input is empty. + * + * @return bool + */ + public function oldInputIsEmpty() + { + return (isset($this->session) && count($this->session->getOldInput()) == 0); + } + + /** + * Transform key from array to dot syntax. + * + * @param string $key + * @return string + */ + protected function transformKey($key) + { + return str_replace(array('.', '[]', '[', ']'), array('_', '', '.', ''), $key); + } + + /** + * 数组转换成一个HTML属性字符串。 + * + * @param array $attributes + * @return string + */ + public function attributes($attributes) + { + $html = array(); + // 假设我们的keys 和 value 是相同的, + // 拿HTML“required”属性来说,假设是['required']数组, + // 会已 required="required" 拼接起来,而不是用数字keys去拼接 + foreach ((array) $attributes as $key => $value) + { + $element = $this->attributeElement($key, $value); + if (!is_null($element)) + $html[] = $element; + } + return count($html) > 0 ? ' ' . implode(' ', $html) : ''; + } + + /** + * 拼接成一个属性。 + * + * @param string $key + * @param string $value + * @return string + */ + protected function attributeElement($key, $value) + { + if (is_numeric($key)) + $key = $value; + if (!is_null($value)) + return $key . '="' . $value . '"'; + } + +} + +class Arr +{ + + /** + * Determine whether the given value is array accessible. + * + * @param mixed $value + * @return bool + */ + public static function accessible($value) + { + return is_array($value) || $value instanceof ArrayAccess; + } + + /** + * Determine if the given key exists in the provided array. + * + * @param \ArrayAccess|array $array + * @param string|int $key + * @return bool + */ + public static function exists($array, $key) + { + if ($array instanceof ArrayAccess) + { + return $array->offsetExists($key); + } + return array_key_exists($key, $array); + } + + /** + * Get an item from an array using "dot" notation. + * + * @param \ArrayAccess|array $array + * @param string $key + * @param mixed $default + * @return mixed + */ + public static function get($array, $key, $default = null) + { + if (!static::accessible($array)) + { + return $default; + } + if (is_null($key)) + { + return $array; + } + if (static::exists($array, $key)) + { + return $array[$key]; + } + foreach (explode('.', $key) as $segment) + { + if (static::accessible($array) && static::exists($array, $segment)) + { + $array = $array[$segment]; + } + else + { + return $default; + } + } + return $array; + } + + /** + * Get all of the given array except for a specified array of items. + * + * @param array $array + * @param array|string $keys + * @return array + */ + public static function except($array, $keys) + { + static::forget($array, $keys); + return $array; + } + + /** + * Remove one or many array items from a given array using "dot" notation. + * + * @param array $array + * @param array|string $keys + * @return void + */ + public static function forget(&$array, $keys) + { + $original = &$array; + $keys = (array) $keys; + if (count($keys) === 0) + { + return; + } + foreach ($keys as $key) + { + // if the exact key exists in the top-level, remove it + if (static::exists($array, $key)) + { + unset($array[$key]); + continue; + } + $parts = explode('.', $key); + // clean up before each pass + $array = &$original; + while (count($parts) > 1) + { + $part = array_shift($parts); + if (isset($array[$part]) && is_array($array[$part])) + { + $array = &$array[$part]; + } + else + { + continue 2; + } + } + unset($array[array_shift($parts)]); + } + } + +} + +if (!function_exists('array_get')) +{ + + /** + * Get an item from an array using "dot" notation. + * + * @param \ArrayAccess|array $array + * @param string $key + * @param mixed $default + * @return mixed + */ + function array_get($array, $key, $default = null) + { + return Arr::get($array, $key, $default); + } + +} +if (!function_exists('e')) +{ + + /** + * Escape HTML special characters in a string. + * + * + * @return string + */ + function e($value) + { + if (is_array($value)) + { + $value = json_encode($value, JSON_UNESCAPED_UNICODE); + } + return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false); + } + +} +if (!function_exists('array_except')) +{ + + /** + * Get all of the given array except for a specified array of items. + * + * @param array $array + * @param array|string $keys + * @return array + */ + function array_except($array, $keys) + { + return Arr::except($array, $keys); + } + +} diff --git a/extend/fast/Http.php b/extend/fast/Http.php new file mode 100644 index 0000000..2206bb5 --- /dev/null +++ b/extend/fast/Http.php @@ -0,0 +1,190 @@ +<?php + +namespace fast; + +/** + * 字符串类 + */ +class Http +{ + + /** + * 发送一个POST请求 + */ + public static function post($url, $params = [], $options = []) + { + $req = self::sendRequest($url, $params, 'POST', $options); + return $req['ret'] ? $req['msg'] : ''; + } + + /** + * 发送一个GET请求 + */ + public static function get($url, $params = [], $options = []) + { + $req = self::sendRequest($url, $params, 'GET', $options); + return $req['ret'] ? $req['msg'] : ''; + } + + /** + * CURL发送Request请求,含POST和REQUEST + * @param string $url 请求的链接 + * @param mixed $params 传递的参数 + * @param string $method 请求的方法 + * @param mixed $options CURL的参数 + * @return array + */ + public static function sendRequest($url, $params = [], $method = 'POST', $options = []) + { + $method = strtoupper($method); + $protocol = substr($url, 0, 5); + $query_string = is_array($params) ? http_build_query($params) : $params; + + $ch = curl_init(); + $defaults = []; + if ('GET' == $method) + { + $geturl = $query_string ? $url . (stripos($url, "?") !== FALSE ? "&" : "?") . $query_string : $url; + $defaults[CURLOPT_URL] = $geturl; + } + else + { + $defaults[CURLOPT_URL] = $url; + if ($method == 'POST') + { + $defaults[CURLOPT_POST] = 1; + } + else + { + $defaults[CURLOPT_CUSTOMREQUEST] = $method; + } + $defaults[CURLOPT_POSTFIELDS] = $query_string; + } + + $defaults[CURLOPT_HEADER] = FALSE; + $defaults[CURLOPT_USERAGENT] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.98 Safari/537.36"; + $defaults[CURLOPT_FOLLOWLOCATION] = TRUE; + $defaults[CURLOPT_RETURNTRANSFER] = TRUE; + $defaults[CURLOPT_CONNECTTIMEOUT] = 3; + $defaults[CURLOPT_TIMEOUT] = 3; + + // disable 100-continue + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); + + if ('https' == $protocol) + { + $defaults[CURLOPT_SSL_VERIFYPEER] = FALSE; + $defaults[CURLOPT_SSL_VERIFYHOST] = FALSE; + } + + curl_setopt_array($ch, (array) $options + $defaults); + + $ret = curl_exec($ch); + $err = curl_error($ch); + + if (FALSE === $ret || !empty($err)) + { + $errno = curl_errno($ch); + $info = curl_getinfo($ch); + curl_close($ch); + return [ + 'ret' => FALSE, + 'errno' => $errno, + 'msg' => $err, + 'info' => $info, + ]; + } + curl_close($ch); + return [ + 'ret' => TRUE, + 'msg' => $ret, + ]; + } + + /** + * 异步发送一个请求 + * @param string $url 请求的链接 + * @param mixed $params 请求的参数 + * @param string $method 请求的方法 + * @return boolean TRUE + */ + public static function sendAsyncRequest($url, $params = [], $method = 'POST') + { + $method = strtoupper($method); + $method = $method == 'POST' ? 'POST' : 'GET'; + //构造传递的参数 + if (is_array($params)) + { + $post_params = []; + foreach ($params as $k => &$v) + { + if (is_array($v)) + $v = implode(',', $v); + $post_params[] = $k . '=' . urlencode($v); + } + $post_string = implode('&', $post_params); + }else + { + $post_string = $params; + } + $parts = parse_url($url); + //构造查询的参数 + if ($method == 'GET' && $post_string) + { + $parts['query'] = isset($parts['query']) ? $parts['query'] . '&' . $post_string : $post_string; + $post_string = ''; + } + $parts['query'] = isset($parts['query']) && $parts['query'] ? '?' . $parts['query'] : ''; + //发送socket请求,获得连接句柄 + $fp = fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80, $errno, $errstr, 3); + if (!$fp) + return FALSE; + //设置超时时间 + stream_set_timeout($fp, 3); + $out = "{$method} {$parts['path']}{$parts['query']} HTTP/1.1\r\n"; + $out.= "Host: {$parts['host']}\r\n"; + $out.= "Content-Type: application/x-www-form-urlencoded\r\n"; + $out.= "Content-Length: " . strlen($post_string) . "\r\n"; + $out.= "Connection: Close\r\n\r\n"; + if ($post_string !== '') + $out .= $post_string; + fwrite($fp, $out); + //不用关心服务器返回结果 + //echo fread($fp, 1024); + fclose($fp); + return TRUE; + } + + /** + * 发送文件到客户端 + * @param string $file + * @param bool $delaftersend + * @param bool $exitaftersend + */ + public static function sendToBrowser($file, $delaftersend = true, $exitaftersend = true) + { + if (file_exists($file) && is_readable($file)) + { + header('Content-Description: File Transfer'); + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment;filename = ' . basename($file)); + header('Content-Transfer-Encoding: binary'); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check = 0, pre-check = 0'); + header('Pragma: public'); + header('Content-Length: ' . filesize($file)); + ob_clean(); + flush(); + readfile($file); + if ($delaftersend) + { + unlink($file); + } + if ($exitaftersend) + { + exit; + } + } + } + +} diff --git a/extend/fast/Menu.php b/extend/fast/Menu.php new file mode 100644 index 0000000..6208171 --- /dev/null +++ b/extend/fast/Menu.php @@ -0,0 +1,166 @@ +<?php + +namespace fast; + +use app\admin\library\Auth; +use fast\Tree; +use think\Config; +use think\Db; + +/** + * 菜单 + */ +class Menu +{ + + protected static $instance; + //默认配置 + protected $config = []; + + public function __construct($options = []) + { + if ($config = Config::get('menu')) + { + $this->config = array_merge($this->config, $config); + } + $this->config = array_merge($this->config, is_array($options) ? $options : []); + } + + /** + * 单例 + * @param array $options 参数 + * @return Menu + */ + public static function instance($options = []) + { + if (is_null(self::$instance)) + { + self::$instance = new static($options); + } + + return self::$instance; + } + + /** + * 导入节点数据 + * @param array $treearr + * @param int $pid + * @param string $module + */ + public function import($treearr, $pid = 0, $module = NULL) + { + $module = is_null($module) ? Config::user('request.modulename') : $module; + foreach ($treearr as $key => & $v) + { + $controller = strtolower($v['controller']) . ($v['childlist'] ? "_folder" : ''); + $icon = isset($v['icon']) ? $v['icon'] : (stripos($v['name'], '_') !== FALSE ? $v['childlist'] ? 'folder' : 'circle-o' : strtolower($v['name'])); + $actionkeys = array_keys($v['actionlist']); + $action = '-' . ($v['actionlist'] ? reset($actionkeys) : ''); + $values = array( + 'name' => $v['name'], + 'weigh' => $key, + 'pid' => $pid, + 'module' => $module, + 'controller' => $controller, + 'action' => $action, + 'icon' => $icon, + 'type' => 'menu', + 'status' => 'normal' + ); + $id = Db::table("node")->data($values)->insert(); + $v['id'] = $id; + } + unset($v); + foreach ($treearr as $k => $v) + { + if ($v['childlist']) + { + $this->import($v['childlist'], $v['id'], $module); + } + else + { + $i = 0; + foreach ($v['actionlist'] as $m => $n) + { + $values = array( + 'name' => $n ? $n : $m, + 'weigh' => $i, + 'pid' => $v['id'], + 'module' => $module, + 'controller' => strtolower($v['controller']), + 'action' => $m, + 'icon' => 'circle-o', + 'type' => 'file', + 'status' => 'normal' + ); + Db::table("node")->data($values)->insert(); + $i++; + } + } + } + } + + /** + * 获取左侧菜单栏 + * + * @param array $params URL对应的badge数据 + * @return string + */ + public function sidebar($params = []) + { + $colorArr = ['red', 'green', 'yellow', 'blue', 'teal', 'orange', 'purple']; + $colorNums = count($colorArr); + $badgeList = []; + // 生成菜单的badge + foreach ($params as $k => $v) + { + if (stripos($k, '/') === false) + { + $url = '/admin/' . $k; + } + else + { + $url = url($k); + } + + if (is_array($v)) + { + $nums = isset($v[0]) ? $v[0] : 0; + $color = isset($v[1]) ? $v[1] : $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums]; + $class = isset($v[2]) ? $v[2] : 'label'; + } + else + { + $nums = $v; + $color = $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums]; + $class = 'label'; + } + //必须nums大于0才显示 + if ($nums) + { + $badgeList[$url] = '<small class="' . $class . ' pull-right bg-' . $color . '">' . $nums . '</small>'; + } + } + + // 读取管理员当前拥有的权限节点 + $userRule = Auth::instance()->getRuleList(); + + $select_id = 0; + $dashboard = rtrim(url('dashboard/'), '/'); + // 必须将结果集转换为数组 + $ruleList = collection(model('AuthRule')->where('ismenu', 1)->order('weigh', 'desc')->cache("__menu__")->select())->toArray(); + foreach ($ruleList as $k => &$v) + { + if (!in_array($v['name'], $userRule)) + continue; + $select_id = $v['name'] == $dashboard ? $v['id'] : $select_id; + $v['url'] = $v['name']; + $v['badge'] = isset($badgeList[$v['name']]) ? $badgeList[$v['name']] : ''; + } + // 构造菜单数据 + Tree::instance()->init($ruleList); + $menu = Tree::instance()->getTreeMenu(0, '<li class="@class"><a href="@url" addtabs="@id" url="@url"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>', $select_id, '', 'ul', 'class="treeview-menu"'); + return $menu; + } + +} diff --git a/extend/fast/Pinyin.php b/extend/fast/Pinyin.php new file mode 100644 index 0000000..be5f4ee --- /dev/null +++ b/extend/fast/Pinyin.php @@ -0,0 +1,89 @@ +<?php + +namespace fast; + +/** + * 中文转拼音类 + */ +class Pinyin +{ + + protected static $keys = "a|ai|an|ang|ao|ba|bai|ban|bang|bao|bei|ben|beng|bi|bian|biao|bie|bin|bing|bo|bu|ca|cai|can|cang|cao|ce|ceng|cha|chai|chan|chang|chao|che|chen|cheng|chi|chong|chou|chu|chuai|chuan|chuang|chui|chun|chuo|ci|cong|cou|cu|cuan|cui|cun|cuo|da|dai|dan|dang|dao|de|deng|di|dian|diao|die|ding|diu|dong|dou|du|duan|dui|dun|duo|e|en|er|fa|fan|fang|fei|fen|feng|fo|fou|fu|ga|gai|gan|gang|gao|ge|gei|gen|geng|gong|gou|gu|gua|guai|guan|guang|gui|gun|guo|ha|hai|han|hang|hao|he|hei|hen|heng|hong|hou|hu|hua|huai|huan|huang|hui|hun|huo|ji|jia|jian|jiang|jiao|jie|jin|jing|jiong|jiu|ju|juan|jue|jun|ka|kai|kan|kang|kao|ke|ken|keng|kong|kou|ku|kua|kuai|kuan|kuang|kui|kun|kuo|la|lai|lan|lang|lao|le|lei|leng|li|lia|lian|liang|liao|lie|lin|ling|liu|long|lou|lu|lv|luan|lue|lun|luo|ma|mai|man|mang|mao|me|mei|men|meng|mi|mian|miao|mie|min|ming|miu|mo|mou|mu|na|nai|nan|nang|nao|ne|nei|nen|neng|ni|nian|niang|niao|nie|nin|ning|niu|nong|nu|nv|nuan|nue|nuo|o|ou|pa|pai|pan|pang|pao|pei|pen|peng|pi|pian|piao|pie|pin|ping|po|pu|qi|qia|qian|qiang|qiao|qie|qin|qing|qiong|qiu|qu|quan|que|qun|ran|rang|rao|re|ren|reng|ri|rong|rou|ru|ruan|rui|run|ruo|sa|sai|san|sang|sao|se|sen|seng|sha|shai|shan|shang|shao|she|shen|sheng|shi|shou|shu|shua|shuai|shuan|shuang|shui|shun|shuo|si|song|sou|su|suan|sui|sun|suo|ta|tai|tan|tang|tao|te|teng|ti|tian|tiao|tie|ting|tong|tou|tu|tuan|tui|tun|tuo|wa|wai|wan|wang|wei|wen|weng|wo|wu|xi|xia|xian|xiang|xiao|xie|xin|xing|xiong|xiu|xu|xuan|xue|xun|ya|yan|yang|yao|ye|yi|yin|ying|yo|yong|you|yu|yuan|yue|yun|za|zai|zan|zang|zao|ze|zei|zen|zeng|zha|zhai|zhan|zhang|zhao|zhe|zhen|zheng|zhi|zhong|zhou|zhu|zhua|zhuai|zhuan|zhuang|zhui|zhun|zhuo|zi|zong|zou|zu|zuan|zui|zun|zuo"; + protected static $values = "-20319|-20317|-20304|-20295|-20292|-20283|-20265|-20257|-20242|-20230|-20051|-20036|-20032|-20026|-20002|-19990|-19986|-19982|-19976|-19805|-19784|-19775|-19774|-19763|-19756|-19751|-19746|-19741|-19739|-19728|-19725|-19715|-19540|-19531|-19525|-19515|-19500|-19484|-19479|-19467|-19289|-19288|-19281|-19275|-19270|-19263|-19261|-19249|-19243|-19242|-19238|-19235|-19227|-19224|-19218|-19212|-19038|-19023|-19018|-19006|-19003|-18996|-18977|-18961|-18952|-18783|-18774|-18773|-18763|-18756|-18741|-18735|-18731|-18722|-18710|-18697|-18696|-18526|-18518|-18501|-18490|-18478|-18463|-18448|-18447|-18446|-18239|-18237|-18231|-18220|-18211|-18201|-18184|-18183|-18181|-18012|-17997|-17988|-17970|-17964|-17961|-17950|-17947|-17931|-17928|-17922|-17759|-17752|-17733|-17730|-17721|-17703|-17701|-17697|-17692|-17683|-17676|-17496|-17487|-17482|-17468|-17454|-17433|-17427|-17417|-17202|-17185|-16983|-16970|-16942|-16915|-16733|-16708|-16706|-16689|-16664|-16657|-16647|-16474|-16470|-16465|-16459|-16452|-16448|-16433|-16429|-16427|-16423|-16419|-16412|-16407|-16403|-16401|-16393|-16220|-16216|-16212|-16205|-16202|-16187|-16180|-16171|-16169|-16158|-16155|-15959|-15958|-15944|-15933|-15920|-15915|-15903|-15889|-15878|-15707|-15701|-15681|-15667|-15661|-15659|-15652|-15640|-15631|-15625|-15454|-15448|-15436|-15435|-15419|-15416|-15408|-15394|-15385|-15377|-15375|-15369|-15363|-15362|-15183|-15180|-15165|-15158|-15153|-15150|-15149|-15144|-15143|-15141|-15140|-15139|-15128|-15121|-15119|-15117|-15110|-15109|-14941|-14937|-14933|-14930|-14929|-14928|-14926|-14922|-14921|-14914|-14908|-14902|-14894|-14889|-14882|-14873|-14871|-14857|-14678|-14674|-14670|-14668|-14663|-14654|-14645|-14630|-14594|-14429|-14407|-14399|-14384|-14379|-14368|-14355|-14353|-14345|-14170|-14159|-14151|-14149|-14145|-14140|-14137|-14135|-14125|-14123|-14122|-14112|-14109|-14099|-14097|-14094|-14092|-14090|-14087|-14083|-13917|-13914|-13910|-13907|-13906|-13905|-13896|-13894|-13878|-13870|-13859|-13847|-13831|-13658|-13611|-13601|-13406|-13404|-13400|-13398|-13395|-13391|-13387|-13383|-13367|-13359|-13356|-13343|-13340|-13329|-13326|-13318|-13147|-13138|-13120|-13107|-13096|-13095|-13091|-13076|-13068|-13063|-13060|-12888|-12875|-12871|-12860|-12858|-12852|-12849|-12838|-12831|-12829|-12812|-12802|-12607|-12597|-12594|-12585|-12556|-12359|-12346|-12320|-12300|-12120|-12099|-12089|-12074|-12067|-12058|-12039|-11867|-11861|-11847|-11831|-11798|-11781|-11604|-11589|-11536|-11358|-11340|-11339|-11324|-11303|-11097|-11077|-11067|-11055|-11052|-11045|-11041|-11038|-11024|-11020|-11019|-11018|-11014|-10838|-10832|-10815|-10800|-10790|-10780|-10764|-10587|-10544|-10533|-10519|-10331|-10329|-10328|-10322|-10315|-10309|-10307|-10296|-10281|-10274|-10270|-10262|-10260|-10256|-10254"; + + /** + * 获取文字的拼音 + * @param string $chinese 中文汉字 + * @param boolean $ucfirst 是否首字母大写 + * @param string $charset 文字编码 + * @return string + */ + public static function get($chinese, $ucfirst = false, $charset = 'utf-8') + { + $keys_a = explode('|', self::$keys); + $values_a = explode('|', self::$values); + $data = array_combine($keys_a, $values_a); + arsort($data); + reset($data); + if ($charset != 'gb2312') + $chinese = self::_u2_utf8_gb($chinese); + $result = ''; + for ($i = 0; $i < strlen($chinese); $i++) + { + $_P = ord(substr($chinese, $i, 1)); + if ($_P > 160) + { + $_Q = ord(substr($chinese, ++$i, 1)); + $_P = $_P * 256 + $_Q - 65536; + } + $result .= ($ucfirst ? ucfirst(self::_pinyin($_P, $data)) : self::_pinyin($_P, $data)); + } + + return preg_replace("/[^a-z0-9_\-]*/i", '', $result); + } + + private static function _pinyin($num, $data) + { + if ($num > 0 && $num < 160) + return chr($num); + elseif ($num < -20319 || $num > -10247) + return ''; + else + { + foreach ($data as $k => $v) + { + if ($v <= $num) + break; + } + + return $k; + } + } + + private static function _u2_utf8_gb($c) + { + $string = ''; + if ($c < 0x80) + $string .= $c; + elseif ($c < 0x800) + { + $string .= chr(0xC0 | $c >> 6); + $string .= chr(0x80 | $c & 0x3F); + } + elseif ($c < 0x10000) + { + $string .= chr(0xE0 | $c >> 12); + $string .= chr(0x80 | $c >> 6 & 0x3F); + $string .= chr(0x80 | $c & 0x3F); + } + elseif ($c < 0x200000) + { + $string .= chr(0xF0 | $c >> 18); + $string .= chr(0x80 | $c >> 12 & 0x3F); + $string .= chr(0x80 | $c >> 6 & 0x3F); + $string .= chr(0x80 | $c & 0x3F); + } + return iconv('UTF-8', 'GB2312//IGNORE', $string); + } + +} diff --git a/extend/fast/Random.php b/extend/fast/Random.php new file mode 100644 index 0000000..8851488 --- /dev/null +++ b/extend/fast/Random.php @@ -0,0 +1,182 @@ +<?php + +namespace fast; + +/** + * 随机生成类 + */ +class Random +{ + + /** + * 生成数字和字母 + * + * @param int $len 长度 + * @return string + */ + public static function alnum($len = 6) + { + return self::build('alnum', $len); + } + + /** + * 仅生成字符 + * + * @param int $len 长度 + * @return string + */ + public static function alpha($len = 6) + { + return self::build('alpha', $len); + } + + /** + * 生成指定长度的随机数字 + * + * @param int $len 长度 + * @return string + */ + public static function numeric($len = 4) + { + return self::build('numeric', $len); + } + + /** + * 数字和字母组合的随机字符串 + * + * @param int $len 长度 + * @return string + */ + public static function nozero($len = 4) + { + return self::build('nozero', $len); + } + + /** + * 能用的随机数生成 + * @param string $type 类型 alpha/alnum/numeric/nozero/unique/md5/encrypt/sha1 + * @param int $len 长度 + * @return string + */ + public static function build($type = 'alnum', $len = 8) + { + switch ($type) + { + case 'alpha': + case 'alnum': + case 'numeric': + case 'nozero': + switch ($type) + { + case 'alpha': + $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + break; + case 'alnum': + $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + break; + case 'numeric': + $pool = '0123456789'; + break; + case 'nozero': + $pool = '123456789'; + break; + } + return substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len); + case 'unique': + case 'md5': + return md5(uniqid(mt_rand())); + case 'encrypt': + case 'sha1': + return sha1(uniqid(mt_rand(), TRUE)); + } + } + + /** + * 根据数组元素的概率获得键名 + * + * @param array $ps array('p1'=>20, 'p2'=>30, 'p3'=>50); + * @param array $num 默认为1,即随机出来的数量 + * @param array $unique 默认为true,即当num>1时,随机出的数量是否唯一 + * @return mixed 当num为1时返回键名,反之返回一维数组 + */ + public static function lottery($ps, $num = 1, $unique = true) + { + if (!$ps) + { + return $num == 1 ? '' : []; + } + if ($num >= count($ps) && $unique) + { + $res = array_keys($ps); + return $num == 1 ? $res[0] : $res; + } + $max_exp = 0; + $res = []; + foreach ($ps as $key => $value) + { + $value = substr($value, 0, stripos($value, ".") + 6); + $exp = strlen(strchr($value, '.')) - 1; + if ($exp > $max_exp) + { + $max_exp = $exp; + } + } + $pow_exp = pow(10, $max_exp); + if ($pow_exp > 1) + { + reset($ps); + foreach ($ps as $key => $value) + { + $ps[$key] = $value * $pow_exp; + } + } + $pro_sum = array_sum($ps); + if ($pro_sum < 1) + { + return $num == 1 ? '' : []; + } + for ($i = 0; $i < $num; $i++) + { + $rand_num = mt_rand(1, $pro_sum); + reset($ps); + foreach ($ps as $key => $value) + { + if ($rand_num <= $value) + { + break; + } + else + { + $rand_num -= $value; + } + } + if ($num == 1) + { + $res = $key; + break; + } + else + { + $res[$i] = $key; + } + if ($unique) + { + $pro_sum -= $value; + unset($ps[$key]); + } + } + return $res; + } + + /** + * 获取全球唯一标识 + * @return string + */ + public static function uuid() + { + return sprintf( + '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) + ); + } + +} diff --git a/extend/fast/Rsa.php b/extend/fast/Rsa.php new file mode 100644 index 0000000..2fc1a8e --- /dev/null +++ b/extend/fast/Rsa.php @@ -0,0 +1,187 @@ +<?php + +namespace fast; + +/** + * RSA签名类 + */ +class Rsa +{ + + public $publicKey = ''; + public $privateKey = ''; + private $_privKey; + + /** + * * private key + */ + private $_pubKey; + + /** + * * public key + */ + private $_keyPath; + + /** + * * the keys saving path + */ + + /** + * * the construtor,the param $path is the keys saving path + */ + function __construct($publicKey = null, $privateKey = null) + { + $this->setKey($publicKey, $privateKey); + } + + /** + * 设置公钥和私钥 + * @param string $publicKey 公钥 + * @param string $privateKey 私钥 + */ + public function setKey($publicKey = null, $privateKey = null) + { + if (!is_null($publicKey)) + $this->publicKey = $publicKey; + if (!is_null($privateKey)) + $this->privateKey = $privateKey; + } + + /** + * * setup the private key + */ + private function setupPrivKey() + { + if (is_resource($this->_privKey)) + { + return true; + } + $pem = chunk_split($this->privateKey, 64, "\n"); + $pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n"; + $this->_privKey = openssl_pkey_get_private($pem); + return true; + } + + /** + * * setup the public key + */ + private function setupPubKey() + { + if (is_resource($this->_pubKey)) + { + return true; + } + $pem = chunk_split($this->publicKey, 64, "\n"); + $pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n"; + $this->_pubKey = openssl_pkey_get_public($pem); + return true; + } + + /** + * * encrypt with the private key + */ + public function privEncrypt($data) + { + if (!is_string($data)) + { + return null; + } + $this->setupPrivKey(); + $r = openssl_private_encrypt($data, $encrypted, $this->_privKey); + if ($r) + { + return base64_encode($encrypted); + } + return null; + } + + /** + * * decrypt with the private key + */ + public function privDecrypt($encrypted) + { + if (!is_string($encrypted)) + { + return null; + } + $this->setupPrivKey(); + $encrypted = base64_decode($encrypted); + $r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey); + if ($r) + { + return $decrypted; + } + return null; + } + + /** + * * encrypt with public key + */ + public function pubEncrypt($data) + { + if (!is_string($data)) + { + return null; + } + $this->setupPubKey(); + $r = openssl_public_encrypt($data, $encrypted, $this->_pubKey); + if ($r) + { + return base64_encode($encrypted); + } + return null; + } + + /** + * * decrypt with the public key + */ + public function pubDecrypt($crypted) + { + if (!is_string($crypted)) + { + return null; + } + $this->setupPubKey(); + $crypted = base64_decode($crypted); + $r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey); + if ($r) + { + return $decrypted; + } + return null; + } + + /** + * 构造签名 + * @param string $dataString 被签名数据 + * @return string + */ + public function sign($dataString) + { + $this->setupPrivKey(); + $signature = false; + openssl_sign($dataString, $signature, $this->_privKey); + return base64_encode($signature); + } + + /** + * 验证签名 + * @param string $dataString 被签名数据 + * @param string $signString 已经签名的字符串 + * @return number 1签名正确 0签名错误 + */ + public function verify($dataString, $signString) + { + $this->setupPubKey(); + $signature = base64_decode($signString); + $flg = openssl_verify($dataString, $signature, $this->_pubKey); + return $flg; + } + + public function __destruct() + { + is_resource($this->_privKey) && @openssl_free_key($this->_privKey); + is_resource($this->_pubKey) && @openssl_free_key($this->_pubKey); + } + +} diff --git a/extend/fast/Tree.php b/extend/fast/Tree.php new file mode 100644 index 0000000..2c201bb --- /dev/null +++ b/extend/fast/Tree.php @@ -0,0 +1,480 @@ +<?php + +namespace fast; + +use think\Config; + +/** + * 通用的树型类 + * @author XiaoYao <476552238li@gmail.com> + */ +class Tree +{ + + protected static $instance; + //默认配置 + protected $config = []; + public $options = []; + + /** + * 生成树型结构所需要的2维数组 + * @var array + */ + public $arr = []; + + /** + * 生成树型结构所需修饰符号,可以换成图片 + * @var array + */ + public $icon = array('│', '├', '└'); + public $nbsp = " "; + public $pidname = 'pid'; + + public function __construct($options = []) + { + if ($config = Config::get('tree')) + { + $this->options = array_merge($this->config, $config); + } + $this->options = array_merge($this->config, $options); + } + + /** + * 初始化 + * @access public + * @param array $options 参数 + * @return Tree + */ + public static function instance($options = []) + { + if (is_null(self::$instance)) + { + self::$instance = new static($options); + } + + return self::$instance; + } + + /** + + * 初始化方法 + + * @param array 2维数组,例如: + * array( + * 1 => array('id'=>'1','pid'=>0,'name'=>'一级栏目一'), + * 2 => array('id'=>'2','pid'=>0,'name'=>'一级栏目二'), + * 3 => array('id'=>'3','pid'=>1,'name'=>'二级栏目一'), + * 4 => array('id'=>'4','pid'=>1,'name'=>'二级栏目二'), + * 5 => array('id'=>'5','pid'=>2,'name'=>'二级栏目三'), + * 6 => array('id'=>'6','pid'=>3,'name'=>'三级栏目一'), + * 7 => array('id'=>'7','pid'=>3,'name'=>'三级栏目二') + * ) + */ + public function init($arr = [], $pidname = NULL, $nbsp = NULL) + { + $this->arr = $arr; + if (!is_null($pidname)) + $this->pidname = $pidname; + if (!is_null($nbsp)) + $this->nbsp = $nbsp; + return $this; + } + + /** + * 得到子级数组 + * @param int + * @return array + */ + public function getChild($myid) + { + $newarr = []; + foreach ($this->arr as $value) + { + if (!isset($value['id'])) + continue; + if ($value[$this->pidname] == $myid) + $newarr[$value['id']] = $value; + } + return $newarr; + } + + /** + + * 读取指定节点的所有孩子节点 + * @param int $myid 节点ID + * @param boolean $withself 是否包含自身 + * @return array + */ + public function getChildren($myid, $withself = FALSE) + { + $newarr = []; + foreach ($this->arr as $value) + { + if (!isset($value['id'])) + continue; + if ($value[$this->pidname] == $myid) + { + $newarr[] = $value; + $newarr = array_merge($newarr, $this->getChildren($value['id'])); + } + else if ($withself && $value['id'] == $myid) + { + $newarr[] = $value; + } + } + return $newarr; + } + + /** + + * 读取指定节点的所有孩子节点ID + * @param int $myid 节点ID + * @param boolean $withself 是否包含自身 + * @return array + */ + public function getChildrenIds($myid, $withself = FALSE) + { + $childrenlist = $this->getChildren($myid, $withself); + $childrenids = []; + foreach ($childrenlist as $k => $v) + { + $childrenids[] = $v['id']; + } + return $childrenids; + } + + /** + + * 得到当前位置父辈数组 + * @param int + * @return array + + */ + public function getParent($myid) + { + $pid = 0; + $newarr = []; + foreach ($this->arr as $value) + { + if (!isset($value['id'])) + continue; + if ($value['id'] == $myid) + { + $pid = $value[$this->pidname]; + break; + } + } + if ($pid) + { + foreach ($this->arr as $value) + { + if ($value['id'] == $pid) + { + $newarr[] = $value; + break; + } + } + } + return $newarr; + } + + /** + + * 得到当前位置所有父辈数组 + * @param int + * @return array + + */ + public function getParents($myid, $withself = FALSE) + { + $pid = 0; + $newarr = []; + foreach ($this->arr as $value) + { + if (!isset($value['id'])) + continue; + if ($value['id'] == $myid) + { + if ($withself) + { + $newarr[] = $value; + } + $pid = $value[$this->pidname]; + break; + } + } + if ($pid) + { + $arr = $this->getParents($pid, TRUE); + $newarr = array_merge($arr, $newarr); + } + return $newarr; + } + + /** + * 读取指定节点所有父类节点ID + * @param int $myid + * @param boolean $withself + * @return array + */ + public function getParentsIds($myid, $withself = FALSE) + { + $parentlist = $this->getParents($myid, $withself); + $parentsids = []; + foreach ($parentlist as $k => $v) + { + $parentsids[] = $v['id']; + } + return $parentsids; + } + + /** + + * 树型结构Option + * @param int $myid 表示获得这个ID下的所有子级 + * @param string $itemtpl 条目模板 如:"<option value=@id @selected @disabled>@spacer@name</option>" + * @param mixed $selectedids 被选中的ID,比如在做树型下拉框的时候需要用到 + * @param mixed $disabledids 被禁用的ID,比如在做树型下拉框的时候需要用到 + * @param string $itemprefix 每一项前缀 + * @param string $toptpl 顶级栏目的模板 + * @return string + + */ + public function getTree($myid, $itemtpl = "<option value=@id @selected @disabled>@spacer@name</option>", $selectedids = '', $disabledids = '', $itemprefix = '', $toptpl = '') + { + $ret = ''; + $number = 1; + $childs = $this->getChild($myid); + if ($childs) + { + $total = count($childs); + foreach ($childs as $value) + { + $id = $value['id']; + $j = $k = ''; + if ($number == $total) + { + $j .= $this->icon[2]; + $k = $itemprefix ? $this->nbsp : ''; + } + else + { + $j .= $this->icon[1]; + $k = $itemprefix ? $this->icon[0] : ''; + } + $spacer = $itemprefix ? $itemprefix . $j : ''; + $selected = $selectedids && in_array($id, (is_array($selectedids) ? $selectedids : explode(',', $selectedids))) ? 'selected' : ''; + $disabled = $disabledids && in_array($id, (is_array($disabledids) ? $disabledids : explode(',', $disabledids))) ? 'disabled' : ''; + $value = array_merge($value, array('selected' => $selected, 'disabled' => $disabled, 'spacer' => $spacer)); + $value = array_combine(array_map(function($k) + { + return '@' . $k; + }, array_keys($value)), $value); + $nstr = strtr((($value["@{$this->pidname}"] == 0 || $this->getChild($id) ) && $toptpl ? $toptpl : $itemtpl), $value); + $ret .= $nstr; + $ret .= $this->getTree($id, $itemtpl, $selectedids, $disabledids, $itemprefix . $k . $this->nbsp, $toptpl); + $number++; + } + } + return $ret; + } + + /** + + * 树型结构UL + * @param int $myid 表示获得这个ID下的所有子级 + * @param string $itemtpl 条目模板 如:"<li value=@id @selected @disabled>@name @childlist</li>" + * @param string $selectedids 选中的ID + * @param string $disabledids 禁用的ID + * @param string $wraptag 子列表包裹标签 + * @return string + + */ + public function getTreeUl($myid, $itemtpl, $selectedids = '', $disabledids = '', $wraptag = 'ul', $wrapattr = '') + { + $str = ''; + $childs = $this->getChild($myid); + if ($childs) + { + foreach ($childs as $value) + { + $id = $value['id']; + unset($value['child']); + $selected = $selectedids && in_array($id, (is_array($selectedids) ? $selectedids : explode(',', $selectedids))) ? 'selected' : ''; + $disabled = $disabledids && in_array($id, (is_array($disabledids) ? $disabledids : explode(',', $disabledids))) ? 'disabled' : ''; + $value = array_merge($value, array('selected' => $selected, 'disabled' => $disabled)); + $value = array_combine(array_map(function($k) + { + return '@' . $k; + }, array_keys($value)), $value); + $nstr = strtr($itemtpl, $value); + $childdata = $this->getTreeUl($id, $itemtpl, $selectedids, $disabledids, $wraptag, $wrapattr); + $childlist = $childdata ? "<{$wraptag} {$wrapattr}>" . $childdata . "</{$wraptag}>" : ""; + $str .= strtr($nstr, array('@childlist' => $childlist)); + } + } + return $str; + } + + /** + * 菜单数据 + * @param int $myid + * @param string $itemtpl + * @param mixed $selectedids + * @param mixed $disabledids + * @param string $wraptag + * @param string $wrapattr + * @param int $deeplevel + * @return string + */ + public function getTreeMenu($myid, $itemtpl, $selectedids = '', $disabledids = '', $wraptag = 'ul', $wrapattr = '', $deeplevel = 0) + { + $str = ''; + $childs = $this->getChild($myid); + if ($childs) + { + foreach ($childs as $value) + { + $id = $value['id']; + unset($value['child']); + $selected = in_array($id, (is_array($selectedids) ? $selectedids : explode(',', $selectedids))) ? 'selected' : ''; + $disabled = in_array($id, (is_array($disabledids) ? $disabledids : explode(',', $disabledids))) ? 'disabled' : ''; + $value = array_merge($value, array('selected' => $selected, 'disabled' => $disabled)); + $value = array_combine(array_map(function($k) + { + return '@' . $k; + }, array_keys($value)), $value); + $bakvalue = array_intersect_key($value, array_flip(['@url', '@caret', '@class'])); + $value = array_diff_key($value, $bakvalue); + $nstr = strtr($itemtpl, $value); + $value = array_merge($value, $bakvalue); + $childdata = $this->getTreeMenu($id, $itemtpl, $selectedids, $disabledids, $wraptag, $wrapattr, $deeplevel + 1); + $childlist = $childdata ? "<{$wraptag} {$wrapattr}>" . $childdata . "</{$wraptag}>" : ""; + $childlist = strtr($childlist, array('@class' => $childdata ? 'last' : '')); + $value = array( + '@childlist' => $childlist, + '@url' => $childdata || !isset($value['@url']) ? "javascript:;" : url($value['@url']), + '@caret' => ($childdata && !$value['@badge'] ? '<i class="fa fa-angle-left"></i>' : ''), + '@badge' => $value['@badge'], + '@class' => ($selected ? ' active' : '') . ($disabled ? ' disabled' : '') . ($childdata ? ' treeview' : ''), + ); + $str .= strtr($nstr, $value); + } + } + return $str; + } + + /** + * 特殊 + * @param integer $myid 要查询的ID + * @param string $itemtpl1 第一种HTML代码方式 + * @param string $itemtpl2 第二种HTML代码方式 + * @param mixed $selectedids 默认选中 + * @param mixed $disabledids 禁用 + * @param integer $itemprefix 前缀 + */ + public function getTreeSpecial($myid, $itemtpl1, $itemtpl2, $selectedids = 0, $disabledids = 0, $itemprefix = '') + { + $ret = ''; + $number = 1; + $childs = $this->getChild($myid); + if ($childs) + { + $total = count($childs); + foreach ($childs as $id => $value) + { + $j = $k = ''; + if ($number == $total) + { + $j .= $this->icon[2]; + $k = $itemprefix ? $this->nbsp : ''; + } + else + { + $j .= $this->icon[1]; + $k = $itemprefix ? $this->icon[0] : ''; + } + $spacer = $itemprefix ? $itemprefix . $j : ''; + $selected = $selectedids && in_array($id, (is_array($selectedids) ? $selectedids : explode(',', $selectedids))) ? 'selected' : ''; + $disabled = $disabledids && in_array($id, (is_array($disabledids) ? $disabledids : explode(',', $disabledids))) ? 'disabled' : ''; + $value = array_merge($value, array('selected' => $selected, 'disabled' => $disabled, 'spacer' => $spacer)); + $value = array_combine(array_map(function($k) + { + return '@' . $k; + }, array_keys($value)), $value); + $nstr = strtr(!isset($value['@disabled']) || !$value['@disabled'] ? $itemtpl1 : $itemtpl2, $value); + + $ret .= $nstr; + $ret .= $this->getTreeSpecial($id, $itemtpl1, $itemtpl2, $selectedids, $disabledids, $itemprefix . $k . $this->nbsp); + $number++; + } + } + return $ret; + } + + /** + * + * 获取树状数组 + * @param string $myid 要查询的ID + * @param string $nametpl 名称条目模板 + * @param string $itemprefix 前缀 + * @return string + */ + public function getTreeArray($myid, $itemprefix = '') + { + $childs = $this->getChild($myid); + $n = 0; + $data = []; + $number = 1; + if ($childs) + { + $total = count($childs); + foreach ($childs as $id => $value) + { + $j = $k = ''; + if ($number == $total) + { + $j .= $this->icon[2]; + $k = $itemprefix ? $this->nbsp : ''; + } + else + { + $j .= $this->icon[1]; + $k = $itemprefix ? $this->icon[0] : ''; + } + $spacer = $itemprefix ? $itemprefix . $j : ''; + $value['spacer'] = $spacer; + $data[$n] = $value; + $data[$n]['childlist'] = $this->getTreeArray($id, $itemprefix . $k . $this->nbsp); + $n++; + $number++; + } + } + return $data; + } + + /** + * 将getTreeArray的结果返回为二维数组 + * @param array $data + * @return array + */ + public function getTreeList($data = [], $field = 'name') + { + $arr = []; + foreach ($data as $k => $v) + { + $childlist = isset($v['childlist']) ? $v['childlist'] : []; + unset($v['childlist']); + $v[$field] = $v['spacer'] . ' ' . $v[$field]; + $v['haschild'] = $childlist ? 1 : 0; + if ($v['id']) + $arr[] = $v; + if ($childlist) + { + $arr = array_merge($arr, $this->getTreeList($childlist, $field)); + } + } + return $arr; + } + +} diff --git a/extend/fast/payment/Alipay.php b/extend/fast/payment/Alipay.php new file mode 100644 index 0000000..97d4e52 --- /dev/null +++ b/extend/fast/payment/Alipay.php @@ -0,0 +1,447 @@ +<?php + +namespace fast\payment; + +use DOMDocument; +use Exception; + +/** + * 支付宝 + * @link https://github.com/mytharcher/alipay-php-sdk + */ +class Alipay +{ + + const SERVICE = 'create_direct_pay_by_user'; + const SERVICE_WAP = 'alipay.wap.trade.create.direct'; + const SERVICE_WAP_AUTH = 'alipay.wap.auth.authAndExecute'; + const SERVICE_APP = 'mobile.securitypay.pay'; + const GATEWAY = 'https://mapi.alipay.com/gateway.do?'; + const GATEWAY_MOBILE = 'http://wappaygw.alipay.com/service/rest.htm?'; + const VERIFY_URL = 'http://notify.alipay.com/trade/notify_query.do?'; + const VERIFY_URL_HTTPS = 'https://mapi.alipay.com/gateway.do?service=notify_verify&'; + + // 配置信息在实例化时传入,以下为范例 + private $config = array( + // 即时到账方式 + 'payment_type' => 1, + // 传输协议 + 'transport' => 'http', + // 编码方式 + 'input_charset' => 'utf-8', + // 签名方法 + 'sign_type' => 'MD5', + // 证书路径 + 'cacert' => './cacert.pem', + //验签公钥地址 + 'public_key_path' => './alipay_public_key.pem', + 'private_key_path' => '', + // 支付完成异步通知调用地址 + // 'notify_url' => 'http://'.$_SERVER['HTTP_HOST'].'/order/callback_alipay/notify', + // 支付完成同步返回地址 + // 'return_url' => 'http://'.$_SERVER['HTTP_HOST'].'/order/callback_alipay/return', + // 支付宝商家 ID + 'partner' => '2088xxxxxxxx', + // // 支付宝商家 KEY + 'key' => 'xxxxxxxxxxxx', + // // 支付宝商家注册邮箱 + 'seller_email' => 'email@domain.com' + ); + private $is_mobile = FALSE; + public $service = self::SERVICE; + public $gateway = self::GATEWAY; + + /** + * 配置 + * @param $options array 配置信息 + * @param null $type string 类型 wap app + */ + public function __construct($options = [], $type = null) + { + if ($config = Config::get('payment.alipay')) + { + $this->config = array_merge($this->config, $config); + } + $this->config = array_merge($this->config, is_array($options) ? $options : []); + $this->is_mobile = (($type == 'wap' || $type === true) ? true : false); + if ($this->is_mobile) + { + $this->gateway = self::GATEWAY_MOBILE; + } + + if ($type == 'wap' || $type === true) + { + $this->service = self::SERVICE_WAP; + } + elseif ($type == 'app') + { + $this->service = self::SERVICE_APP; + } + } + + /** + * 生成请求参数的签名 + * + * @param $params <Array> + * @return <String> + * + */ + function signParameters($params) + { + // 支付宝的签名串必须是未经过 urlencode 的字符串 + // 不清楚为何 PHP 5.5 里没有 http_build_str() 方法 + $paramStr = urldecode(http_build_query($params)); + switch (strtoupper(trim($this->config['sign_type']))) + { + case "MD5" : + $result = md5($paramStr . $this->config['key']); + break; + case "RSA" : + case "0001" : + $priKey = file_get_contents($this->config['private_key_path']); + $res = openssl_get_privatekey($priKey); + openssl_sign($paramStr, $sign, $res); + openssl_free_key($res); + //base64编码 + $result = base64_encode($sign); + break; + default : + $result = ""; + } + return $result; + } + + /** + * 准备签名参数 + * + * @param $params <Array> + * $params['out_trade_no'] 唯一订单编号 + * $params['subject'] + * $params['total_fee'] + * $params['body'] + * $params['show_url'] + * $params['anti_phishing_key'] + * $params['exter_invoke_ip'] + * $params['it_b_pay'] + * $params['_input_charset'] + * @return <Array> + */ + function prepareParameters($params) + { + $default = array( + 'service' => $this->service, + 'partner' => $this->config['partner'], + '_input_charset' => trim(strtolower($this->config['input_charset'])) + ); + if (!$this->is_mobile) + { + $default = array_merge($default, array( + 'payment_type' => $this->config['payment_type'], + 'seller_id' => $this->config['partner'], + 'notify_url' => $this->config['notify_url'], + )); + if (isset($this->config['return_url'])) + { + $default['return_url'] = $this->config['return_url']; + } + } + + $params = $this->filterSignParameter(array_merge($default, (array) $params)); + ksort($params); + reset($params); + return $params; + } + + /** + * 生成签名后的请求参数 + * + */ + function buildSignedParameters($params) + { + $params = $this->prepareParameters($params); + $params['sign'] = $this->signParameters($params); + if ($params['service'] != self::SERVICE_WAP && $params['service'] != self::SERVICE_WAP_AUTH) + { + $params['sign_type'] = strtoupper(trim($this->config['sign_type'])); + } + return $params; + } + + /** + * https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.NgdeQA&treeId=59&articleId=103663&docType=1 + * 服务端生成app支付使用的参数以及签名 + * @param $params <Array> + * @return <Array> + */ + function buildSignedParametersForApp($params) + { + $params = $this->prepareParameters($params); + $params['sign'] = urlencode($this->signParameters($params)); + $params['sign_type'] = 'RSA'; + $paramStr = []; + foreach ($params as $k => &$param) + { + $param = '"' . $param . '"'; + $paramStr[] = $k . '=' . $param; + } + + return implode('&', $paramStr); + } + + /** + * 生成请求参数的发送表单HTML + * + * 其实这个函数没有必要,更应该使用签名后的参数自己组装,只不过有时候方便就从官方 SDK 里留下了。 + * + * @param $params <Array> 请求参数(未签名的) + * @param $method <String> 请求方法,默认:post,可选 get + * @param $target <String> 提交目标,默认:_self + * @return <String> + * + */ + function buildRequestFormHTML($params, $method = 'post', $target = '_self') + { + $params = $this->buildSignedParameters($params); + $html = '<meta charset="' . $this->config['input_charset'] . '" /><form id="alipaysubmit" name="alipaysubmit" action="' . $this->gateway . ' _input_charset="' . trim(strtolower($this->config['input_charset'])) . '" method="' . $method . ' target="$target">'; + foreach ($params as $key => $value) + { + $html .= "<input type='hidden' name='$key' value='$value'/>"; + } + $html .= "</form><script>document.forms['alipaysubmit'].submit();</script>"; + return $html; + } + + /** + * 准备移动网页支付的请求参数 + * + * 移动网页支付接口不同,需要先服务器提交一次请求,拿到返回 token 再返回客户端发起真实支付请求。 + * 该方法只完成第一次服务端请求,生成参数后需要客户端另行处理(可调用`buildRequestFormHTML`生成表单提交)。 + * + * @param $params <Array> + * $params['out_trade_no'] 订单唯一编号 + * $params['subject'] 商品标题 + * $params['total_fee'] 支付总费用 + * $params['merchant_url'] 商品链接地址 + * $params['req_id'] 请求唯一 ID + * $params['it_b_pay'] 超期时间(秒) + * @return <Array>/<NULL> + */ + function prepareMobileTradeData($params) + { + // 不要用 SimpleXML 来构建 xml 结构,因为有第一行文档申明支付宝验证不通过 + $xml_str = '<direct_trade_create_req>' . + '<notify_url>' . $this->config['notify_url'] . '</notify_url>' . + '<call_back_url>' . $this->config['return_url'] . '</call_back_url>' . + '<seller_account_name>' . $this->config['seller_email'] . '</seller_account_name>' . + '<out_trade_no>' . $params['out_trade_no'] . '</out_trade_no>' . + '<subject>' . htmlspecialchars($params['subject'], ENT_XML1, 'UTF-8') . '</subject>' . + '<total_fee>' . $params['total_fee'] . '</total_fee>' . + '<merchant_url>' . $params['merchant_url'] . '</merchant_url>' . + (isset($params['it_b_pay']) ? '<pay_expire>' . $params['it_b_pay'] . '</pay_expire>' : '') . + '</direct_trade_create_req>'; + $request_data = $this->buildSignedParameters(array( + 'service' => $this->service, + 'partner' => $this->config['partner'], + 'sec_id' => $this->config['sign_type'], + 'format' => 'xml', + 'v' => '2.0', + 'req_id' => $params['req_id'], + 'req_data' => $xml_str + )); + $url = $this->gateway; + $input_charset = trim(strtolower($this->config['input_charset'])); + if (trim($input_charset) != '') + { + $url = $url . "_input_charset=" . $input_charset; + } + $curl = curl_init($url); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); //SSL证书认证 + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); //严格认证 + curl_setopt($curl, CURLOPT_CAINFO, $this->config['cacert']); //证书地址 + curl_setopt($curl, CURLOPT_HEADER, 0); // 过滤HTTP头 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 显示输出结果 + curl_setopt($curl, CURLOPT_POST, true); // post传输数据 + curl_setopt($curl, CURLOPT_POSTFIELDS, $request_data); // post传输数据 + $responseText = curl_exec($curl); + //var_dump( curl_error($curl) );//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容 + curl_close($curl); + if (empty($responseText)) + { + return NULL; + } + parse_str($responseText, $responseData); + if (empty($responseData['res_data'])) + { + return NULL; + } + if ($this->config['sign_type'] == '0001') + { + $responseData['res_data'] = $this->rsaDecrypt($responseData['res_data'], $this->config['private_key_path']); + } + //token从res_data中解析出来(也就是说res_data中已经包含token的内容) + $doc = new DOMDocument(); + $doc->loadXML($responseData['res_data']); + $responseData['request_token'] = $doc->getElementsByTagName("request_token")->item(0)->nodeValue; + $xml_str = '<auth_and_execute_req>' . + '<request_token>' . $responseData['request_token'] . '</request_token>' . + '</auth_and_execute_req>'; + return array( + 'service' => self::SERVICE_WAP_AUTH, + 'partner' => $this->config['partner'], + 'sec_id' => $this->config['sign_type'], + 'format' => 'xml', + 'v' => '2.0', + 'req_data' => $xml_str + ); + } + + /** + * 支付完成验证返回参数(包含同步和异步) + * + * @return <Boolean> + */ + function verifyCallback() + { + $async = empty($_GET); + $data = $async ? $_POST : $_GET; + if (empty($data)) + { + return FALSE; + } + $signValid = $this->verifyParameters($data, $data["sign"]); + $notify_id = isset($data['notify_id']) ? $data['notify_id'] : NULL; + if ($async && $this->is_mobile) + { + //对notify_data解密 + if ($this->config['sign_type'] == '0001') + { + $data['notify_data'] = $this->rsaDecrypt($data['notify_data'], $this->config['private_key_path']); + } + //notify_id从decrypt_post_para中解析出来(也就是说decrypt_post_para中已经包含notify_id的内容) + $doc = new DOMDocument(); + $doc->loadXML($data['notify_data']); + $notify_id = $doc->getElementsByTagName('notify_id')->item(0)->nodeValue; + } + //获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息) + $responseTxt = 'true'; + if (!empty($notify_id)) + { + $responseTxt = $this->verifyFromServer($notify_id); + } + //验证 + //$signValid的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关 + //$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关 + return $signValid && preg_match("/true$/i", $responseTxt); + } + + function verifyParameters($params, $sign) + { + $params = $this->filterSignParameter($params); + if (isset($params['notify_data'])) + { + $params = array( + 'service' => $params['service'], + 'v' => $params['v'], + 'sec_id' => $params['sec_id'], + 'notify_data' => $params['notify_data'] + ); + } + else + { + ksort($params); + reset($params); + } + $content = urldecode(http_build_query($params)); + switch (strtoupper(trim($this->config['sign_type']))) + { + case "MD5" : + return md5($content . $this->config['key']) == $sign; + case "RSA" : + case "0001" : + return $this->rsaVerify($content, $this->config['public_key_path'], $sign); + default : + return FALSE; + } + } + + /** + * 过滤参数,去除sign/sign_type参数 + * @param $params + * @return <Array> + */ + function filterSignParameter($params) + { + $result = array(); + foreach ($params as $key => $value) + { + if ($key != 'sign' && $key != 'sign_type' && $value) + { + $result[$key] = $value; + } + } + return $result; + } + + function verifyFromServer($notify_id) + { + $transport = strtolower(trim($this->config['transport'])); + $partner = trim($this->config['partner']); + $veryfy_url = ($transport == 'https' ? self::VERIFY_URL_HTTPS : self::VERIFY_URL) . "partner=$partner¬ify_id=$notify_id"; + $curl = curl_init($veryfy_url); + curl_setopt($curl, CURLOPT_HEADER, 0); // 过滤HTTP头 + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); //SSL证书认证 + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); //严格认证 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 显示输出结果 + curl_setopt($curl, CURLOPT_CAINFO, $this->config['cacert']); //证书地址 + $responseText = curl_exec($curl); + // var_dump( curl_error($curl) );//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容 + curl_close($curl); + return $responseText; + } + + /** + * RSA验签,注意验签的公钥是支付宝的公钥,不是自己生成的rsa公钥,可以在淘宝的demo中获得 + * @param $data string 待签名数据 + * @param $ali_public_key_path string 支付宝的公钥文件路径 + * @param $sign string 要校对的的签名结果 + * @return <Boolean> 验证结果 + * @throws Exception + */ + function rsaVerify($data, $ali_public_key_path, $sign) + { + $pubKey = file_get_contents($ali_public_key_path); + $res = openssl_get_publickey($pubKey); + if (!$res) + { + throw new Exception('公钥格式错误'); + } + $result = (bool) openssl_verify($data, base64_decode($sign), $res); + openssl_free_key($res); + return $result; + } + + /** + * RSA解密 + * @param $content string 需要解密的内容,密文 + * @param $private_key_path string 商户私钥文件路径 + * @return string 解密后内容,明文 + */ + function rsaDecrypt($content, $private_key_path) + { + $priKey = file_get_contents($private_key_path); + $res = openssl_get_privatekey($priKey); + //用base64将内容还原成二进制 + $content = base64_decode($content); + //把需要解密的内容,按128位拆开解密 + $result = ''; + for ($i = 0; $i < strlen($content) / 128; $i++) + { + $data = substr($content, $i * 128, 128); + openssl_private_decrypt($data, $decrypt, $res); + $result .= $decrypt; + } + openssl_free_key($res); + return $result; + } + +} diff --git a/extend/fast/payment/Wechat.php b/extend/fast/payment/Wechat.php new file mode 100644 index 0000000..fc02c94 --- /dev/null +++ b/extend/fast/payment/Wechat.php @@ -0,0 +1,440 @@ +<?php + +namespace fast\payment; + +use Exception; +use think\Config; + +/** + * @link https://github.com/zhangv/wechat-pay + */ +class Wechat +{ + + const TRADETYPE_JSAPI = 'JSAPI', TRADETYPE_NATIVE = 'NATIVE', TRADETYPE_APP = 'APP'; + const URL_UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder"; + const URL_ORDERQUERY = "https://api.mch.weixin.qq.com/pay/orderquery"; + const URL_CLOSEORDER = 'https://api.mch.weixin.qq.com/pay/closeorder'; + const URL_REFUND = 'https://api.mch.weixin.qq.com/secapi/pay/refund'; + const URL_REFUNDQUERY = 'https://api.mch.weixin.qq.com/pay/refundquery'; + const URL_DOWNLOADBILL = 'https://api.mch.weixin.qq.com/pay/downloadbill'; + const URL_REPORT = 'https://api.mch.weixin.qq.com/payitil/report'; + const URL_SHORTURL = 'https://api.mch.weixin.qq.com/tools/shorturl'; + const URL_MICROPAY = 'https://api.mch.weixin.qq.com/pay/micropay'; + + /** + * 错误信息 + */ + public $error = null; + + /** + * 错误信息XML + */ + public $errorXML = null; + + /** + * 微信支付配置数组 + * appid 公众账号appid + * mch_id 商户号 + * apikey 加密key + * appsecret 公众号appsecret + * sslcertPath 证书路径(apiclient_cert.pem) + * sslkeyPath 密钥路径(apiclient_key.pem) + */ + private $_config; + + /** + * @param $options 微信支付配置数组 + */ + public function __construct($options = []) + { + if ($config = Config::get('payment.wechat')) + { + $this->config = array_merge($this->config, $config); + } + $this->_config = array_merge($this->_config, is_array($options) ? $options : []); + } + + /** + * JSAPI获取prepay_id + * + * @param string $body + * @param string $out_trade_no + * @param int $total_fee + * @param string $openid + * @param array $ext + * @return string + */ + public function getPrepayId($body, $out_trade_no, $total_fee, $openid, $ext = null) + { + $data = $ext? : []; + $data["nonce_str"] = $this->getNonceStr(); + $data["body"] = $body; + $data["out_trade_no"] = $out_trade_no; + $data["total_fee"] = $total_fee; + $data["spbill_create_ip"] = $_SERVER["REMOTE_ADDR"]; + $data["trade_type"] = self::TRADETYPE_JSAPI; + $data["openid"] = $openid; + $result = $this->unifiedOrder($data); + if ($result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS") + { + return $result["prepay_id"]; + } + else + { + $this->error = $result["return_code"] == "SUCCESS" ? $result["err_code_des"] : $result["return_msg"]; + $this->errorXML = $this->array2xml($result); + return null; + } + } + + private function getNonceStr() + { + return substr(str_shuffle("abcdefghijklmnopqrstuvwxyz0123456789"), 0, 32); + } + + /** + * 统一下单接口 + */ + public function unifiedOrder($params) + { + $data = array(); + $data["appid"] = $this->_config["appid"]; + $data["mch_id"] = $this->_config["mch_id"]; + $data["device_info"] = (isset($params['device_info']) && trim($params['device_info']) != '') ? $params['device_info'] : null; + $data["nonce_str"] = $this->getNonceStr(); + $data["body"] = $params['body']; + $data["detail"] = isset($params['detail']) ? $params['detail'] : null; //optional + $data["attach"] = isset($params['attach']) ? $params['attach'] : null; //optional + $data["out_trade_no"] = isset($params['out_trade_no']) ? $params['out_trade_no'] : null; + $data["fee_type"] = isset($params['fee_type']) ? $params['fee_type'] : 'CNY'; + $data["total_fee"] = $params['total_fee']; + $data["spbill_create_ip"] = $params['spbill_create_ip']; + $data["time_start"] = isset($params['time_start']) ? $params['time_start'] : null; //optional + $data["time_expire"] = isset($params['time_expire']) ? $params['time_expire'] : null; //optional + $data["goods_tag"] = isset($params['goods_tag']) ? $params['goods_tag'] : null; + $data["notify_url"] = isset($params['notify_url']) ? $params['notify_url'] : $this->_config['notify_url']; + $data["trade_type"] = $params['trade_type']; + $data["product_id"] = isset($params['product_id']) ? $params['product_id'] : null; //required when trade_type = NATIVE + $data["openid"] = isset($params['openid']) ? $params['openid'] : null; //required when trade_type = JSAPI + $result = $this->post(self::URL_UNIFIEDORDER, $data); + return $result; + } + + private function post($url, $data, $cert = false) + { + if (!isset($data['sign'])) + $data["sign"] = $this->sign($data); + $xml = $this->array2xml($data); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_URL, $url); + if ($cert == true) + { + //使用证书:cert 与 key 分别属于两个.pem文件 + curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); + curl_setopt($ch, CURLOPT_SSLCERT, $this->_config['sslcertPath']); + curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM'); + curl_setopt($ch, CURLOPT_SSLKEY, $this->_config['sslkeyPath']); + } + $content = curl_exec($ch); + $array = $this->xml2array($content); + return $array; + } + + /** + * 扫码支付(模式二)获取支付二维码 + * + * @param string $body + * @param string $out_trade_no + * @param int $total_fee + * @param string $product_id + * @param array $ext + * @return string + */ + public function getCodeUrl($body, $out_trade_no, $total_fee, $product_id, $ext = null) + { + $data = $ext ? $ext : []; + $data["nonce_str"] = $this->getNonceStr(); + $data["body"] = $body; + $data["out_trade_no"] = $out_trade_no; + $data["total_fee"] = $total_fee; + $data["spbill_create_ip"] = $_SERVER["SERVER_ADDR"]; + $data["trade_type"] = self::TRADETYPE_NATIVE; + $data["product_id"] = $product_id; + $result = $this->unifiedOrder($data); + if ($result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS") + { + return $result["code_url"]; + } + else + { + $this->error = $result["return_code"] == "SUCCESS" ? $result["err_code_des"] : $result["return_msg"]; + return null; + } + } + + /** + * 查询订单 + * @param $transaction_id + * @param $out_trade_no + * @return array + */ + public function orderQuery($transaction_id, $out_trade_no) + { + $data = array(); + $data["appid"] = $this->_config["appid"]; + $data["mch_id"] = $this->_config["mch_id"]; + $data["transaction_id"] = $transaction_id; + $data["out_trade_no"] = $out_trade_no; + $data["nonce_str"] = $this->getNonceStr(); + $result = $this->post(self::URL_ORDERQUERY, $data); + return $result; + } + + /** + * 关闭订单 + * @param $out_trade_no + * @return array + */ + public function closeOrder($out_trade_no) + { + $data = array(); + $data["appid"] = $this->_config["appid"]; + $data["mch_id"] = $this->_config["mch_id"]; + $data["out_trade_no"] = $out_trade_no; + $data["nonce_str"] = $this->getNonceStr(); + $result = $this->post(self::URL_CLOSEORDER, $data); + return $result; + } + + /** + * 申请退款 - 使用商户订单号 + * @param $out_trade_no 商户订单号 + * @param $out_refund_no 退款单号 + * @param $total_fee 总金额(单位:分) + * @param $refund_fee 退款金额(单位:分) + * @param $op_user_id 操作员账号 + * @return array + */ + public function refund($out_trade_no, $out_refund_no, $total_fee, $refund_fee, $op_user_id) + { + $data = array(); + $data["appid"] = $this->_config["appid"]; + $data["mch_id"] = $this->_config["mch_id"]; + $data["nonce_str"] = $this->getNonceStr(); + $data["out_trade_no"] = $out_trade_no; + $data["out_refund_no"] = $out_refund_no; + $data["total_fee"] = $total_fee; + $data["refund_fee"] = $refund_fee; + $data["op_user_id"] = $op_user_id; + $result = $this->post(self::URL_REFUND, $data, true); + return $result; + } + + /** + * 申请退款 - 使用微信订单号 + * @param $transaction_id 微信订单号 + * @param $out_refund_no 退款单号 + * @param $total_fee 总金额(单位:分) + * @param $refund_fee 退款金额(单位:分) + * @param $op_user_id 操作员账号 + * @return array + */ + public function refundByTransId($transaction_id, $out_refund_no, $total_fee, $refund_fee, $op_user_id) + { + $data = array(); + $data["appid"] = $this->_config["appid"]; + $data["mch_id"] = $this->_config["mch_id"]; + $data["nonce_str"] = $this->getNonceStr(); + $data["transaction_id"] = $transaction_id; + $data["out_refund_no"] = $out_refund_no; + $data["total_fee"] = $total_fee; + $data["refund_fee"] = $refund_fee; + $data["op_user_id"] = $op_user_id; + $result = $this->post(self::URL_REFUND, $data, true); + return $result; + } + + /** + * 下载对账单 + * @param $bill_date 下载对账单的日期,格式:20140603 + * @param string $bill_type 类型 + * @return array + */ + public function downloadBill($bill_date, $bill_type = 'ALL') + { + $data = array(); + $data["appid"] = $this->_config["appid"]; + $data["mch_id"] = $this->_config["mch_id"]; + $data["bill_date"] = $bill_date; + $data["bill_type"] = $bill_type; + $data["nonce_str"] = $this->getNonceStr(); + $result = $this->post(self::URL_DOWNLOADBILL, $data); + return $result; + } + + /** + * 扫码原生支付模式一中的二维码链接转成短链接 + * @param $long_url 需要转换的URL,签名用原串,传输需URLencode + * @return array + */ + public function shortUrl($long_url) + { + $data = array(); + $data["appid"] = $this->_config["appid"]; + $data["mch_id"] = $this->_config["mch_id"]; + $data["long_url"] = $long_url; + $data["nonce_str"] = $this->getNonceStr(); + $data["sign"] = $this->sign($data); + $data["long_url"] = urlencode($long_url); + $result = $this->post(self::URL_SHORTURL, $data); + return $result; + } + + /** + * 获取jsapi支付所需参数 + * + * @param string $prepay_id + * @return array + */ + public function getPackageData($prepay_id) + { + $data = array(); + $data["appId"] = $this->_config["appid"]; + //解决微信支付调用JSAPI缺少参数:timeStamp + $data["timeStamp"] = time(); + $data["nonceStr"] = $this->getNonceStr(); + $data["package"] = "prepay_id=$prepay_id"; + $data["signType"] = "MD5"; + $data["paySign"] = $this->sign($data); + return $data; + } + + /** + * 获取发送到通知地址的数据(在通知地址内使用) + * @return string 结果数组,如果不是微信服务器发送的数据返回null + * appid + * bank_type + * cash_fee + * fee_type + * is_subscribe + * mch_id + * nonce_str + * openid + * out_trade_no 商户订单号 + * result_code + * return_code + * sign + * time_end + * total_fee 总金额 + * trade_type + * transaction_id 微信支付订单号 + */ + public function getNotifyData() + { + $xml = file_get_contents("php://input"); + $data = $this->xml2array($xml); + if ($this->validate($data)) + { + return $data; + } + else + { + return null; + } + } + + /** + * 验证数据签名 + * @param $data 数据数组 + * @return 数据校验结果 + */ + public function validate($data) + { + if (!isset($data["sign"])) + { + return false; + } + $sign = $data["sign"]; + unset($data["sign"]); + return $this->sign($data) == $sign; + } + + /** + * 响应微信支付后台通知 + * @param string $return_code 返回状态码 SUCCESS/FAIL + * @param $return_msg 返回信息 + */ + public function response_back($return_code = "SUCCESS", $return_msg = null) + { + $data = array(); + $data["return_code"] = $return_code; + if ($return_msg) + { + $data["return_msg"] = $return_msg; + } + $xml = $this->array2xml($data); + print $xml; + } + + /** + * 数据签名 + * @param $data + * @return string + */ + private function sign($data) + { + ksort($data); + $string1 = ""; + foreach ($data as $k => $v) + { + if ($v && trim($v) != '') + { + $string1 .= "$k=$v&"; + } + } + $stringSignTemp = $string1 . "key=" . $this->_config["apikey"]; + $sign = strtoupper(md5($stringSignTemp)); + return $sign; + } + + private function array2xml($array) + { + $xml = "<xml>" . PHP_EOL; + foreach ($array as $k => $v) + { + if ($v && trim($v) != '') + $xml .= "<$k><![CDATA[$v]]></$k>" . PHP_EOL; + } + $xml .= "</xml>"; + return $xml; + } + + private function xml2array($xml) + { + $array = array(); + $tmp = null; + try + { + $tmp = (array) simplexml_load_string($xml); + } + catch (Exception $e) + { + + } + if ($tmp && is_array($tmp)) + { + foreach ($tmp as $k => $v) + { + $array[$k] = (string) $v; + } + } + return $array; + } + +} diff --git a/extend/fast/service/Alisms.php b/extend/fast/service/Alisms.php new file mode 100644 index 0000000..92d87cf --- /dev/null +++ b/extend/fast/service/Alisms.php @@ -0,0 +1,167 @@ +<?php + +namespace fast\service; + +use think\Config; + +/** + * 阿里大于SMS短信发送 + */ +class Alisms +{ + + private $_params = []; + public $error = []; + protected $config = []; + + public function __construct($options = []) + { + if ($config = Config::get('service.alisms')) + { + $this->config = array_merge($this->config, $config); + } + $this->config = array_merge($this->config, is_array($options) ? $options : []); + } + + /** + * 单例 + * @param array $options 参数 + * @return Alisms + */ + public static function instance($options = []) + { + if (is_null(self::$instance)) + { + self::$instance = new static($options); + } + + return self::$instance; + } + + /** + * 设置签名 + * @param string $sign + * @return Alisms + */ + public function sign($sign = '') + { + $this->_params['sms_free_sign_name'] = $sign; + return $this; + } + + /** + * 设置参数 + * @param array $param + * @return Alisms + */ + public function param(array $param = []) + { + foreach ($param as $k => &$v) + { + $v = (string) $v; + } + unset($v); + $this->_params['sms_param'] = json_encode($param); + return $this; + } + + /** + * 设置模板 + * @param string $code 短信模板 + * @return Alisms + */ + public function template($code = '') + { + $this->_params['sms_template_code'] = $code; + return $this; + } + + /** + * 接收手机 + * @param string $mobile 手机号码 + * @return Alisms + */ + public function mobile($mobile = '') + { + $this->_params['rec_num'] = $mobile; + return $this; + } + + /** + * 立即发送 + * @return boolean + */ + public function send() + { + $this->error = []; + $params = $this->_params(); + $params['sign'] = $this->_signed($params); + $reponse = $this->_curl($params); + if ($reponse !== FALSE) + { + $res = json_decode($reponse, TRUE); + $res = array_pop($res); + if (isset($res['result'])) + return TRUE; + $this->error = $res; + } + else + { + $this->error = array('code' => 0, 'msg' => 'HTTP_RESPONSE_NOT_WELL_FORMED'); + } + return FALSE; + } + + /** + * 获取错误信息 + * @return array + */ + public function getError() + { + return $this->error; + } + + private function _params() + { + return array_merge([ + 'app_key' => $this->config['key'], + 'format' => 'json', + 'method' => 'alibaba.aliqin.fc.sms.num.send', + 'v' => '2.0', + 'timestamp' => date('Y-m-d H:i:s'), + 'sign_method' => 'md5', + 'sms_type' => 'normal' + ], $this->_params); + } + + private function _signed($params) + { + ksort($params); + $sign = $this->config['secret']; + foreach ($params as $k => $v) + { + if (is_string($v) && '@' != substr($v, 0, 1)) + $sign .= $k . $v; + } + $sign .= $this->config['secret']; + return strtoupper(md5($sign)); + } + + private function _curl($params) + { + $uri = 'https://eco.taobao.com/router/rest?' . http_build_query($params); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_setopt($ch, CURLOPT_URL, $uri); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); + curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.98 Safari/537.36"); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + $reponse = curl_exec($ch); + curl_close($ch); + return $reponse; + } + +} diff --git a/extend/fast/service/Easemob.php b/extend/fast/service/Easemob.php new file mode 100644 index 0000000..c1a9da5 --- /dev/null +++ b/extend/fast/service/Easemob.php @@ -0,0 +1,307 @@ +<?php + +namespace fast\service; + +use fast\Http; +use think\Cache; +use think\Config; +use think\Log; + +/** + * 环信消息类 + */ +class Easemob +{ + + const URL = 'https://a1.easemob.com'; + + static $_config = null; + + /** + * 创建用户 + * + * @param string $username 用户名 + * @param string $password 密码 + * @param string $nickname 昵称 + * @param boolean $token 是否认证模式 + * @return array + */ + public static function register($username, $password, $nickname = '', $token = TRUE) + { + $params = ['username' => $username, 'password' => $password]; + if ($nickname) + { + $params['nickname'] = $nickname; + } + return self::api('users', $params, $token); + } + + /** + * 创建聊天室 + * + * @param string $name 名称 + * @param string $description 描述 + * @param string $owner 创建人 + * @param int $maxusers 最多参与者 + * @param array $members 成员 + * @return array + */ + public static function createRoom($name, $description, $owner, $maxusers = 5000, $members = []) + { + $owner = (string) $owner; + $params = [ + "name" => $name, //聊天室名称,此属性为必须的 + "description" => $description, //聊天室描述,此属性为必须的 + "maxusers" => $maxusers, //聊天室成员最大数(包括群主),值为数值类型,默认值200,最大值5000,此属性为可选的 + "owner" => $owner, //聊天室的管理员,此属性为必须的 + ]; + if ($members) + { + if (!in_array($owner, $members)) + { + $members[] = $owner; + } + $params['members'] = $members; + } + return self::api('chatrooms', $params, TRUE); + } + + /** + * 创建群组 + * + * @param string $name 名称 + * @param string $description 描述 + * @param string $owner 管理员 + * @param int $maxusers 最大成员数量 + * @param array $members 成员列表 + * @param boolean $public 是否公开 + * @param boolean $approval 加入是否审核 + * @return array + */ + public static function createGroup($name, $description, $owner, $maxusers = 2000, $members = [], $public = TRUE, $approval = FALSE) + { + $owner = (string) $owner; + $params = [ + "groupname" => $name, + "desc" => $description, + "public" => (bool) $public, + "maxusers" => $maxusers, + "approval" => (bool) $approval, + "owner" => $owner, + ]; + if ($members) + { + if (!in_array($owner, $members)) + { + $members[] = $owner; + } + $params['members'] = $members; + } + return self::api('chatgroups', $params, TRUE); + } + + /** + * 修改群组信息 + * + * @param int $group_id + * @param string $name + * @param string $description + * @param int $maxusers + * @return array + */ + public static function editGroup($group_id, $name, $description, $maxusers) + { + $params = [ + "groupname" => $name, + "desc" => $description, + "maxusers" => $maxusers, + ]; + return self::api('chatgroups/' . $group_id, $params, TRUE, 'PUT'); + } + + /** + * 获取好友列表 + */ + public static function getFiends($owner_username) + { + return self::api("users/{$owner_username}/contacts/users", [], TRUE, 'GET'); + } + + /** + * 删除群组 + * + * @param int $group_id + * @return array + */ + public static function deleteGroup($group_id) + { + $params = []; + return self::api('chatgroups/' . $group_id, $params, TRUE, 'DELETE'); + } + + /** + * 发送消息 + * + * @param string $from 发件人 + * @param string $to 收件人 + * @param mixed $msg 消息内容 + * @param string $target_type 消息类型 users/chatgroups/chatrooms + * @return array + */ + public static function sendMessage($from, $to, $msg, $target_type = 'users') + { + if (!is_array($msg)) + { + $msg = [ + 'type' => 'txt', + 'msg' => $msg + ]; + } + $data = [ + 'target_type' => $target_type, + 'target' => is_array($to) ? $to : [$to], + 'from' => $from, + ]; + if (isset($msg['ext'])) + { + $data['ext'] = $msg['ext']; + } + unset($msg['ext']); + $data['msg'] = $msg; + return self::api('messages', $data); + } + + /** + * 获取离线消息记录条数 + * @param string $owner_username + * @return array + */ + public static function getOfflineMsgCount($owner_username) + { + return self::api("users/{$owner_username}/offline_msg_count", [], TRUE, 'GET'); + } + + /** + * 群组添加成员 + * @param int $chatroom_id + * @param array $usernames + * @param array + */ + public static function addChatRoomMembers($chatroom_id, $usernames) + { + return self::api("chatgroups/{$chatroom_id}/users", $usernames, TRUE); + } + + /** + * 添加单个成员POST + */ + public static function addOneChatRoomMember($chatroom_id, $username) + { + //return $chatroom_id; + return self::api("chatgroups/{$chatroom_id}/users/{$username}", [], TRUE); + } + + /** + * 群组删除成员 + * @param int $chatroom_id + * @param string $usernames + * @return array + */ + public static function minusChatRoomMembers($chatroom_id, $usernames) + { + return self::api("chatgroups/{$chatroom_id}/users/{$usernames}", [], TRUE, 'DELETE'); + } + + /** + * 添加好友 + */ + public static function addFriends($owner_username, $friend_username) + { + return self::api("users/{$owner_username}/contacts/users/{$friend_username}", [], TRUE); + } + + /** + * 删除好友 + */ + public static function minusFriends($owner_username, $friend_username) + { + return self::api("users/{$owner_username}/contacts/users/{$friend_username}", [], TRUE, 'DELETE'); + } + + /** + * 查看用户参与的所有群组 + * @param type $owner_username + * @return type + */ + public static function joinedChatgroups($owner_username) + { + return self::api("users/{$owner_username}/joined_chatgroups", [], TRUE, 'GET'); + } + + /** + * 调用API接口 + * + * @param string $api 接口 + * @param array $params request head参数 + * @param boolean $token 是否认证模式 + * @param string $method 请求方法 POST/GET + * @param array $options 扩展配置 + * @return array + */ + public static function api($api, $params = [], $token = TRUE, $method = 'POST', $options = []) + { + $header = ['Content-Type:application/json']; + if ($token) + { + $header[] = self::getNewToken(); + } + $config = Config::get('service.easemob'); + $options[CURLOPT_HTTPHEADER] = $header; + + $url = self::URL . '/' . $config['org_name'] . '/' . $config['app_name'] . '/' . $api; + //return $url; + $ret = Http::sendRequest($url, json_encode($params), $method, $options); + if ($ret['ret'] && $ret['msg']) + { + $msg = json_decode($ret['msg'], TRUE); + if (isset($msg['error'])) + { + Log::error($ret['msg']); + } + return isset($msg['error']) ? [] : $msg; + } + else + { + return []; + } + } + + private static function getToken() + { + $tokendata = Cache::get('easemobtoken'); + if ($tokendata && $tokendata['expiretime'] > time()) + { + return $tokendata['access_token']; + } + else + { + $config = Config::get('service.easemob'); + $data = self::api('token', [ + 'grant_type' => 'client_credentials', + 'client_id' => $config['client_id'], + 'client_secret' => $config['client_secret'], + ], FALSE, 'POST'); + if ($data) + { + $data['expiretime'] = time() + $data['expires_in']; + Cache::set('easemobtoken', $data, $data['expires_in'] - 10); + return $data['access_token']; + } + else + { + return ''; + } + } + } + +} diff --git a/extend/fast/service/Qiniu.php b/extend/fast/service/Qiniu.php new file mode 100644 index 0000000..c240bd5 --- /dev/null +++ b/extend/fast/service/Qiniu.php @@ -0,0 +1,187 @@ +<?php + +namespace fast\service; + +use think\Config; +use think\Log; + +/** + * 七牛上传文件管理 + */ +class Qiniu +{ + + const QINIU_RS = 'http://rs.qbox.me'; + + static $_config = null; + + /** + * 获取文件 + * + * @param string $domain 域名 + * @param string $name 文件名 + * @param string $param 附加参数 + * @return string + */ + public static function download($domain, $name, $param = []) + { + $url = $domain . $name . '?' . http_build_query($param); + $token = self::sign($url); + return $url . '&token=' . $token; + } + + /** + * 重命名【移动】 + * + * @param string $from 来源位置 + * @param string $to 目标位置 + * return bool + */ + public static function move($from, $to) + { + // $bucket = $this->_config['bucket']; + $op = '/move/' . self::qiniuEncode($from) . '/' . self::qiniuEncode($to); + return self::opration($op); + } + + /** + * 复制文件 + * + * @param string $from 来源文件 + * @param string $saveas 目标文件 + * @return bool + */ + public static function copy($from, $saveas) + { + // $bucket = $this->_config['bucket']; + $op = '/copy/' . self::qiniuEncode($from) . '/' . self::qiniuEncode($saveas); + return self::opration($op); + } + + /** + * 获取token + * + * @param string $bucket 空间名 + * @param string $key 密钥 + * @param int $max 文件大小限制 + * @param int $timeout 超时时间 + * @return string + */ + public static function getToken($bucket, $key, $max = 10485760, $timeout = 600) + { + $setting = array( + 'scope' => $bucket, + 'saveKey' => $key, + 'deadline' => $timeout + $_SERVER['REQUEST_TIME'], + 'fsizeLimit' => intval($max), + ); + $setting = self::qiniuEncode(json_encode($setting)); + return self::sign($setting) . ':' . $setting; + } + + /** + * 删除 + * + * @param string $uri 文件路径 + * @return boolean + */ + public static function delete($uri) + { + $file = self::qiniuEncode($uri); + return self::opration('/delete/' . $file); + } + + /** + * 判断文件是否存在 + * + * @param string $uri + * @return boolean + */ + public static function has($uri) + { + $op = '/stat/' . self::qiniuEncode($uri); + return self::opration($op); + } + + /** + * 转pdf + * + * @param string $bucket + * @param string $key + * @param string $saveas + * @return boolean + */ + public static function toPdf($bucket, $key, $saveas) + { + $API = 'http://api.qiniu.com'; + $op = '/pfop/'; + $data = 'bucket=' . $bucket . '&key=' . $key . '&fops=yifangyun_preview|saveas/' . self::qiniuEncode($saveas); + return self::opration($op, $data, $API); + } + + /** + * 七牛操作 + * + * @param string $op 操作命令 + * @param string $data 操作结果 + * @param string $host + * @return boolean + */ + private static function opration($op, $data = null, $host = self::QINIU_RS) + { + $token = self::sign(is_string($data) ? $op . "\n" . $data : $op . "\n"); + $url = $host . $op; + $header = array('Authorization: QBox ' . $token); + + if ($ch = curl_init($url)) + { + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); + if ($data) + { + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + } + curl_setopt($ch, CURLOPT_HEADER, 1); + $response = curl_exec($ch); + $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($status == 200) + { + return true; + } + // elseif (\Config::get('debug')) + // { + // /*操作出错*/ + // \Log::debug($response, '七牛请求出错'); + // } + } + Log::error('[QINIU]七牛错误' . $url . ':' . ($response ? : '请求失败'), 'ERROR'); + return false; + } + + /** + * 获取url签名 + * + * @param string $url + * @return string + */ + private static function sign($url) + { + $config = self::$_config ? : (self::$_config = Config::get('service.qiniu')); + $sign = hash_hmac('sha1', $url, $config['secretkey'], true); + $ak = $config['accesskey']; + return $ak . ':' . self::qiniuEncode($sign); + } + + /** + * 七牛安全编码 + */ + private static function qiniuEncode($str) + { + return strtr(base64_encode($str), ['+' => '-', '/' => '_']); + } + +} diff --git a/extend/fast/service/Upyun.php b/extend/fast/service/Upyun.php new file mode 100644 index 0000000..2155aee --- /dev/null +++ b/extend/fast/service/Upyun.php @@ -0,0 +1,572 @@ +<?php + +namespace fast\service; + +use Exception; +use think\Config; + +/** + * 又拍云上传管理 + */ +class Upyun +{ + + const VERSION = '2.0'; + + /* {{{ */ + const ED_AUTO = 'v0.api.upyun.com'; + const ED_TELECOM = 'v1.api.upyun.com'; + const ED_CNC = 'v2.api.upyun.com'; + const ED_CTT = 'v3.api.upyun.com'; + const CONTENT_TYPE = 'Content-Type'; + const CONTENT_MD5 = 'Content-MD5'; + const CONTENT_SECRET = 'Content-Secret'; + // 缩略图 + const X_GMKERL_THUMBNAIL = 'x-gmkerl-thumbnail'; + const X_GMKERL_TYPE = 'x-gmkerl-type'; + const X_GMKERL_VALUE = 'x-gmkerl-value'; + const X_GMKERL_QUALITY = 'xgmkerl-quality'; + const X_GMKERL_UNSHARP = 'xgmkerl-unsharp'; + + private static $_instance; + + /* }}} */ + + /** + * @deprecated + */ + private $_content_md5 = NULL; + + /** + * @deprecated + */ + private $_file_secret = NULL; + + /** + * @deprecated + */ + private $_file_infos = NULL; + + /** + * @var string: UPYUN 请求唯一id, 出现错误时, 可以将该id报告给 UPYUN,进行调试 + */ + private $x_request_id; + + /** + * 初始化 UpYun 存储接口 + */ + public function __construct($options = []) + { + if ($config = Config::get('service.upyun')) + { + $this->config = array_merge($this->config, $config); + } + $this->config = array_merge($this->config, is_array($options) ? $options : []); + } + + /* }}} */ + + /** + * 获取当前SDK版本号 + */ + public function version() + { + return self::VERSION; + } + + /** + * 创建目录 + * @param $path 路径 + * @param $auto_mkdir 是否自动创建父级目录,最多10层次 + * + * @return void + */ + public function makeDir($path, $auto_mkdir = false) + {/* {{{ */ + $headers = array('Folder' => 'true'); + if ($auto_mkdir) + $headers['Mkdir'] = 'true'; + return $this->_do_request('PUT', $path, $headers); + } + + /* }}} */ + + /** + * 删除目录和文件 + * @param string $path 路径 + * + * @return boolean + */ + public function delete($path) + {/* {{{ */ + return $this->_do_request('DELETE', $path); + } + + /* }}} */ + + /** + * 上传文件 + * @param string $path 存储路径 + * @param mixed $file 需要上传的文件,可以是文件流或者文件内容 + * @param boolean $auto_mkdir 自动创建目录 + * @param array $opts 可选参数 + */ + public function upload($path, $file = NULL, $auto_mkdir = True, $opts = NULL) + { + return $this->writeFile($path, $file = NULL, $auto_mkdir, $opts); + } + + public function writeFile($path, $file = NULL, $auto_mkdir = True, $opts = NULL) + {/* {{{ */ + if (is_null($file)) + $file = ROOT_PATH . 'public/' . $path; + if (is_null($opts)) + $opts = array(); + if (!is_null($this->_content_md5) || !is_null($this->_file_secret)) + { + //if (!is_null($this->_content_md5)) array_push($opts, self::CONTENT_MD5 . ": {$this->_content_md5}"); + //if (!is_null($this->_file_secret)) array_push($opts, self::CONTENT_SECRET . ": {$this->_file_secret}"); + if (!is_null($this->_content_md5)) + $opts[self::CONTENT_MD5] = $this->_content_md5; + if (!is_null($this->_file_secret)) + $opts[self::CONTENT_SECRET] = $this->_file_secret; + } + + // 如果设置了缩略版本或者缩略图类型,则添加默认压缩质量和锐化参数 + //if (isset($opts[self::X_GMKERL_THUMBNAIL]) || isset($opts[self::X_GMKERL_TYPE])) { + // if (!isset($opts[self::X_GMKERL_QUALITY])) $opts[self::X_GMKERL_QUALITY] = 95; + // if (!isset($opts[self::X_GMKERL_UNSHARP])) $opts[self::X_GMKERL_UNSHARP] = 'true'; + //} + + if ($auto_mkdir === True) + $opts['Mkdir'] = 'true'; + + $this->_file_infos = $this->_do_request('PUT', $path, $opts, $file); + + return $this->_file_infos; + } + + /* }}} */ + + /** + * 下载文件 + * @param string $path 文件路径 + * @param mixed $file_handle + * + * @return mixed + */ + public function readFile($path, $file_handle = NULL) + {/* {{{ */ + return $this->_do_request('GET', $path, NULL, NULL, $file_handle); + } + + /* }}} */ + + /** + * 获取目录文件列表 + * + * @param string $path 查询路径 + * + * @return mixed + */ + public function getList($path = '/') + {/* {{{ */ + $rsp = $this->_do_request('GET', $path); + + $list = array(); + if ($rsp) + { + $rsp = explode("\n", $rsp); + foreach ($rsp as $item) + { + @list($name, $type, $size, $time) = explode("\t", trim($item)); + if (!empty($time)) + { + $type = $type == 'N' ? 'file' : 'folder'; + } + + $item = array( + 'name' => $name, + 'type' => $type, + 'size' => intval($size), + 'time' => intval($time), + ); + array_push($list, $item); + } + } + + return $list; + } + + /* }}} */ + + /** + * @deprecated + * @param string $path 目录路径 + * @return mixed + */ + public function getFolderUsage($path = '/') + {/* {{{ */ + $rsp = $this->_do_request('GET', '/?usage'); + return floatval($rsp); + } + + /* }}} */ + + /** + * 获取文件、目录信息 + * + * @param string $path 路径 + * + * @return mixed + */ + public function getFileInfo($path) + {/* {{{ */ + $rsp = $this->_do_request('HEAD', $path); + + return $rsp; + } + + /* }}} */ + + /** + * 连接签名方法 + * @param $method 请求方式 {GET, POST, PUT, DELETE} + * return 签名字符串 + */ + private function sign($method, $uri, $date, $length) + {/* {{{ */ + //$uri = urlencode($uri); + $sign = "{$method}&{$uri}&{$date}&{$length}&{$this->config['password']}"; + return 'UpYun ' . $this->config['username'] . ':' . md5($sign); + } + + /* }}} */ + + /** + * HTTP REQUEST 封装 + * @param string $method HTTP REQUEST方法,包括PUT、POST、GET、OPTIONS、DELETE + * @param string $path 除Bucketname之外的请求路径,包括get参数 + * @param array $headers 请求需要的特殊HTTP HEADERS + * @param array $body 需要POST发送的数据 + * + * @return mixed + */ + protected function _do_request($method, $path, $headers = NULL, $body = NULL, $file_handle = NULL) + {/* {{{ */ + $uri = "/{$this->config['bucket']}{$path}"; + $ch = curl_init("http://{$this->config['endpoint']}{$uri}"); + + $_headers = array('Expect:'); + if (!is_null($headers) && is_array($headers)) + { + foreach ($headers as $k => $v) + { + array_push($_headers, "{$k}: {$v}"); + } + } + + $length = 0; + $date = gmdate('D, d M Y H:i:s \G\M\T'); + + if (!is_null($body)) + { + if (!is_resource($body) && file_exists($body)) + { + $body = fopen($body, "rb"); + } + if (is_resource($body)) + { + fseek($body, 0, SEEK_END); + $length = ftell($body); + fseek($body, 0); + + array_push($_headers, "Content-Length: {$length}"); + curl_setopt($ch, CURLOPT_INFILE, $body); + curl_setopt($ch, CURLOPT_INFILESIZE, $length); + } + else + { + $length = @strlen($body); + array_push($_headers, "Content-Length: {$length}"); + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + } + } + else + { + array_push($_headers, "Content-Length: {$length}"); + } + + array_push($_headers, "Authorization: {$this->sign($method, $uri, $date, $length)}"); + array_push($_headers, "Date: {$date}"); + + curl_setopt($ch, CURLOPT_HTTPHEADER, $_headers); + curl_setopt($ch, CURLOPT_TIMEOUT, $this->config['timeout']); + curl_setopt($ch, CURLOPT_HEADER, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + + if ($method == 'PUT' || $method == 'POST') + { + curl_setopt($ch, CURLOPT_POST, 1); + } + else + { + curl_setopt($ch, CURLOPT_POST, 0); + } + + if ($method == 'GET' && is_resource($file_handle)) + { + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_FILE, $file_handle); + } + + if ($method == 'HEAD') + { + curl_setopt($ch, CURLOPT_NOBODY, true); + } + $response = curl_exec($ch); + $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + if ($http_code == 0) + throw new Exception('Connection Failed', $http_code); + + curl_close($ch); + + $header_string = ''; + $body = ''; + + if ($method == 'GET' && is_resource($file_handle)) + { + $header_string = ''; + $body = $response; + } + else + { + list($header_string, $body) = explode("\r\n\r\n", $response, 2); + } + $this->setXRequestId($header_string); + if ($http_code == 200) + { + if ($method == 'GET' && is_null($file_handle)) + { + return $body; + } + else + { + $data = $this->_getHeadersData($header_string); + return count($data) > 0 ? $data : true; + } + } + else + { + $message = $this->_getErrorMessage($header_string); + if (is_null($message) && $method == 'GET' && is_resource($file_handle)) + { + $message = 'File Not Found'; + } + switch ($http_code) + { + case 401: + throw new Exception($message, $http_code); + break; + case 403: + throw new Exception($message, $http_code); + break; + case 404: + throw new Exception($message, $http_code); + break; + case 406: + throw new Exception($message, $http_code); + break; + case 503: + throw new Exception($message, $http_code); + break; + default: + throw new Exception($message, $http_code); + } + } + } + + /* }}} */ + + /** + * 处理HTTP HEADERS中返回的自定义数据 + * + * @param string $text header字符串 + * + * @return array + */ + private function _getHeadersData($text) + {/* {{{ */ + $headers = explode("\r\n", $text); + $items = array(); + foreach ($headers as $header) + { + $header = trim($header); + if (stripos($header, 'x-upyun') !== False) + { + list($k, $v) = explode(':', $header); + $items[trim($k)] = in_array(substr($k, 8, 5), array('width', 'heigh', 'frame')) ? intval($v) : trim($v); + } + } + return $items; + } + + /* }}} */ + + /** + * 获取返回的错误信息 + * + * @param string $header_string + * + * @return mixed + */ + private function _getErrorMessage($header_string) + { + list($status, $stash) = explode("\r\n", $header_string, 2); + list($v, $code, $message) = explode(" ", $status, 3); + return $message . " X-Request-Id: " . $this->getXRequestId(); + } + + private function setXRequestId($header_string) + { + preg_match('~^X-Request-Id: ([0-9a-zA-Z]{32})~ism', $header_string, $result); + $this->x_request_id = isset($result[1]) ? $result[1] : ''; + } + + public function getXRequestId() + { + return $this->x_request_id; + } + + /** + * 删除目录 + * @deprecated + * @param $path 路径 + * + * @return void + */ + public function rmDir($path) + {/* {{{ */ + $this->_do_request('DELETE', $path); + } + + /* }}} */ + + /** + * 删除文件 + * + * @deprecated + * @param string $path 要删除的文件路径 + * + * @return boolean + */ + public function deleteFile($path) + {/* {{{ */ + $rsp = $this->_do_request('DELETE', $path); + } + + /* }}} */ + + /** + * 获取目录文件列表 + * @deprecated + * + * @param string $path 要获取列表的目录 + * + * @return array + */ + public function readDir($path) + {/* {{{ */ + return $this->getList($path); + } + + /* }}} */ + + /** + * 获取空间使用情况 + * + * @deprecated 推荐直接使用 getFolderUsage('/')来获取 + * @return mixed + */ + public function getBucketUsage() + {/* {{{ */ + return $this->getFolderUsage('/'); + } + + /* }}} */ + + /** + * 获取文件信息 + * + * #deprecated + * @param $file 文件路径(包含文件名) + * return array('type'=> file | folder, 'size'=> file size, 'date'=> unix time) 或 null + */ + //public function getFileInfo($file){/*{{{*/ + // $result = $this->head($file); + // if(is_null($r))return null; + // return array('type'=> $this->tmp_infos['x-upyun-file-type'], 'size'=> @intval($this->tmp_infos['x-upyun-file-size']), 'date'=> @intval($this->tmp_infos['x-upyun-file-date'])); + //}/*}}}*/ + + /** + * 切换 API 接口的域名 + * + * @deprecated + * @param $domain {默然 v0.api.upyun.com 自动识别, v1.api.upyun.com 电信, v2.api.upyun.com 联通, v3.api.upyun.com 移动} + * return null; + */ + public function setApiDomain($domain) + {/* {{{ */ + $this->config['endpoint'] = $domain; + } + + /* }}} */ + + /** + * 设置待上传文件的 Content-MD5 值(如又拍云服务端收到的文件MD5值与用户设置的不一致,将回报 406 Not Acceptable 错误) + * + * @deprecated + * @param $str (文件 MD5 校验码) + * return null; + */ + public function setContentMD5($str) + {/* {{{ */ + $this->_content_md5 = $str; + } + + /* }}} */ + + /** + * 设置待上传文件的 访问密钥(注意:仅支持图片空!,设置密钥后,无法根据原文件URL直接访问,需带 URL 后面加上 (缩略图间隔标志符+密钥) 进行访问) + * 如缩略图间隔标志符为 ! ,密钥为 bac,上传文件路径为 /folder/test.jpg ,那么该图片的对外访问地址为: http://空间域名/folder/test.jpg!bac + * + * @deprecated + * @param $str (文件 MD5 校验码) + * return null; + */ + public function setFileSecret($str) + {/* {{{ */ + $this->_file_secret = $str; + } + + /* }}} */ + + /** + * @deprecated + * 获取上传文件后的信息(仅图片空间有返回数据) + * @param $key 信息字段名(x-upyun-width、x-upyun-height、x-upyun-frames、x-upyun-file-type) + * return value or NULL + */ + public function getWritedFileInfo($key) + {/* {{{ */ + if (!isset($this->_file_infos)) + return NULL; + return $this->_file_infos[$key]; + } + + /* }}} */ +} diff --git a/extend/fast/service/Wechat.php b/extend/fast/service/Wechat.php new file mode 100644 index 0000000..f64438b --- /dev/null +++ b/extend/fast/service/Wechat.php @@ -0,0 +1,213 @@ +<?php + +namespace fast\service; + +use app\common\model\Page; +use app\common\model\User; +use app\common\model\UserSignin; +use app\common\model\UserThird; +use EasyWeChat\Message\News; +use EasyWeChat\Message\Transfer; +use fast\Date; + +/** + * Wechat服务类 + */ +class Wechat +{ + + public function __construct() + { + + } + + public static function appConfig() + { + return array( + 'signin' => array( + 'name' => '签到送积分', + 'config' => array( + ) + ), + 'article' => array( + 'name' => '关联文章', + 'config' => array( + array( + 'type' => 'text', + 'caption' => '文章ID', + 'field' => 'id', + 'options' => '' + ) + ) + ), + 'page' => array( + 'name' => '关联单页', + 'config' => array( + array( + 'type' => 'text', + 'caption' => '单页ID', + 'field' => 'id', + 'options' => '' + ) + ) + ), + 'service' => array( + 'name' => '在线客服', + 'config' => array( + ) + ), + ); + } + + // 微信输入交互内容指令 + public function command($obj, $openid, $content, $context) + { + $content = []; + $response = FALSE; + if (isset($content['app'])) + { + switch ($content['app']) + { + case 'signin': + case 'article': + case 'page': + break; + case 'service': + $service = configvalue('service'); + list($begintime, $endtime) = explode('-', $service['onlinetime']); + $session = $obj->app->staff_session; + $staff = $obj->app->staff; + + $kf_account = $session->get($openid)->kf_account; + $time = time(); + if (!$kf_account && ($time < strtotime(date("Y-m-d {$begintime}")) || $time > strtotime(date("Y-m-d {$endtime}")))) + { + return $service['offlinemsg']; + } + if (!$kf_account) + { + $kf_list = $staff->onlines()->kf_online_list; + if ($kf_list) + { + $kfarr = []; + foreach ($kf_list as $k => $v) + { + $kfarr[$v['kf_account']] = $v['accepted_case']; + } + $kfkeys = array_keys($kfarr, min($kfarr)); + $kf_account = reset($kfkeys); + $session->create($kf_account, $openid); + $response = $service['waitformsg']; + } + else + { + $response = $service['nosessionmsg']; + } + } + else + { + $server = $obj->app->server; + $server->setMessageHandler(function($message) + { + return new Transfer(); + }); + $response = $server->serve(); + $response->send(); + exit; + } + + break; + default: + break; + } + } + else + { + $response = isset($content['content']) ? $content['content'] : $response; + } + return $response; + } + + // 微信点击菜单event指令 + public function response($obj, $openid, $content, $context) + { + $content = []; + $response = FALSE; + if (isset($content['app'])) + { + switch ($content['app']) + { + case 'signin': + $thirdinfo = UserThird::get(['platform' => 'wechat', 'openid' => $openid]); + if (!$thirdinfo) + { + $response = '您还没有<a href="' . url('user/profile', 1) . '">绑定用户</a>还不能签到!'; + } + else + { + $user_id = $thirdinfo->user_id; + $usersign = new UserSignin; + $signdata = $usersign->get([['user_id', '=', $user_id], ['createtime', '>=', Date::unixtime()]]); + if ($signdata) + { + $response = '今天已签到,请明天再来!'; + } + else + { + $signdata = configvalue('signin'); + + $lastdata = $usersign->where('user_id', $user_id)->order('id', 'desc')->limit(1)->get(); + $successions = $lastdata && $lastdata['createtime'] > Date::unixtime('day', -1) ? $lastdata['successions'] + 1 : 1; + $usersign->save(['user_id' => $thirdinfo['user_id'], 'successions' => $successions, 'createtime' => time()]); + $score = isset($signdata['s' . $successions]) ? $signdata['s' . $successions] : $signdata['sn']; + User::where(['id' => $user_id])->setInc('score', $score); + $response = '签到成功!连续签到' . $successions . '天!获得' . $score . '积分'; + } + } + + break; + case 'article': + $id = explode(',', $content['id']); + $pagelist = Page::all($id); + $response = []; + foreach ($pagelist as $k => $pageinfo) + { + if ($pageinfo) + { + $news = new News(); + $news->title = $pageinfo['title']; + $news->url = $pageinfo['outlink'] ? $pageinfo['outlink'] : url('page/show/' . $pageinfo['id'], 1); + $news->image = cdn($pageinfo['image']); + $news->description = $pageinfo['description']; + $response[] = $news; + } + } + + case 'page': + $id = isset($content['id']) ? $content['id'] : 0; + $pageinfo = Page::get($id); + if ($pageinfo) + { + $news = new News(); + $news->title = $pageinfo['title']; + $news->url = $pageinfo['outlink'] ? $pageinfo['outlink'] : url('page/show/' . $pageinfo['id'], 1); + $news->image = cdn($pageinfo['image']); + $news->description = $pageinfo['description']; + return $news; + } + break; + case 'service': + $response = $this->command($obj, $openid, $content, $context); + break; + default: + break; + } + } + else + { + $response = isset($content['content']) ? $content['content'] : $response; + } + return $response; + } + +} diff --git a/extend/fast/third/Application.php b/extend/fast/third/Application.php new file mode 100644 index 0000000..de16a3a --- /dev/null +++ b/extend/fast/third/Application.php @@ -0,0 +1,76 @@ +<?php + +namespace fast\third; + +use think\Config; + +class Application +{ + + /** + * 配置信息 + * @var array + */ + private $config = []; + + /** + * 服务提供者 + * @var array + */ + private $providers = [ + 'qq' => 'Qq', + 'weibo' => 'Weibo', + 'wechat' => 'Wechat', + ]; + + /** + * 服务对象信息 + * @var array + */ + protected $services = []; + + public function __construct($options = []) + { + if ($config = Config::get('third')) + { + $this->config = array_merge($this->config, $config); + } + $this->config = array_merge($this->config, is_array($options) ? $options : []); + + //注册服务器提供者 + $this->registerProviders(); + } + + /** + * 注册服务提供者 + */ + private function registerProviders() + { + foreach ($this->providers as $k => $v) + { + $this->services[$k] = function() use ($k, $v) + { + $options = $this->config[$k]; + $options['app_id'] = isset($options['app_id']) ? $options['app_id'] : ''; + $options['app_secret'] = isset($options['app_secret']) ? $options['app_secret'] : ''; + // 如果未定义回调地址则自动生成 + $options['callback'] = isset($options['callback']) && $options['callback'] ? $options['callback'] : url('user/third?action=callback&platform=' . $k, [], false, true); + // 如果非http地址则转换一下 + $options['callback'] = substr($options['callback'], 0, 7) == 'http://' || substr($options['callback'], 0, 8) == 'https://' ? $options['callback'] : url($options['callback'], '', false, true); + $objname = __NAMESPACE__ . "\\{$v}"; + return new $objname($options); + }; + } + } + + public function __set($key, $value) + { + $this->services[$key] = $value; + } + + public function __get($key) + { + return $this->services[$key]($this); + } + +} diff --git a/extend/fast/third/Qq.php b/extend/fast/third/Qq.php new file mode 100644 index 0000000..f7a2e65 --- /dev/null +++ b/extend/fast/third/Qq.php @@ -0,0 +1,145 @@ +<?php + +namespace fast\third; + +use fast\Http; +use think\Config; +use think\Session; + +/** + * QQ + */ +class Qq +{ + + const GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize"; + const GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token"; + const GET_USERINFO_URL = "https://graph.qq.com/user/get_user_info"; + const GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me"; + + /** + * 配置信息 + * @var array + */ + private $config = []; + + public function __construct($options = []) + { + if ($config = Config::get('third.qq')) + { + $this->config = array_merge($this->config, $config); + } + $this->config = array_merge($this->config, is_array($options) ? $options : []); + } + + /** + * 登陆 + */ + public function login() + { + header("Location:" . $this->getAuthorizeUrl()); + } + + /** + * 获取authorize_url + */ + public function getAuthorizeUrl() + { + $state = md5(uniqid(rand(), TRUE)); + Session::set('state', $state); + $queryarr = array( + "response_type" => "code", + "client_id" => $this->config['app_id'], + "redirect_uri" => $this->config['callback'], + "scope" => $this->config['scope'], + "state" => $state, + ); + request()->isMobile() && $queryarr['display'] = 'mobile'; + $url = self::GET_AUTH_CODE_URL . '?' . http_build_query($queryarr); + return $url; + } + + /** + * 获取用户信息 + * @param array $params + * @return array + */ + public function getUserInfo($params = []) + { + $params = $params ? $params : $_GET; + if (isset($params['access_token']) || (isset($params['state']) && $params['state'] == Session::get('state') && isset($params['code']))) + { + //获取access_token + $data = isset($params['code']) ? $this->getAccessToken($params['code']) : $params; + $access_token = isset($data['access_token']) ? $data['access_token'] : ''; + $refresh_token = isset($data['refresh_token']) ? $data['refresh_token'] : ''; + $expires_in = isset($data['expires_in']) ? $data['expires_in'] : 0; + if ($access_token) + { + $openid = $this->getOpenId($access_token); + //获取用户信息 + $queryarr = [ + "access_token" => $access_token, + "oauth_consumer_key" => $this->config['app_id'], + "openid" => $openid, + ]; + $ret = Http::get(self::GET_USERINFO_URL, $queryarr); + $userinfo = json_decode($ret, TRUE); + if (!$userinfo || !isset($userinfo['ret']) || $userinfo['ret'] !== 0) + return []; + $userinfo = $userinfo ? $userinfo : []; + $userinfo['avatar'] = isset($userinfo['figureurl_qq_2']) ? $userinfo['figureurl_qq_2'] : ''; + $data = [ + 'access_token' => $access_token, + 'refresh_token' => $refresh_token, + 'expires_in' => $expires_in, + 'openid' => $openid, + 'userinfo' => $userinfo + ]; + return $data; + } + } + return []; + } + + /** + * 获取access_token + * @param string $code + * @return array + */ + private function getAccessToken($code = '') + { + if (!$code) + return ''; + $queryarr = array( + "grant_type" => "authorization_code", + "client_id" => $this->config['app_id'], + "client_secret" => $this->config['app_secret'], + "redirect_uri" => $this->config['callback'], + "code" => $code, + ); + $ret = Http::get(self::GET_ACCESS_TOKEN_URL, $queryarr); + $params = []; + parse_str($ret, $params); + return $params ? $params : []; + } + + /** + * 获取open_id + * @param string $access_token + * @return string + */ + private function getOpenId($access_token = '') + { + $response = Http::get(self::GET_OPENID_URL, ['access_token' => $access_token]); + if (strpos($response, "callback") !== false) + { + $lpos = strpos($response, "("); + $rpos = strrpos($response, ")"); + $response = substr($response, $lpos + 1, $rpos - $lpos - 1); + } + $user = json_decode($response, TRUE); + return isset($user['openid']) ? $user['openid'] : ''; + } + +} diff --git a/extend/fast/third/Wechat.php b/extend/fast/third/Wechat.php new file mode 100644 index 0000000..6dd7f29 --- /dev/null +++ b/extend/fast/third/Wechat.php @@ -0,0 +1,124 @@ +<?php + +namespace fast\third; + +use fast\Http; +use think\Config; +use think\Session; + +/** + * 微博 + */ +class Wechat +{ + + const GET_AUTH_CODE_URL = "https://api.weixin.qq.com/sns/oauth2/authorize"; + const GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token"; + const GET_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo"; + + /** + * 配置信息 + * @var array + */ + private $config = []; + + public function __construct($options = []) + { + if ($config = Config::get('third.wechat')) + { + $this->config = array_merge($this->config, $config); + } + $this->config = array_merge($this->config, is_array($options) ? $options : []); + } + + /** + * 登陆 + */ + public function login() + { + header("Location:" . $this->getAuthorizeUrl()); + } + + /** + * 获取authorize_url + */ + public function getAuthorizeUrl() + { + $state = md5(uniqid(rand(), TRUE)); + Session::set('state', $state); + $queryarr = array( + "app_id" => $this->config['app_id'], + "redirect_uri" => $this->config['callback'], + "response_type" => "code", + "scope" => $this->config['scope'], + "state" => $state, + ); + request()->isMobile() && $queryarr['display'] = 'mobile'; + $url = self::GET_AUTH_CODE_URL . '?' . http_build_query($queryarr) . '#wechat_redirect'; + return $url; + } + + /** + * 获取用户信息 + * @param array $params + * @return array + */ + public function getUserInfo($params = []) + { + $params = $params ? $params : $_GET; + if (isset($params['access_token']) || (isset($params['state']) && $params['state'] == Session::get('state') && isset($params['code']))) + { + //获取access_token + $data = isset($params['code']) ? $this->getAccessToken($params['code']) : $params; + $access_token = isset($data['access_token']) ? $data['access_token'] : ''; + $refresh_token = isset($data['refresh_token']) ? $data['refresh_token'] : ''; + $expires_in = isset($data['expires_in']) ? $data['expires_in'] : 0; + if ($access_token) + { + $openid = isset($data['openid']) ? $data['openid'] : ''; + //获取用户信息 + $queryarr = [ + "access_token" => $access_token, + "openid" => $openid, + "lang" => 'zh_CN' + ]; + $ret = Http::post(self::GET_USERINFO_URL, $queryarr); + $userinfo = json_decode($ret, TRUE); + if (!$userinfo || isset($userinfo['errcode'])) + return []; + $userinfo = $userinfo ? $userinfo : []; + $userinfo['avatar'] = isset($userinfo['headimgurl']) ? $userinfo['headimgurl'] : ''; + $data = [ + 'access_token' => $access_token, + 'refresh_token' => $refresh_token, + 'expires_in' => $expires_in, + 'openid' => $openid, + 'userinfo' => $userinfo + ]; + return $data; + } + } + return []; + } + + /** + * 获取access_token + * @param string code + * @return array + */ + private function getAccessToken($code = '') + { + if (!$code) + return ''; + $queryarr = array( + "appid" => $this->config['app_id'], + "secret" => $this->config['app_secret'], + "code" => $code, + "grant_type" => "authorization_code", + ); + $response = Http::post(self::GET_ACCESS_TOKEN_URL, $queryarr); + $ret = json_decode($response, TRUE); + return $ret ? $ret : []; + } + +} diff --git a/extend/fast/third/Weibo.php b/extend/fast/third/Weibo.php new file mode 100644 index 0000000..fb1dbab --- /dev/null +++ b/extend/fast/third/Weibo.php @@ -0,0 +1,124 @@ +<?php + +namespace fast\third; + +use fast\Http; +use think\Config; +use think\Session; + +/** + * 微博 + */ +class Weibo +{ + + const GET_AUTH_CODE_URL = "https://api.weibo.com/oauth2/authorize"; + const GET_ACCESS_TOKEN_URL = "https://api.weibo.com/oauth2/access_token"; + const GET_USERINFO_URL = "https://api.weibo.com/2/users/show.json"; + + /** + * 配置信息 + * @var array + */ + private $config = []; + + public function __construct($options = []) + { + if ($config = Config::get('third.weibo')) + { + $this->config = array_merge($this->config, $config); + } + $this->config = array_merge($this->config, is_array($options) ? $options : []); + } + + /** + * 登陆 + */ + public function login() + { + header("Location:" . $this->getAuthorizeUrl()); + } + + /** + * 获取authorize_url + */ + public function getAuthorizeUrl() + { + $state = md5(uniqid(rand(), TRUE)); + Session::set('state', $state); + $queryarr = array( + "response_type" => "code", + "client_id" => $this->config['app_id'], + "redirect_uri" => $this->config['callback'], + "state" => $state, + ); + request()->isMobile() && $queryarr['display'] = 'mobile'; + $url = self::GET_AUTH_CODE_URL . '?' . http_build_query($queryarr); + return $url; + } + + /** + * 获取用户信息 + * @param array $params + * @return array + */ + public function getUserInfo($params = []) + { + $params = $params ? $params : $_GET; + if (isset($params['access_token']) || (isset($params['state']) && $params['state'] == Session::get('state') && isset($params['code']))) + { + //获取access_token + $data = isset($params['code']) ? $this->getAccessToken($params['code']) : $params; + $access_token = isset($data['access_token']) ? $data['access_token'] : ''; + $refresh_token = isset($data['refresh_token']) ? $data['refresh_token'] : ''; + $expires_in = isset($data['expires_in']) ? $data['expires_in'] : 0; + if ($access_token) + { + $uid = isset($data['uid']) ? $data['uid'] : ''; + //获取用户信息 + $queryarr = [ + "access_token" => $access_token, + "uid" => $uid, + ]; + $ret = Http::get(self::GET_USERINFO_URL, $queryarr); + $userinfo = json_decode($ret, TRUE); + if (!$userinfo || isset($userinfo['error_code'])) + return []; + $userinfo = $userinfo ? $userinfo : []; + $userinfo['nickname'] = isset($userinfo['screen_name']) ? $userinfo['screen_name'] : ''; + $userinfo['avatar'] = isset($userinfo['profile_image_url']) ? $userinfo['profile_image_url'] : ''; + $data = [ + 'access_token' => $access_token, + 'refresh_token' => $refresh_token, + 'expires_in' => $expires_in, + 'openid' => $uid, + 'userinfo' => $userinfo + ]; + return $data; + } + } + return []; + } + + /** + * 获取access_token + * @param string code + * @return array + */ + private function getAccessToken($code = '') + { + if (!$code) + return ''; + $queryarr = array( + "grant_type" => "authorization_code", + "client_id" => $this->config['app_id'], + "client_secret" => $this->config['app_secret'], + "redirect_uri" => $this->config['callback'], + "code" => $code, + ); + $response = Http::post(self::GET_ACCESS_TOKEN_URL, $queryarr); + $ret = json_decode($response, TRUE); + return $ret ? $ret : []; + } + +} diff --git a/extend/fast/ucenter/client/Client.php b/extend/fast/ucenter/client/Client.php new file mode 100644 index 0000000..58ed17b --- /dev/null +++ b/extend/fast/ucenter/client/Client.php @@ -0,0 +1,31 @@ +<?php + +namespace fast\ucenter\client; + +use Exception; +use think\Loader; + +class Client +{ + + public function __construct() + { + $this->initConfig(); + Loader::import('client', dirname(__FILE__) . "/uc_client/"); //加载uc客户端主脚本 + } + + //加载配置 + public function initConfig() + { + if (!defined('UC_API')) + { + new Exception('未发现uc常量配置信息'); + } + } + + function __call($method, $params) + { + return call_user_func_array($method, $params); + } + +} diff --git a/extend/fast/ucenter/client/uc_client/client.php b/extend/fast/ucenter/client/uc_client/client.php new file mode 100644 index 0000000..67f361f --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/client.php @@ -0,0 +1,840 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: client.php 1179 2014-11-03 07:11:25Z hypowang $ + */ + +if (!defined('UC_API')) +{ + exit('Access denied'); +} + +error_reporting(0); + +define('IN_UC', TRUE); +define('UC_CLIENT_VERSION', '1.6.0'); +define('UC_CLIENT_RELEASE', '20141101'); +define('UC_ROOT', substr(__FILE__, 0, -10)); +define('UC_DATADIR', UC_ROOT . './data/'); +define('UC_DATAURL', UC_API . '/data'); +define('UC_API_FUNC', UC_CONNECT == 'mysql' ? 'uc_api_mysql' : 'uc_api_post'); +$GLOBALS['uc_controls'] = array(); + +function uc_addslashes($string, $force = 0, $strip = FALSE) +{ + !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc()); + if (!MAGIC_QUOTES_GPC || $force) + { + if (is_array($string)) + { + foreach ($string as $key => $val) + { + $string[$key] = uc_addslashes($val, $force, $strip); + } + } + else + { + $string = addslashes($strip ? stripslashes($string) : $string); + } + } + return $string; +} + +if (!function_exists('daddslashes')) +{ + + function daddslashes($string, $force = 0) + { + return uc_addslashes($string, $force); + } + +} + +if (!function_exists('dhtmlspecialchars')) +{ + + function dhtmlspecialchars($string, $flags = null) + { + if (is_array($string)) + { + foreach ($string as $key => $val) + { + $string[$key] = dhtmlspecialchars($val, $flags); + } + } + else + { + if ($flags === null) + { + $string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string); + if (strpos($string, '&#') !== false) + { + $string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string); + } + } + else + { + if (PHP_VERSION < '5.4.0') + { + $string = htmlspecialchars($string, $flags); + } + else + { + if (strtolower(CHARSET) == 'utf-8') + { + $charset = 'UTF-8'; + } + else + { + $charset = 'ISO-8859-1'; + } + $string = htmlspecialchars($string, $flags, $charset); + } + } + } + return $string; + } + +} + +if (!function_exists('fsocketopen')) +{ + + function fsocketopen($hostname, $port = 80, &$errno, &$errstr, $timeout = 15) + { + $fp = ''; + if (function_exists('fsockopen')) + { + $fp = @fsockopen($hostname, $port, $errno, $errstr, $timeout); + } + elseif (function_exists('pfsockopen')) + { + $fp = @pfsockopen($hostname, $port, $errno, $errstr, $timeout); + } + elseif (function_exists('stream_socket_client')) + { + $fp = @stream_socket_client($hostname . ':' . $port, $errno, $errstr, $timeout); + } + return $fp; + } + +} + +function uc_stripslashes($string) +{ + !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc()); + if (MAGIC_QUOTES_GPC) + { + return stripslashes($string); + } + else + { + return $string; + } +} + +// 采用POST请求形式 +function uc_api_post($module, $action, $arg = array()) +{ + $s = $sep = ''; + foreach ($arg as $k => $v) + { + $k = urlencode($k); + if (is_array($v)) + { + $s2 = $sep2 = ''; + foreach ($v as $k2 => $v2) + { + $k2 = urlencode($k2); + $s2 .= "$sep2{$k}[$k2]=" . urlencode(uc_stripslashes($v2)); + $sep2 = '&'; + } + $s .= $sep . $s2; + } + else + { + $s .= "$sep$k=" . urlencode(uc_stripslashes($v)); + } + $sep = '&'; + } + $postdata = uc_api_requestdata($module, $action, $s); + return uc_fopen2(UC_API . '/index.php', 500000, $postdata, '', TRUE, UC_IP, 20); +} + +function uc_api_requestdata($module, $action, $arg = '', $extra = '') +{ + $input = uc_api_input($arg); + $post = "m=$module&a=$action&inajax=2&release=" . UC_CLIENT_RELEASE . "&input=$input&appid=" . UC_APPID . $extra; + return $post; +} + +function uc_api_url($module, $action, $arg = '', $extra = '') +{ + $url = UC_API . '/index.php?' . uc_api_requestdata($module, $action, $arg, $extra); + return $url; +} + +function uc_api_input($data) +{ + $s = urlencode(uc_authcode($data . '&agent=' . md5($_SERVER['HTTP_USER_AGENT']) . "&time=" . time(), 'ENCODE', UC_KEY)); + return $s; +} + +// 直连数据库的形式 +function uc_api_mysql($model, $action, $args = array()) +{ + global $uc_controls; + if (empty($uc_controls[$model])) + { + // 优先使用mysqli + if (function_exists("mysqli_connect")) + { + include_once UC_ROOT . './lib/dbi.class.php'; + } + else + { + include_once UC_ROOT . './lib/db.class.php'; + } + include_once UC_ROOT . './model/base.php'; + include_once UC_ROOT . "./control/$model.php"; + $classname = $model . 'control'; + $uc_controls[$model] = new $classname(); + } + if ($action{0} != '_') + { + $args = uc_addslashes($args, 1, TRUE); + $action = 'on' . $action; + $uc_controls[$model]->input = $args; + return $uc_controls[$model]->$action($args); + } + else + { + return ''; + } +} + +function uc_serialize($arr, $htmlon = 0) +{ + include_once UC_ROOT . './lib/xml.class.php'; + return xml_serialize($arr, $htmlon); +} + +function uc_unserialize($s) +{ + include_once UC_ROOT . './lib/xml.class.php'; + return @xml_unserialize($s); +} + +function uc_authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) +{ + + $ckey_length = 4; + + $key = md5($key ? $key : UC_KEY); + $keya = md5(substr($key, 0, 16)); + $keyb = md5(substr($key, 16, 16)); + $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : ''; + + $cryptkey = $keya . md5($keya . $keyc); + $key_length = strlen($cryptkey); + + $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string; + $string_length = strlen($string); + + $result = ''; + $box = range(0, 255); + + $rndkey = array(); + for ($i = 0; $i <= 255; $i++) + { + $rndkey[$i] = ord($cryptkey[$i % $key_length]); + } + + for ($j = $i = 0; $i < 256; $i++) + { + $j = ($j + $box[$i] + $rndkey[$i]) % 256; + $tmp = $box[$i]; + $box[$i] = $box[$j]; + $box[$j] = $tmp; + } + + for ($a = $j = $i = 0; $i < $string_length; $i++) + { + $a = ($a + 1) % 256; + $j = ($j + $box[$a]) % 256; + $tmp = $box[$a]; + $box[$a] = $box[$j]; + $box[$j] = $tmp; + $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); + } + + if ($operation == 'DECODE') + { + if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) + { + return substr($result, 26); + } + else + { + return ''; + } + } + else + { + return $keyc . str_replace('=', '', base64_encode($result)); + } +} + +function uc_fopen2($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) +{ + $__times__ = isset($_GET['__times__']) ? intval($_GET['__times__']) + 1 : 1; + if ($__times__ > 2) + { + return ''; + } + $url .= (strpos($url, '?') === FALSE ? '?' : '&') . "__times__=$__times__"; + return uc_fopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block); +} + +function uc_fopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) +{ + $return = ''; + $matches = parse_url($url); + !isset($matches['scheme']) && $matches['scheme'] = ''; + !isset($matches['host']) && $matches['host'] = ''; + !isset($matches['path']) && $matches['path'] = ''; + !isset($matches['query']) && $matches['query'] = ''; + !isset($matches['port']) && $matches['port'] = ''; + $scheme = $matches['scheme']; + $host = $matches['host']; + $path = $matches['path'] ? $matches['path'] . ($matches['query'] ? '?' . $matches['query'] : '') : '/'; + $port = !empty($matches['port']) ? $matches['port'] : 80; + if ($post) + { + $out = "POST $path HTTP/1.0\r\n"; + $header = "Accept: */*\r\n"; + $header .= "Accept-Language: zh-cn\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "User-Agent: {$_SERVER['HTTP_USER_AGENT']}\r\n"; + $header .= "Host: $host\r\n"; + $header .= 'Content-Length: ' . strlen($post) . "\r\n"; + $header .= "Connection: Close\r\n"; + $header .= "Cache-Control: no-cache\r\n"; + $header .= "Cookie: $cookie\r\n\r\n"; + $out .= $header . $post; + } + else + { + $out = "GET $path HTTP/1.0\r\n"; + $header = "Accept: */*\r\n"; + $header .= "Accept-Language: zh-cn\r\n"; + $header .= "User-Agent: {$_SERVER['HTTP_USER_AGENT']}\r\n"; + $header .= "Host: $host\r\n"; + $header .= "Connection: Close\r\n"; + $header .= "Cookie: $cookie\r\n\r\n"; + $out .= $header; + } + $fpflag = 0; + if (!$fp = @fsocketopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout)) + { + $context = array( + 'http' => array( + 'method' => $post ? 'POST' : 'GET', + 'header' => $header, + 'content' => $post, + 'timeout' => $timeout, + ), + ); + $context = stream_context_create($context); + $fp = @fopen($scheme . '://' . ($ip ? $ip : $host) . ':' . $port . $path, 'b', false, $context); + $fpflag = 1; + } + if (!$fp) + { + return ''; + } + else + { + stream_set_blocking($fp, $block); + stream_set_timeout($fp, $timeout); + @fwrite($fp, $out); + $status = stream_get_meta_data($fp); + if (!$status['timed_out']) + { + while (!feof($fp) && !$fpflag) + { + if (($header = @fgets($fp)) && ($header == "\r\n" || $header == "\n")) + { + break; + } + } + + $stop = false; + while (!feof($fp) && !$stop) + { + $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit)); + $return .= $data; + if ($limit) + { + $limit -= strlen($data); + $stop = $limit <= 0; + } + } + } + @fclose($fp); + return $return; + } +} + +function uc_app_ls() +{ + $return = call_user_func(UC_API_FUNC, 'app', 'ls', array()); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_feed_add($icon, $uid, $username, $title_template = '', $title_data = '', $body_template = '', $body_data = '', $body_general = '', $target_ids = '', $images = array()) +{ + return call_user_func(UC_API_FUNC, 'feed', 'add', array( + 'icon' => $icon, + 'appid' => UC_APPID, + 'uid' => $uid, + 'username' => $username, + 'title_template' => $title_template, + 'title_data' => $title_data, + 'body_template' => $body_template, + 'body_data' => $body_data, + 'body_general' => $body_general, + 'target_ids' => $target_ids, + 'image_1' => $images[0]['url'], + 'image_1_link' => $images[0]['link'], + 'image_2' => $images[1]['url'], + 'image_2_link' => $images[1]['link'], + 'image_3' => $images[2]['url'], + 'image_3_link' => $images[2]['link'], + 'image_4' => $images[3]['url'], + 'image_4_link' => $images[3]['link'] + ) + ); +} + +function uc_feed_get($limit = 100, $delete = TRUE) +{ + $return = call_user_func(UC_API_FUNC, 'feed', 'get', array('limit' => $limit, 'delete' => $delete)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_friend_add($uid, $friendid, $comment = '') +{ + return call_user_func(UC_API_FUNC, 'friend', 'add', array('uid' => $uid, 'friendid' => $friendid, 'comment' => $comment)); +} + +function uc_friend_delete($uid, $friendids) +{ + return call_user_func(UC_API_FUNC, 'friend', 'delete', array('uid' => $uid, 'friendids' => $friendids)); +} + +function uc_friend_totalnum($uid, $direction = 0) +{ + return call_user_func(UC_API_FUNC, 'friend', 'totalnum', array('uid' => $uid, 'direction' => $direction)); +} + +function uc_friend_ls($uid, $page = 1, $pagesize = 10, $totalnum = 10, $direction = 0) +{ + $return = call_user_func(UC_API_FUNC, 'friend', 'ls', array('uid' => $uid, 'page' => $page, 'pagesize' => $pagesize, 'totalnum' => $totalnum, 'direction' => $direction)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_user_register($username, $password, $email = '', $mobile = '', $extend = []) +{ + return call_user_func(UC_API_FUNC, 'user', 'register', array('username' => $username, 'password' => $password, 'email' => $email, 'mobile' => $mobile, 'extend' => $extend)); +} + +function uc_user_login($username, $password, $isuid = 0, $extend = []) +{ + $isuid = intval($isuid); + $return = call_user_func(UC_API_FUNC, 'user', 'login', array('username' => $username, 'password' => $password, 'isuid' => $isuid, 'extend' => $extend)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +/** + * 同步注册 + * @param int $uid + * @param string $password + * @return string + */ +function uc_user_synregister($uid, $password) +{ + $uid = intval($uid); + if (@include UC_ROOT . './data/cache/apps.php') + { + if (count($_CACHE['apps']) > 1) + { + $return = uc_api_post('user', 'synregister', array('uid' => $uid, 'password' => $password)); + } + else + { + $return = ''; + } + } + return $return; +} + +/** + * 同步登录 + * @param int $uid + * @return string + */ +function uc_user_synlogin($uid) +{ + $uid = intval($uid); + if (@include UC_ROOT . './data/cache/apps.php') + { + if (count($_CACHE['apps']) > 1) + { + $return = uc_api_post('user', 'synlogin', array('uid' => $uid)); + } + else + { + $return = ''; + } + } + return $return; +} + +/** + * 同步退出 + * @return string + */ +function uc_user_synlogout() +{ + if (@include UC_ROOT . './data/cache/apps.php') + { + if (count($_CACHE['apps']) > 1) + { + $return = uc_api_post('user', 'synlogout', array()); + } + else + { + $return = ''; + } + } + return $return; +} + +/** + * 修改用户信息 + * @param int $uid 会员ID + * @param string $username 用户名 + * @param string $password 密码 + * @param string $email 邮箱 + * @param string $mobile 手机号 + * @param array $extend 扩展信息 + * @return type + */ +function uc_user_edit($uid, $username, $password, $email = '', $mobile = '', $extend = []) +{ + return call_user_func(UC_API_FUNC, 'user', 'edit', array('uid' => $uid, 'username' => $username, 'password' => $password, 'email' => $email, 'mobile' => $mobile, 'extend' => $extend)); +} + +function uc_user_delete($uid) +{ + return call_user_func(UC_API_FUNC, 'user', 'delete', array('uid' => $uid)); +} + +function uc_user_deleteavatar($uid) +{ + uc_api_post('user', 'deleteavatar', array('uid' => $uid)); +} + +function uc_user_checkname($username) +{ + return call_user_func(UC_API_FUNC, 'user', 'check_username', array('username' => $username)); +} + +function uc_user_checkemail($email) +{ + return call_user_func(UC_API_FUNC, 'user', 'check_email', array('email' => $email)); +} + +function uc_user_checkmobile($mobile) +{ + return call_user_func(UC_API_FUNC, 'user', 'check_mobile', array('mobile' => $mobile)); +} + +function uc_user_addprotected($username, $admin = '') +{ + return call_user_func(UC_API_FUNC, 'user', 'addprotected', array('username' => $username, 'admin' => $admin)); +} + +function uc_user_deleteprotected($username) +{ + return call_user_func(UC_API_FUNC, 'user', 'deleteprotected', array('username' => $username)); +} + +function uc_user_getprotected() +{ + $return = call_user_func(UC_API_FUNC, 'user', 'getprotected', array('1' => 1)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_get_user($username, $isuid = 0) +{ + $return = call_user_func(UC_API_FUNC, 'user', 'get_user', array('username' => $username, 'isuid' => $isuid)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_user_merge($oldusername, $newusername, $uid, $password, $email) +{ + return call_user_func(UC_API_FUNC, 'user', 'merge', array('oldusername' => $oldusername, 'newusername' => $newusername, 'uid' => $uid, 'password' => $password, 'email' => $email)); +} + +function uc_user_merge_remove($username) +{ + return call_user_func(UC_API_FUNC, 'user', 'merge_remove', array('username' => $username)); +} + +function uc_user_getcredit($appid, $uid, $credit) +{ + return uc_api_post('user', 'getcredit', array('appid' => $appid, 'uid' => $uid, 'credit' => $credit)); +} + +function uc_user_logincheck($username, $ip) +{ + return call_user_func(UC_API_FUNC, 'user', 'logincheck', array('username' => $username, 'ip' => $ip)); +} + +function uc_pm_location($uid, $newpm = 0) +{ + $apiurl = uc_api_url('pm_client', 'ls', "uid=$uid", ($newpm ? '&folder=newbox' : '')); + @header("Expires: 0"); + @header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE); + @header("Pragma: no-cache"); + @header("location: $apiurl"); +} + +function uc_pm_checknew($uid, $more = 0) +{ + $return = call_user_func(UC_API_FUNC, 'pm', 'check_newpm', array('uid' => $uid, 'more' => $more)); + return (!$more || UC_CONNECT == 'mysql') ? $return : uc_unserialize($return); +} + +function uc_pm_send($fromuid, $msgto, $subject, $message, $instantly = 1, $replypmid = 0, $isusername = 0, $type = 0) +{ + if ($instantly) + { + $replypmid = @is_numeric($replypmid) ? $replypmid : 0; + return call_user_func(UC_API_FUNC, 'pm', 'sendpm', array('fromuid' => $fromuid, 'msgto' => $msgto, 'subject' => $subject, 'message' => $message, 'replypmid' => $replypmid, 'isusername' => $isusername, 'type' => $type)); + } + else + { + $fromuid = intval($fromuid); + $subject = rawurlencode($subject); + $msgto = rawurlencode($msgto); + $message = rawurlencode($message); + $replypmid = @is_numeric($replypmid) ? $replypmid : 0; + $replyadd = $replypmid ? "&pmid=$replypmid&do=reply" : ''; + $apiurl = uc_api_url('pm_client', 'send', "uid=$fromuid", "&msgto=$msgto&subject=$subject&message=$message$replyadd"); + @header("Expires: 0"); + @header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE); + @header("Pragma: no-cache"); + @header("location: " . $apiurl); + } +} + +function uc_pm_delete($uid, $folder, $pmids) +{ + return call_user_func(UC_API_FUNC, 'pm', 'delete', array('uid' => $uid, 'pmids' => $pmids)); +} + +function uc_pm_deleteuser($uid, $touids) +{ + return call_user_func(UC_API_FUNC, 'pm', 'deleteuser', array('uid' => $uid, 'touids' => $touids)); +} + +function uc_pm_deletechat($uid, $plids, $type = 0) +{ + return call_user_func(UC_API_FUNC, 'pm', 'deletechat', array('uid' => $uid, 'plids' => $plids, 'type' => $type)); +} + +function uc_pm_readstatus($uid, $uids, $plids = array(), $status = 0) +{ + return call_user_func(UC_API_FUNC, 'pm', 'readstatus', array('uid' => $uid, 'uids' => $uids, 'plids' => $plids, 'status' => $status)); +} + +function uc_pm_list($uid, $page = 1, $pagesize = 10, $folder = 'inbox', $filter = 'newpm', $msglen = 0) +{ + $uid = intval($uid); + $page = intval($page); + $pagesize = intval($pagesize); + $return = call_user_func(UC_API_FUNC, 'pm', 'ls', array('uid' => $uid, 'page' => $page, 'pagesize' => $pagesize, 'filter' => $filter, 'msglen' => $msglen)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_pm_ignore($uid) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'ignore', array('uid' => $uid)); +} + +function uc_pm_view($uid, $pmid = 0, $touid = 0, $daterange = 1, $page = 0, $pagesize = 10, $type = 0, $isplid = 0) +{ + $uid = intval($uid); + $touid = intval($touid); + $page = intval($page); + $pagesize = intval($pagesize); + $pmid = @is_numeric($pmid) ? $pmid : 0; + $return = call_user_func(UC_API_FUNC, 'pm', 'view', array('uid' => $uid, 'pmid' => $pmid, 'touid' => $touid, 'daterange' => $daterange, 'page' => $page, 'pagesize' => $pagesize, 'type' => $type, 'isplid' => $isplid)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_pm_view_num($uid, $touid, $isplid) +{ + $uid = intval($uid); + $touid = intval($touid); + $isplid = intval($isplid); + return call_user_func(UC_API_FUNC, 'pm', 'viewnum', array('uid' => $uid, 'touid' => $touid, 'isplid' => $isplid)); +} + +function uc_pm_viewnode($uid, $type, $pmid) +{ + $uid = intval($uid); + $type = intval($type); + $pmid = @is_numeric($pmid) ? $pmid : 0; + $return = call_user_func(UC_API_FUNC, 'pm', 'viewnode', array('uid' => $uid, 'type' => $type, 'pmid' => $pmid)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_pm_chatpmmemberlist($uid, $plid = 0) +{ + $uid = intval($uid); + $plid = intval($plid); + $return = call_user_func(UC_API_FUNC, 'pm', 'chatpmmemberlist', array('uid' => $uid, 'plid' => $plid)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_pm_kickchatpm($plid, $uid, $touid) +{ + $uid = intval($uid); + $plid = intval($plid); + $touid = intval($touid); + return call_user_func(UC_API_FUNC, 'pm', 'kickchatpm', array('uid' => $uid, 'plid' => $plid, 'touid' => $touid)); +} + +function uc_pm_appendchatpm($plid, $uid, $touid) +{ + $uid = intval($uid); + $plid = intval($plid); + $touid = intval($touid); + return call_user_func(UC_API_FUNC, 'pm', 'appendchatpm', array('uid' => $uid, 'plid' => $plid, 'touid' => $touid)); +} + +function uc_pm_blackls_get($uid) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'blackls_get', array('uid' => $uid)); +} + +function uc_pm_blackls_set($uid, $blackls) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'blackls_set', array('uid' => $uid, 'blackls' => $blackls)); +} + +function uc_pm_blackls_add($uid, $username) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'blackls_add', array('uid' => $uid, 'username' => $username)); +} + +function uc_pm_blackls_delete($uid, $username) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'blackls_delete', array('uid' => $uid, 'username' => $username)); +} + +function uc_domain_ls() +{ + $return = call_user_func(UC_API_FUNC, 'domain', 'ls', array('1' => 1)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_credit_exchange_request($uid, $from, $to, $toappid, $amount) +{ + $uid = intval($uid); + $from = intval($from); + $toappid = intval($toappid); + $to = intval($to); + $amount = intval($amount); + return uc_api_post('credit', 'request', array('uid' => $uid, 'from' => $from, 'to' => $to, 'toappid' => $toappid, 'amount' => $amount)); +} + +function uc_tag_get($tagname, $nums = 0) +{ + $return = call_user_func(UC_API_FUNC, 'tag', 'gettag', array('tagname' => $tagname, 'nums' => $nums)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_avatar($uid, $type = 'virtual', $returnhtml = 1) +{ + $uid = intval($uid); + $uc_input = uc_api_input("uid=$uid"); + $uc_avatarflash = UC_API . '/images/camera.swf?inajax=1&appid=' . UC_APPID . '&input=' . $uc_input . '&agent=' . md5($_SERVER['HTTP_USER_AGENT']) . '&ucapi=' . urlencode(str_replace('http://', '', UC_API)) . '&avatartype=' . $type . '&uploadSize=2048'; + if ($returnhtml) + { + return '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="450" height="253" id="mycamera" align="middle"> + <param name="allowScriptAccess" value="always" /> + <param name="scale" value="exactfit" /> + <param name="wmode" value="transparent" /> + <param name="quality" value="high" /> + <param name="bgcolor" value="#ffffff" /> + <param name="movie" value="' . $uc_avatarflash . '" /> + <param name="menu" value="false" /> + <embed src="' . $uc_avatarflash . '" quality="high" bgcolor="#ffffff" width="450" height="253" name="mycamera" align="middle" allowScriptAccess="always" allowFullScreen="false" scale="exactfit" wmode="transparent" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> + </object>'; + } + else + { + return array( + 'width', '450', + 'height', '253', + 'scale', 'exactfit', + 'src', $uc_avatarflash, + 'id', 'mycamera', + 'name', 'mycamera', + 'quality', 'high', + 'bgcolor', '#ffffff', + 'menu', 'false', + 'swLiveConnect', 'true', + 'allowScriptAccess', 'always' + ); + } +} + +function uc_mail_queue($uids, $emails, $subject, $message, $frommail = '', $charset = 'gbk', $htmlon = FALSE, $level = 1) +{ + return call_user_func(UC_API_FUNC, 'mail', 'add', array('uids' => $uids, 'emails' => $emails, 'subject' => $subject, 'message' => $message, 'frommail' => $frommail, 'charset' => $charset, 'htmlon' => $htmlon, 'level' => $level)); +} + +function uc_check_avatar($uid, $size = 'middle', $type = 'virtual') +{ + $url = UC_API . "/avatar.php?uid=$uid&size=$size&type=$type&check_file_exists=1"; + $res = uc_fopen2($url, 500000, '', '', TRUE, UC_IP, 20); + if ($res == 1) + { + return 1; + } + else + { + return 0; + } +} + +function uc_check_version() +{ + $return = uc_api_post('version', 'check', array()); + $data = uc_unserialize($return); + return is_array($data) ? $data : $return; +} diff --git a/extend/fast/ucenter/client/uc_client/control/app.php b/extend/fast/ucenter/client/uc_client/control/app.php new file mode 100644 index 0000000..dc66f54 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/app.php @@ -0,0 +1,63 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: app.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class appcontrol extends base +{ + + function __construct() + { + $this->appcontrol(); + } + + function appcontrol() + { + parent::__construct(); + $this->load('app'); + } + + function onls() + { + $this->init_input(); + $applist = $_ENV['app']->get_apps('appid, type, name, url, tagtemplates, viewprourl, synlogin'); + $applist2 = array(); + foreach ($applist as $key => $app) + { + $app['tagtemplates'] = $this->unserialize($app['tagtemplates']); + $applist2[$app['appid']] = $app; + } + return $applist2; + } + + function onadd() + { + + } + + function onucinfo() + { + + } + + function _random($length, $numeric = 0) + { + + } + + function _generate_key() + { + + } + + function _format_notedata($notedata) + { + + } + +} diff --git a/extend/fast/ucenter/client/uc_client/control/cache.php b/extend/fast/ucenter/client/uc_client/control/cache.php new file mode 100644 index 0000000..e8a621c --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/cache.php @@ -0,0 +1,30 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: cache.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class cachecontrol extends base +{ + + function __construct() + { + $this->cachecontrol(); + } + + function cachecontrol() + { + parent::__construct(); + } + + function onupdate($arr) + { + $this->load("cache"); + $_ENV['cache']->updatedata(); + } + +} diff --git a/extend/fast/ucenter/client/uc_client/control/client.php b/extend/fast/ucenter/client/uc_client/control/client.php new file mode 100644 index 0000000..9536bca --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/client.php @@ -0,0 +1,817 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: client.php 1179 2014-11-03 07:11:25Z hypowang $ + */ + +if (!defined('UC_API')) +{ + exit('Access denied'); +} + +error_reporting(0); + +define('IN_UC', TRUE); +define('UC_CLIENT_VERSION', '1.6.0'); +define('UC_CLIENT_RELEASE', '20141101'); +define('UC_ROOT', substr(__FILE__, 0, -10)); +define('UC_DATADIR', UC_ROOT . './data/'); +define('UC_DATAURL', UC_API . '/data'); +define('UC_API_FUNC', UC_CONNECT == 'mysql' ? 'uc_api_mysql' : 'uc_api_post'); +$GLOBALS['uc_controls'] = array(); + +function uc_addslashes($string, $force = 0, $strip = FALSE) +{ + !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc()); + if (!MAGIC_QUOTES_GPC || $force) + { + if (is_array($string)) + { + foreach ($string as $key => $val) + { + $string[$key] = uc_addslashes($val, $force, $strip); + } + } + else + { + $string = addslashes($strip ? stripslashes($string) : $string); + } + } + return $string; +} + +if (!function_exists('daddslashes')) +{ + + function daddslashes($string, $force = 0) + { + return uc_addslashes($string, $force); + } + +} + +if (!function_exists('dhtmlspecialchars')) +{ + + function dhtmlspecialchars($string, $flags = null) + { + if (is_array($string)) + { + foreach ($string as $key => $val) + { + $string[$key] = dhtmlspecialchars($val, $flags); + } + } + else + { + if ($flags === null) + { + $string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string); + if (strpos($string, '&#') !== false) + { + $string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string); + } + } + else + { + if (PHP_VERSION < '5.4.0') + { + $string = htmlspecialchars($string, $flags); + } + else + { + if (strtolower(CHARSET) == 'utf-8') + { + $charset = 'UTF-8'; + } + else + { + $charset = 'ISO-8859-1'; + } + $string = htmlspecialchars($string, $flags, $charset); + } + } + } + return $string; + } + +} + +if (!function_exists('fsocketopen')) +{ + + function fsocketopen($hostname, $port = 80, &$errno, &$errstr, $timeout = 15) + { + $fp = ''; + if (function_exists('fsockopen')) + { + $fp = @fsockopen($hostname, $port, $errno, $errstr, $timeout); + } + elseif (function_exists('pfsockopen')) + { + $fp = @pfsockopen($hostname, $port, $errno, $errstr, $timeout); + } + elseif (function_exists('stream_socket_client')) + { + $fp = @stream_socket_client($hostname . ':' . $port, $errno, $errstr, $timeout); + } + return $fp; + } + +} + +function uc_stripslashes($string) +{ + !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc()); + if (MAGIC_QUOTES_GPC) + { + return stripslashes($string); + } + else + { + return $string; + } +} + +// 采用POST请求形式 +function uc_api_post($module, $action, $arg = array()) +{ + $s = $sep = ''; + foreach ($arg as $k => $v) + { + $k = urlencode($k); + if (is_array($v)) + { + $s2 = $sep2 = ''; + foreach ($v as $k2 => $v2) + { + $k2 = urlencode($k2); + $s2 .= "$sep2{$k}[$k2]=" . urlencode(uc_stripslashes($v2)); + $sep2 = '&'; + } + $s .= $sep . $s2; + } + else + { + $s .= "$sep$k=" . urlencode(uc_stripslashes($v)); + } + $sep = '&'; + } + $postdata = uc_api_requestdata($module, $action, $s); + return uc_fopen2(UC_API . '/index.php', 500000, $postdata, '', TRUE, UC_IP, 20); +} + +function uc_api_requestdata($module, $action, $arg = '', $extra = '') +{ + $input = uc_api_input($arg); + $post = "m=$module&a=$action&inajax=2&release=" . UC_CLIENT_RELEASE . "&input=$input&appid=" . UC_APPID . $extra; + return $post; +} + +function uc_api_url($module, $action, $arg = '', $extra = '') +{ + $url = UC_API . '/index.php?' . uc_api_requestdata($module, $action, $arg, $extra); + return $url; +} + +function uc_api_input($data) +{ + $s = urlencode(uc_authcode($data . '&agent=' . md5($_SERVER['HTTP_USER_AGENT']) . "&time=" . time(), 'ENCODE', UC_KEY)); + return $s; +} + +// 直连数据库的形式 +function uc_api_mysql($model, $action, $args = array()) +{ + global $uc_controls; + if (empty($uc_controls[$model])) + { + // 优先使用mysqli + if (function_exists("mysqli_connect")) + { + include_once UC_ROOT . './lib/dbi.class.php'; + } + else + { + include_once UC_ROOT . './lib/db.class.php'; + } + include_once UC_ROOT . './model/base.php'; + include_once UC_ROOT . "./control/$model.php"; + $classname = $model . 'control'; + $uc_controls[$model] = new $classname(); + } + if ($action{0} != '_') + { + $args = uc_addslashes($args, 1, TRUE); + $action = 'on' . $action; + $uc_controls[$model]->input = $args; + return $uc_controls[$model]->$action($args); + } + else + { + return ''; + } +} + +function uc_serialize($arr, $htmlon = 0) +{ + include_once UC_ROOT . './lib/xml.class.php'; + return xml_serialize($arr, $htmlon); +} + +function uc_unserialize($s) +{ + include_once UC_ROOT . './lib/xml.class.php'; + return @xml_unserialize($s); +} + +function uc_authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) +{ + + $ckey_length = 4; + + $key = md5($key ? $key : UC_KEY); + $keya = md5(substr($key, 0, 16)); + $keyb = md5(substr($key, 16, 16)); + $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : ''; + + $cryptkey = $keya . md5($keya . $keyc); + $key_length = strlen($cryptkey); + + $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string; + $string_length = strlen($string); + + $result = ''; + $box = range(0, 255); + + $rndkey = array(); + for ($i = 0; $i <= 255; $i++) + { + $rndkey[$i] = ord($cryptkey[$i % $key_length]); + } + + for ($j = $i = 0; $i < 256; $i++) + { + $j = ($j + $box[$i] + $rndkey[$i]) % 256; + $tmp = $box[$i]; + $box[$i] = $box[$j]; + $box[$j] = $tmp; + } + + for ($a = $j = $i = 0; $i < $string_length; $i++) + { + $a = ($a + 1) % 256; + $j = ($j + $box[$a]) % 256; + $tmp = $box[$a]; + $box[$a] = $box[$j]; + $box[$j] = $tmp; + $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); + } + + if ($operation == 'DECODE') + { + if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) + { + return substr($result, 26); + } + else + { + return ''; + } + } + else + { + return $keyc . str_replace('=', '', base64_encode($result)); + } +} + +function uc_fopen2($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) +{ + $__times__ = isset($_GET['__times__']) ? intval($_GET['__times__']) + 1 : 1; + if ($__times__ > 2) + { + return ''; + } + $url .= (strpos($url, '?') === FALSE ? '?' : '&') . "__times__=$__times__"; + return uc_fopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block); +} + +function uc_fopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) +{ + $return = ''; + $matches = parse_url($url); + !isset($matches['scheme']) && $matches['scheme'] = ''; + !isset($matches['host']) && $matches['host'] = ''; + !isset($matches['path']) && $matches['path'] = ''; + !isset($matches['query']) && $matches['query'] = ''; + !isset($matches['port']) && $matches['port'] = ''; + $scheme = $matches['scheme']; + $host = $matches['host']; + $path = $matches['path'] ? $matches['path'] . ($matches['query'] ? '?' . $matches['query'] : '') : '/'; + $port = !empty($matches['port']) ? $matches['port'] : 80; + if ($post) + { + $out = "POST $path HTTP/1.0\r\n"; + $header = "Accept: */*\r\n"; + $header .= "Accept-Language: zh-cn\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n"; + $header .= "Host: $host\r\n"; + $header .= 'Content-Length: ' . strlen($post) . "\r\n"; + $header .= "Connection: Close\r\n"; + $header .= "Cache-Control: no-cache\r\n"; + $header .= "Cookie: $cookie\r\n\r\n"; + $out .= $header . $post; + } + else + { + $out = "GET $path HTTP/1.0\r\n"; + $header = "Accept: */*\r\n"; + $header .= "Accept-Language: zh-cn\r\n"; + $header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n"; + $header .= "Host: $host\r\n"; + $header .= "Connection: Close\r\n"; + $header .= "Cookie: $cookie\r\n\r\n"; + $out .= $header; + } + + $fpflag = 0; + if (!$fp = @fsocketopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout)) + { + $context = array( + 'http' => array( + 'method' => $post ? 'POST' : 'GET', + 'header' => $header, + 'content' => $post, + 'timeout' => $timeout, + ), + ); + $context = stream_context_create($context); + $fp = @fopen($scheme . '://' . ($ip ? $ip : $host) . ':' . $port . $path, 'b', false, $context); + $fpflag = 1; + } + + if (!$fp) + { + return ''; + } + else + { + stream_set_blocking($fp, $block); + stream_set_timeout($fp, $timeout); + @fwrite($fp, $out); + $status = stream_get_meta_data($fp); + if (!$status['timed_out']) + { + while (!feof($fp) && !$fpflag) + { + if (($header = @fgets($fp)) && ($header == "\r\n" || $header == "\n")) + { + break; + } + } + + $stop = false; + while (!feof($fp) && !$stop) + { + $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit)); + $return .= $data; + if ($limit) + { + $limit -= strlen($data); + $stop = $limit <= 0; + } + } + } + @fclose($fp); + return $return; + } +} + +function uc_app_ls() +{ + $return = call_user_func(UC_API_FUNC, 'app', 'ls', array()); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_feed_add($icon, $uid, $username, $title_template = '', $title_data = '', $body_template = '', $body_data = '', $body_general = '', $target_ids = '', $images = array()) +{ + return call_user_func(UC_API_FUNC, 'feed', 'add', array( + 'icon' => $icon, + 'appid' => UC_APPID, + 'uid' => $uid, + 'username' => $username, + 'title_template' => $title_template, + 'title_data' => $title_data, + 'body_template' => $body_template, + 'body_data' => $body_data, + 'body_general' => $body_general, + 'target_ids' => $target_ids, + 'image_1' => $images[0]['url'], + 'image_1_link' => $images[0]['link'], + 'image_2' => $images[1]['url'], + 'image_2_link' => $images[1]['link'], + 'image_3' => $images[2]['url'], + 'image_3_link' => $images[2]['link'], + 'image_4' => $images[3]['url'], + 'image_4_link' => $images[3]['link'] + ) + ); +} + +function uc_feed_get($limit = 100, $delete = TRUE) +{ + $return = call_user_func(UC_API_FUNC, 'feed', 'get', array('limit' => $limit, 'delete' => $delete)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_friend_add($uid, $friendid, $comment = '') +{ + return call_user_func(UC_API_FUNC, 'friend', 'add', array('uid' => $uid, 'friendid' => $friendid, 'comment' => $comment)); +} + +function uc_friend_delete($uid, $friendids) +{ + return call_user_func(UC_API_FUNC, 'friend', 'delete', array('uid' => $uid, 'friendids' => $friendids)); +} + +function uc_friend_totalnum($uid, $direction = 0) +{ + return call_user_func(UC_API_FUNC, 'friend', 'totalnum', array('uid' => $uid, 'direction' => $direction)); +} + +function uc_friend_ls($uid, $page = 1, $pagesize = 10, $totalnum = 10, $direction = 0) +{ + $return = call_user_func(UC_API_FUNC, 'friend', 'ls', array('uid' => $uid, 'page' => $page, 'pagesize' => $pagesize, 'totalnum' => $totalnum, 'direction' => $direction)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_user_register($username, $password, $email = '', $mobile = '', $extend = []) +{ + return call_user_func(UC_API_FUNC, 'user', 'register', array('username' => $username, 'password' => $password, 'email' => $email, 'mobile' => $mobile, 'extend' => $extend)); +} + +function uc_user_login($username, $password, $isuid = 0, $extend = []) +{ + $isuid = intval($isuid); + $return = call_user_func(UC_API_FUNC, 'user', 'login', array('username' => $username, 'password' => $password, 'isuid' => $isuid, 'extend' => $extend)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_user_synregister($uid, $password) +{ + $uid = intval($uid); + if (@include UC_ROOT . './data/cache/apps.php') + { + if (count($_CACHE['apps']) > 1) + { + $return = uc_api_post('user', 'synregister', array('uid' => $uid, 'password' => $password)); + } + else + { + $return = ''; + } + } + return $return; +} + +function uc_user_synlogin($uid) +{ + $uid = intval($uid); + if (@include UC_ROOT . './data/cache/apps.php') + { + if (count($_CACHE['apps']) > 1) + { + $return = uc_api_post('user', 'synlogin', array('uid' => $uid)); + } + else + { + $return = ''; + } + } + return $return; +} + +function uc_user_synlogout() +{ + if (@include UC_ROOT . './data/cache/apps.php') + { + if (count($_CACHE['apps']) > 1) + { + $return = uc_api_post('user', 'synlogout', array()); + } + else + { + $return = ''; + } + } + return $return; +} + +function uc_user_edit($uid, $username, $password, $email = '', $mobile = '', $extend = []) +{ + return call_user_func(UC_API_FUNC, 'user', 'edit', array('uid' => $uid, 'username' => $username, 'password' => $password, 'email' => $email, 'mobile' => $mobile, 'extend' => $extend)); +} + +function uc_user_delete($uid) +{ + return call_user_func(UC_API_FUNC, 'user', 'delete', array('uid' => $uid)); +} + +function uc_user_deleteavatar($uid) +{ + uc_api_post('user', 'deleteavatar', array('uid' => $uid)); +} + +function uc_user_checkname($username) +{ + return call_user_func(UC_API_FUNC, 'user', 'check_username', array('username' => $username)); +} + +function uc_user_checkemail($email) +{ + return call_user_func(UC_API_FUNC, 'user', 'check_email', array('email' => $email)); +} + +function uc_user_checkmobile($mobile) +{ + return call_user_func(UC_API_FUNC, 'user', 'check_mobile', array('mobile' => $mobile)); +} + +function uc_user_addprotected($username, $admin = '') +{ + return call_user_func(UC_API_FUNC, 'user', 'addprotected', array('username' => $username, 'admin' => $admin)); +} + +function uc_user_deleteprotected($username) +{ + return call_user_func(UC_API_FUNC, 'user', 'deleteprotected', array('username' => $username)); +} + +function uc_user_getprotected() +{ + $return = call_user_func(UC_API_FUNC, 'user', 'getprotected', array('1' => 1)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_get_user($username, $isuid = 0) +{ + $return = call_user_func(UC_API_FUNC, 'user', 'get_user', array('username' => $username, 'isuid' => $isuid)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_user_merge($oldusername, $newusername, $uid, $password, $email) +{ + return call_user_func(UC_API_FUNC, 'user', 'merge', array('oldusername' => $oldusername, 'newusername' => $newusername, 'uid' => $uid, 'password' => $password, 'email' => $email)); +} + +function uc_user_merge_remove($username) +{ + return call_user_func(UC_API_FUNC, 'user', 'merge_remove', array('username' => $username)); +} + +function uc_user_getcredit($appid, $uid, $credit) +{ + return uc_api_post('user', 'getcredit', array('appid' => $appid, 'uid' => $uid, 'credit' => $credit)); +} + +function uc_user_logincheck($username, $ip) +{ + return call_user_func(UC_API_FUNC, 'user', 'logincheck', array('username' => $username, 'ip' => $ip)); +} + +function uc_pm_location($uid, $newpm = 0) +{ + $apiurl = uc_api_url('pm_client', 'ls', "uid=$uid", ($newpm ? '&folder=newbox' : '')); + @header("Expires: 0"); + @header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE); + @header("Pragma: no-cache"); + @header("location: $apiurl"); +} + +function uc_pm_checknew($uid, $more = 0) +{ + $return = call_user_func(UC_API_FUNC, 'pm', 'check_newpm', array('uid' => $uid, 'more' => $more)); + return (!$more || UC_CONNECT == 'mysql') ? $return : uc_unserialize($return); +} + +function uc_pm_send($fromuid, $msgto, $subject, $message, $instantly = 1, $replypmid = 0, $isusername = 0, $type = 0) +{ + if ($instantly) + { + $replypmid = @is_numeric($replypmid) ? $replypmid : 0; + return call_user_func(UC_API_FUNC, 'pm', 'sendpm', array('fromuid' => $fromuid, 'msgto' => $msgto, 'subject' => $subject, 'message' => $message, 'replypmid' => $replypmid, 'isusername' => $isusername, 'type' => $type)); + } + else + { + $fromuid = intval($fromuid); + $subject = rawurlencode($subject); + $msgto = rawurlencode($msgto); + $message = rawurlencode($message); + $replypmid = @is_numeric($replypmid) ? $replypmid : 0; + $replyadd = $replypmid ? "&pmid=$replypmid&do=reply" : ''; + $apiurl = uc_api_url('pm_client', 'send', "uid=$fromuid", "&msgto=$msgto&subject=$subject&message=$message$replyadd"); + @header("Expires: 0"); + @header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE); + @header("Pragma: no-cache"); + @header("location: " . $apiurl); + } +} + +function uc_pm_delete($uid, $folder, $pmids) +{ + return call_user_func(UC_API_FUNC, 'pm', 'delete', array('uid' => $uid, 'pmids' => $pmids)); +} + +function uc_pm_deleteuser($uid, $touids) +{ + return call_user_func(UC_API_FUNC, 'pm', 'deleteuser', array('uid' => $uid, 'touids' => $touids)); +} + +function uc_pm_deletechat($uid, $plids, $type = 0) +{ + return call_user_func(UC_API_FUNC, 'pm', 'deletechat', array('uid' => $uid, 'plids' => $plids, 'type' => $type)); +} + +function uc_pm_readstatus($uid, $uids, $plids = array(), $status = 0) +{ + return call_user_func(UC_API_FUNC, 'pm', 'readstatus', array('uid' => $uid, 'uids' => $uids, 'plids' => $plids, 'status' => $status)); +} + +function uc_pm_list($uid, $page = 1, $pagesize = 10, $folder = 'inbox', $filter = 'newpm', $msglen = 0) +{ + $uid = intval($uid); + $page = intval($page); + $pagesize = intval($pagesize); + $return = call_user_func(UC_API_FUNC, 'pm', 'ls', array('uid' => $uid, 'page' => $page, 'pagesize' => $pagesize, 'filter' => $filter, 'msglen' => $msglen)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_pm_ignore($uid) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'ignore', array('uid' => $uid)); +} + +function uc_pm_view($uid, $pmid = 0, $touid = 0, $daterange = 1, $page = 0, $pagesize = 10, $type = 0, $isplid = 0) +{ + $uid = intval($uid); + $touid = intval($touid); + $page = intval($page); + $pagesize = intval($pagesize); + $pmid = @is_numeric($pmid) ? $pmid : 0; + $return = call_user_func(UC_API_FUNC, 'pm', 'view', array('uid' => $uid, 'pmid' => $pmid, 'touid' => $touid, 'daterange' => $daterange, 'page' => $page, 'pagesize' => $pagesize, 'type' => $type, 'isplid' => $isplid)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_pm_view_num($uid, $touid, $isplid) +{ + $uid = intval($uid); + $touid = intval($touid); + $isplid = intval($isplid); + return call_user_func(UC_API_FUNC, 'pm', 'viewnum', array('uid' => $uid, 'touid' => $touid, 'isplid' => $isplid)); +} + +function uc_pm_viewnode($uid, $type, $pmid) +{ + $uid = intval($uid); + $type = intval($type); + $pmid = @is_numeric($pmid) ? $pmid : 0; + $return = call_user_func(UC_API_FUNC, 'pm', 'viewnode', array('uid' => $uid, 'type' => $type, 'pmid' => $pmid)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_pm_chatpmmemberlist($uid, $plid = 0) +{ + $uid = intval($uid); + $plid = intval($plid); + $return = call_user_func(UC_API_FUNC, 'pm', 'chatpmmemberlist', array('uid' => $uid, 'plid' => $plid)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_pm_kickchatpm($plid, $uid, $touid) +{ + $uid = intval($uid); + $plid = intval($plid); + $touid = intval($touid); + return call_user_func(UC_API_FUNC, 'pm', 'kickchatpm', array('uid' => $uid, 'plid' => $plid, 'touid' => $touid)); +} + +function uc_pm_appendchatpm($plid, $uid, $touid) +{ + $uid = intval($uid); + $plid = intval($plid); + $touid = intval($touid); + return call_user_func(UC_API_FUNC, 'pm', 'appendchatpm', array('uid' => $uid, 'plid' => $plid, 'touid' => $touid)); +} + +function uc_pm_blackls_get($uid) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'blackls_get', array('uid' => $uid)); +} + +function uc_pm_blackls_set($uid, $blackls) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'blackls_set', array('uid' => $uid, 'blackls' => $blackls)); +} + +function uc_pm_blackls_add($uid, $username) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'blackls_add', array('uid' => $uid, 'username' => $username)); +} + +function uc_pm_blackls_delete($uid, $username) +{ + $uid = intval($uid); + return call_user_func(UC_API_FUNC, 'pm', 'blackls_delete', array('uid' => $uid, 'username' => $username)); +} + +function uc_domain_ls() +{ + $return = call_user_func(UC_API_FUNC, 'domain', 'ls', array('1' => 1)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_credit_exchange_request($uid, $from, $to, $toappid, $amount) +{ + $uid = intval($uid); + $from = intval($from); + $toappid = intval($toappid); + $to = intval($to); + $amount = intval($amount); + return uc_api_post('credit', 'request', array('uid' => $uid, 'from' => $from, 'to' => $to, 'toappid' => $toappid, 'amount' => $amount)); +} + +function uc_tag_get($tagname, $nums = 0) +{ + $return = call_user_func(UC_API_FUNC, 'tag', 'gettag', array('tagname' => $tagname, 'nums' => $nums)); + return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return); +} + +function uc_avatar($uid, $type = 'virtual', $returnhtml = 1) +{ + $uid = intval($uid); + $uc_input = uc_api_input("uid=$uid"); + $uc_avatarflash = UC_API . '/images/camera.swf?inajax=1&appid=' . UC_APPID . '&input=' . $uc_input . '&agent=' . md5($_SERVER['HTTP_USER_AGENT']) . '&ucapi=' . urlencode(str_replace('http://', '', UC_API)) . '&avatartype=' . $type . '&uploadSize=2048'; + if ($returnhtml) + { + return '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="450" height="253" id="mycamera" align="middle"> + <param name="allowScriptAccess" value="always" /> + <param name="scale" value="exactfit" /> + <param name="wmode" value="transparent" /> + <param name="quality" value="high" /> + <param name="bgcolor" value="#ffffff" /> + <param name="movie" value="' . $uc_avatarflash . '" /> + <param name="menu" value="false" /> + <embed src="' . $uc_avatarflash . '" quality="high" bgcolor="#ffffff" width="450" height="253" name="mycamera" align="middle" allowScriptAccess="always" allowFullScreen="false" scale="exactfit" wmode="transparent" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> + </object>'; + } + else + { + return array( + 'width', '450', + 'height', '253', + 'scale', 'exactfit', + 'src', $uc_avatarflash, + 'id', 'mycamera', + 'name', 'mycamera', + 'quality', 'high', + 'bgcolor', '#ffffff', + 'menu', 'false', + 'swLiveConnect', 'true', + 'allowScriptAccess', 'always' + ); + } +} + +function uc_mail_queue($uids, $emails, $subject, $message, $frommail = '', $charset = 'gbk', $htmlon = FALSE, $level = 1) +{ + return call_user_func(UC_API_FUNC, 'mail', 'add', array('uids' => $uids, 'emails' => $emails, 'subject' => $subject, 'message' => $message, 'frommail' => $frommail, 'charset' => $charset, 'htmlon' => $htmlon, 'level' => $level)); +} + +function uc_check_avatar($uid, $size = 'middle', $type = 'virtual') +{ + $url = UC_API . "/avatar.php?uid=$uid&size=$size&type=$type&check_file_exists=1"; + $res = uc_fopen2($url, 500000, '', '', TRUE, UC_IP, 20); + if ($res == 1) + { + return 1; + } + else + { + return 0; + } +} + +function uc_check_version() +{ + $return = uc_api_post('version', 'check', array()); + $data = uc_unserialize($return); + return is_array($data) ? $data : $return; +} diff --git a/extend/fast/ucenter/client/uc_client/control/domain.php b/extend/fast/ucenter/client/uc_client/control/domain.php new file mode 100644 index 0000000..a7c76a9 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/domain.php @@ -0,0 +1,31 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: domain.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class domaincontrol extends base +{ + + function __construct() + { + $this->domaincontrol(); + } + + function domaincontrol() + { + parent::__construct(); + $this->init_input(); + $this->load('domain'); + } + + function onls() + { + return $_ENV['domain']->get_list(1, 9999, 9999); + } + +} diff --git a/extend/fast/ucenter/client/uc_client/control/feed.php b/extend/fast/ucenter/client/uc_client/control/feed.php new file mode 100644 index 0000000..86a58b3 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/feed.php @@ -0,0 +1,114 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: feed.php 1139 2012-05-08 09:02:11Z liulanbo $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class feedcontrol extends base +{ + + function __construct() + { + $this->feedcontrol(); + } + + function feedcontrol() + { + parent::__construct(); + $this->init_input(); + } + + function onadd() + { + $this->load('misc'); + $appid = intval($this->input('appid')); + $icon = $this->input('icon'); + $uid = intval($this->input('uid')); + $username = $this->input('username'); + $body_data = $_ENV['misc']->array2string($this->input('body_data')); + $title_data = $_ENV['misc']->array2string($this->input('title_data')); + + $title_template = $this->_parsetemplate($this->input('title_template')); + $body_template = $this->_parsetemplate($this->input('body_template')); + $body_general = $this->input('body_general'); + $target_ids = $this->input('target_ids'); + $image_1 = $this->input('image_1'); + $image_1_link = $this->input('image_1_link'); + $image_2 = $this->input('image_2'); + $image_2_link = $this->input('image_2_link'); + $image_3 = $this->input('image_3'); + $image_3_link = $this->input('image_3_link'); + $image_4 = $this->input('image_4'); + $image_4_link = $this->input('image_4_link'); + + $hash_template = md5($title_template . $body_template); + $hash_data = md5($title_template . $title_data . $body_template . $body_data); + $dateline = $this->time; + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "feeds SET appid='$appid', icon='$icon', uid='$uid', username='$username', + title_template='$title_template', title_data='$title_data', body_template='$body_template', body_data='$body_data', body_general='$body_general', + image_1='$image_1', image_1_link='$image_1_link', image_2='$image_2', image_2_link='$image_2_link', + image_3='$image_3', image_3_link='$image_3_link', image_4='$image_4', image_4_link='$image_4_link', + hash_template='$hash_template', hash_data='$hash_data', target_ids='$target_ids', dateline='$dateline'"); + return $this->db->insert_id(); + } + + function ondelete() + { + $start = $this->input('start'); + $limit = $this->input('limit'); + $end = $start + $limit; + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "feeds WHERE feedid>'$start' AND feedid<'$end'"); + } + + function onget() + { + $this->load('misc'); + $limit = intval($this->input('limit')); + $delete = $this->input('delete'); + $feedlist = $this->db->fetch_all("SELECT * FROM " . UC_DBTABLEPRE . "feeds ORDER BY feedid DESC LIMIT $limit"); + if ($feedlist) + { + $maxfeedid = $feedlist[0]['feedid']; + foreach ($feedlist as $key => $feed) + { + $feed['body_data'] = $_ENV['misc']->string2array($feed['body_data']); + $feed['title_data'] = $_ENV['misc']->string2array($feed['title_data']); + $feedlist[$key] = $feed; + } + } + if (!empty($feedlist)) + { + if (!isset($delete) || $delete) + { + $this->_delete(0, $maxfeedid); + } + } + return $feedlist; + } + + function _delete($start, $end) + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "feeds WHERE feedid>='$start' AND feedid<='$end'"); + } + + function _parsetemplate($template) + { + $template = str_replace(array("\r", "\n"), '', $template); + $template = str_replace(array('<br>', '<br />', '<BR>', '<BR />'), "\n", $template); + $template = str_replace(array('<b>', '<B>'), '[B]', $template); + $template = str_replace(array('<i>', '<I>'), '[I]', $template); + $template = str_replace(array('<u>', '<U>'), '[U]', $template); + $template = str_replace(array('</b>', '</B>'), '[/B]', $template); + $template = str_replace(array('</i>', '</I>'), '[/I]', $template); + $template = str_replace(array('</u>', '</U>'), '[/U]', $template); + $template = dhtmlspecialchars($template); + $template = nl2br($template); + $template = str_replace(array('[B]', '[I]', '[U]', '[/B]', '[/I]', '[/U]'), array('<b>', '<i>', '<u>', '</b>', '</i>', '</u>'), $template); + return $template; + } + +} diff --git a/extend/fast/ucenter/client/uc_client/control/friend.php b/extend/fast/ucenter/client/uc_client/control/friend.php new file mode 100644 index 0000000..01768b5 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/friend.php @@ -0,0 +1,64 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: friend.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class friendcontrol extends base +{ + + function __construct() + { + $this->friendcontrol(); + } + + function friendcontrol() + { + parent::__construct(); + $this->init_input(); + $this->load('friend'); + } + + function ondelete() + { + $uid = intval($this->input('uid')); + $friendids = $this->input('friendids'); + $id = $_ENV['friend']->delete($uid, $friendids); + return $id; + } + + function onadd() + { + $uid = intval($this->input('uid')); + $friendid = $this->input('friendid'); + $comment = $this->input('comment'); + $id = $_ENV['friend']->add($uid, $friendid, $comment); + return $id; + } + + function ontotalnum() + { + $uid = intval($this->input('uid')); + $direction = intval($this->input('direction')); + $totalnum = $_ENV['friend']->get_totalnum_by_uid($uid, $direction); + return $totalnum; + } + + function onls() + { + $uid = intval($this->input('uid')); + $page = intval($this->input('page')); + $pagesize = intval($this->input('pagesize')); + $totalnum = intval($this->input('totalnum')); + $direction = intval($this->input('direction')); + $pagesize = $pagesize ? $pagesize : UC_PPP; + $totalnum = $totalnum ? $totalnum : $_ENV['friend']->get_totalnum_by_uid($uid); + $data = $_ENV['friend']->get_list($uid, $page, $pagesize, $totalnum, $direction); + return $data; + } + +} diff --git a/extend/fast/ucenter/client/uc_client/control/index.htm b/extend/fast/ucenter/client/uc_client/control/index.htm new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/index.htm @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extend/fast/ucenter/client/uc_client/control/mail.php b/extend/fast/ucenter/client/uc_client/control/mail.php new file mode 100644 index 0000000..28bdedd --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/mail.php @@ -0,0 +1,42 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: mail.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class mailcontrol extends base +{ + + function __construct() + { + $this->mailcontrol(); + } + + function mailcontrol() + { + parent::__construct(); + $this->init_input(); + } + + function onadd() + { + $this->load('mail'); + $mail = array(); + $mail['appid'] = UC_APPID; + $mail['uids'] = explode(',', $this->input('uids')); + $mail['emails'] = explode(',', $this->input('emails')); + $mail['subject'] = $this->input('subject'); + $mail['message'] = $this->input('message'); + $mail['charset'] = $this->input('charset'); + $mail['htmlon'] = intval($this->input('htmlon')); + $mail['level'] = abs(intval($this->input('level'))); + $mail['frommail'] = $this->input('frommail'); + $mail['dateline'] = $this->time; + return $_ENV['mail']->add($mail); + } + +} diff --git a/extend/fast/ucenter/client/uc_client/control/pm.php b/extend/fast/ucenter/client/uc_client/control/pm.php new file mode 100644 index 0000000..940d398 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/pm.php @@ -0,0 +1,463 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: pm.php 1067 2011-03-08 10:06:51Z svn_project_zhangjie $ + */ +!defined('IN_UC') && exit('Access Denied'); + +define('PRIVATEPMTHREADLIMIT_ERROR', -1); +define('PMFLOODCTRL_ERROR', -2); +define('PMMSGTONOTFRIEND', -3); +define('PMSENDREGDAYS', -4); +define('CHATPMTHREADLIMIT_ERROR', -5); +define('CHATPMMEMBERLIMIT_ERROR', -7); + +class pmcontrol extends base +{ + + function __construct() + { + $this->pmcontrol(); + } + + function pmcontrol() + { + parent::__construct(); + $this->load('user'); + $this->load('pm'); + } + + function oncheck_newpm() + { + $this->init_input(); + $uid = intval($this->input('uid')); + $more = intval($this->input('more')); + if (!$_ENV['pm']->isnewpm($uid) && !$more) + { + return 0; + } + $newprvpm = $_ENV['pm']->getpmnum($uid, 1, 1); + $newchatpm = $_ENV['pm']->getpmnum($uid, 2, 1); + $newpm = $newprvpm + $newchatpm; + if ($more == 0) + { + return $newpm; + } + elseif ($more == 1) + { + return array('newpm' => $newpm, 'newprivatepm' => $newprvpm); + } + elseif ($more == 2 || $more == 3) + { + if ($more == 2) + { + return array('newpm' => $newpm, 'newprivatepm' => $newprvpm, 'newchatpm' => $newchatpm); + } + else + { + $lastpm = $_ENV['pm']->lastpm($uid); + require_once UC_ROOT . 'lib/uccode.class.php'; + $this->uccode = new uccode(); + $lastpm['lastsummary'] = $this->uccode->complie($lastpm['lastsummary']); + return array('newpm' => $newpm, 'newprivatepm' => $newprvpm, 'newchatpm' => $newchatpm, 'lastdate' => $lastpm['lastdateline'], 'lastmsgfromid' => $lastpm['lastauthorid'], 'lastmsgfrom' => $lastpm['lastauthorusername'], 'lastmsg' => $lastpm['lastsummary']); + } + } + elseif ($more == 4) + { + return array('newpm' => $newpm, 'newprivatepm' => $newprvpm, 'newchatpm' => $newchatpm); + } + else + { + return 0; + } + } + + function onsendpm() + { + $this->init_input(); + $fromuid = $this->input('fromuid'); + $msgto = $this->input('msgto'); + $subject = $this->input('subject'); + $message = $this->input('message'); + $replypmid = $this->input('replypmid'); + $isusername = $this->input('isusername'); + $type = $this->input('type'); + + if (!$fromuid) + { + return 0; + } + + $user = $_ENV['user']->get_user_by_uid($fromuid); + $user = daddslashes($user, 1); + if (!$user) + { + return 0; + } + $this->user['uid'] = $user['uid']; + $this->user['username'] = $user['username']; + + if ($replypmid) + { + $isusername = 0; + $plid = $_ENV['pm']->getplidbypmid($replypmid); + $msgto = $_ENV['pm']->getuidbyplid($plid); + unset($msgto[$this->user['uid']]); + } + else + { + if (!empty($msgto)) + { + $msgto = array_unique(explode(',', $msgto)); + } + } + + if ($isusername) + { + $msgto = $_ENV['user']->name2id($msgto); + } + $countmsgto = count($msgto); + + if ($this->settings['pmsendregdays']) + { + if ($user['regdate'] > $this->time - $this->settings['pmsendregdays'] * 86400) + { + return PMSENDREGDAYS; + } + } + if ($this->settings['chatpmmemberlimit']) + { + if ($type == 1 && ($countmsgto > ($this->settings['chatpmmemberlimit'] - 1))) + { + return CHATPMMEMBERLIMIT_ERROR; + } + } + if ($this->settings['pmfloodctrl']) + { + if (!$_ENV['pm']->ispminterval($this->user['uid'], $this->settings['pmfloodctrl'])) + { + return PMFLOODCTRL_ERROR; + } + } + if ($this->settings['privatepmthreadlimit']) + { + if (!$_ENV['pm']->isprivatepmthreadlimit($this->user['uid'], $this->settings['privatepmthreadlimit'])) + { + return PRIVATEPMTHREADLIMIT_ERROR; + } + } + if ($this->settings['chatpmthreadlimit']) + { + if (!$_ENV['pm']->ischatpmthreadlimit($this->user['uid'], $this->settings['chatpmthreadlimit'])) + { + return CHATPMTHREADLIMIT_ERROR; + } + } + + $lastpmid = 0; + if ($replypmid) + { + $lastpmid = $_ENV['pm']->replypm($plid, $this->user['uid'], $this->user['username'], $message); + } + else + { + $lastpmid = $_ENV['pm']->sendpm($this->user['uid'], $this->user['username'], $msgto, $subject, $message, $type); + } + return $lastpmid; + } + + function ondelete() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $pmids = $this->input('pmids'); + if (empty($pmids)) + { + return 0; + } + if (is_array($pmids)) + { + $this->apps = $this->cache('apps'); + if ($this->apps[$this->app['appid']]['type'] == 'UCHOME') + { + $id = $_ENV['pm']->deletepmbyplids($this->user['uid'], $this->input('pmids')); + } + else + { + $id = $_ENV['pm']->deletepmbypmids($this->user['uid'], $this->input('pmids')); + } + } + else + { + $id = $_ENV['pm']->deletepmbypmid($this->user['uid'], $this->input('pmids')); + } + return $id; + } + + function ondeletechat() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $plids = $this->input('plids'); + $type = intval($this->input('type')); + if ($type == 1) + { + return $_ENV['pm']->deletepmbyplids($this->user['uid'], $plids); + } + else + { + return $_ENV['pm']->quitchatpm($this->user['uid'], $plids); + } + } + + function ondeleteuser() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $id = $_ENV['pm']->deletepmbyplids($this->user['uid'], $this->input('touids'), 1); + return $id; + } + + function onreadstatus() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $_ENV['pm']->setpmstatus($this->user['uid'], $this->input('uids'), $this->input('plids'), $this->input('status')); + } + + function onignore() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + return $_ENV['pm']->set_ignore($this->user['uid']); + } + + function onls() + { + $this->init_input(); + $pagesize = $this->input('pagesize'); + $filter = $this->input('filter'); + $page = $this->input('page'); + $msglen = $this->input('msglen'); + $this->user['uid'] = intval($this->input('uid')); + + $filter = $filter ? (in_array($filter, array('newpm', 'privatepm')) ? $filter : '') : ''; + if ($filter == 'newpm') + { + $type = 0; + $new = 1; + } + elseif ($filter == 'privatepm') + { + $type = 0; + $new = 0; + } + else + { + return array(); + } + $pmnum = $_ENV['pm']->getpmnum($this->user['uid'], $type, $new); + $start = $this->page_get_start($page, $pagesize, $pmnum); + + if ($pagesize > 0) + { + $pms = $_ENV['pm']->getpmlist($this->user['uid'], $filter, $start, $pagesize); + if (is_array($pms) && !empty($pms)) + { + foreach ($pms as $key => $pm) + { + if ($msglen) + { + $pms[$key]['lastsummary'] = $_ENV['pm']->removecode($pms[$key]['lastsummary'], $msglen); + } + else + { + unset($pms[$key]['lastsummary']); + } + } + } + $result['data'] = $pms; + } + $result['count'] = $pmnum; + return $result; + } + + function onview() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $pmid = $this->input('pmid'); + $touid = $this->input('touid'); + $daterange = $this->input('daterange'); + $page = $this->input('page'); + $pagesize = $this->input('pagesize'); + $isplid = $this->input('isplid'); + $type = $this->input('type'); + + $daterange = empty($daterange) ? 1 : $daterange; + $today = $this->time - ($this->time + $this->settings['timeoffset']) % 86400; + if ($daterange == 1) + { + $starttime = $today; + } + elseif ($daterange == 2) + { + $starttime = $today - 86400; + } + elseif ($daterange == 3) + { + $starttime = $today - 172800; + } + elseif ($daterange == 4) + { + $starttime = $today - 604800; + } + elseif ($daterange == 5) + { + $starttime = 0; + } + $endtime = $this->time; + + if (!$isplid) + { + $plid = $_ENV['pm']->getplidbytouid($this->user['uid'], $touid); + } + else + { + $plid = $touid; + } + if ($page) + { + $pmnum = $_ENV['pm']->getpmnumbyplid($this->user['uid'], $plid); + $start = $this->page_get_start($page, $pagesize, $pmnum); + $ppp = $pagesize; + } + else + { + $pmnum = 0; + $start = 0; + $ppp = 0; + } + + if ($pmid) + { + $pms = $_ENV['pm']->getpmbypmid($this->user['uid'], $pmid); + } + else + { + $pms = $_ENV['pm']->getpmbyplid($this->user['uid'], $plid, $starttime, $endtime, $start, $ppp, $type); + } + + require_once UC_ROOT . 'lib/uccode.class.php'; + $this->uccode = new uccode(); + if ($pms) + { + foreach ($pms as $key => $pm) + { + $pms[$key]['message'] = $this->uccode->complie($pms[$key]['message']); + } + } + return $pms; + } + + function onviewnum() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $touid = $this->input('touid'); + $isplid = $this->input('isplid'); + if (!$isplid) + { + $plid = $_ENV['pm']->getplidbytouid($this->user['uid'], $touid); + } + else + { + $plid = $touid; + } + $pmnum = $_ENV['pm']->getpmnumbyplid($this->user['uid'], $plid); + return $pmnum; + } + + function onviewnode() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $type = $this->input('type'); + $pmid = $this->input('pmid'); + $type = 0; + $pms = $_ENV['pm']->getpmbypmid($this->user['uid'], $pmid); + + require_once UC_ROOT . 'lib/uccode.class.php'; + $this->uccode = new uccode(); + if ($pms) + { + foreach ($pms as $key => $pm) + { + $pms[$key]['message'] = $this->uccode->complie($pms[$key]['message']); + } + } + $pms = $pms[0]; + return $pms; + } + + function onchatpmmemberlist() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $plid = intval($this->input('plid')); + return $_ENV['pm']->chatpmmemberlist($this->user['uid'], $plid); + } + + function onkickchatpm() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $plid = intval($this->input('plid')); + $touid = intval($this->input('touid')); + return $_ENV['pm']->kickchatpm($plid, $this->user['uid'], $touid); + } + + function onappendchatpm() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $plid = intval($this->input('plid')); + $touid = intval($this->input('touid')); + return $_ENV['pm']->appendchatpm($plid, $this->user['uid'], $touid); + } + + function onblackls_get() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + return $_ENV['pm']->get_blackls($this->user['uid']); + } + + function onblackls_set() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $blackls = $this->input('blackls'); + return $_ENV['pm']->set_blackls($this->user['uid'], $blackls); + } + + function onblackls_add() + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $username = $this->input('username'); + return $_ENV['pm']->update_blackls($this->user['uid'], $username, 1); + } + + function onblackls_delete($arr) + { + $this->init_input(); + $this->user['uid'] = intval($this->input('uid')); + $username = $this->input('username'); + return $_ENV['pm']->update_blackls($this->user['uid'], $username, 2); + } + +} diff --git a/extend/fast/ucenter/client/uc_client/control/tag.php b/extend/fast/ucenter/client/uc_client/control/tag.php new file mode 100644 index 0000000..8fc80aa --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/tag.php @@ -0,0 +1,102 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: tag.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class tagcontrol extends base +{ + + function __construct() + { + $this->tagcontrol(); + } + + function tagcontrol() + { + parent::__construct(); + $this->init_input(); + $this->load('tag'); + $this->load('misc'); + } + + function ongettag() + { + $appid = $this->input('appid'); + $tagname = $this->input('tagname'); + $nums = $this->input('nums'); + if (empty($tagname)) + { + return NULL; + } + $return = $apparray = $appadd = array(); + + if ($nums && is_array($nums)) + { + foreach ($nums as $k => $num) + { + $apparray[$k] = $k; + } + } + + $data = $_ENV['tag']->get_tag_by_name($tagname); + if ($data) + { + $apparraynew = array(); + foreach ($data as $tagdata) + { + $row = $r = array(); + $tmp = explode("\t", $tagdata['data']); + $type = $tmp[0]; + array_shift($tmp); + foreach ($tmp as $tmp1) + { + $tmp1 != '' && $r[] = $_ENV['misc']->string2array($tmp1); + } + if (in_array($tagdata['appid'], $apparray)) + { + if ($tagdata['expiration'] > 0 && $this->time - $tagdata['expiration'] > 3600) + { + $appadd[] = $tagdata['appid']; + $_ENV['tag']->formatcache($tagdata['appid'], $tagname); + } + else + { + $apparraynew[] = $tagdata['appid']; + } + $datakey = array(); + $count = 0; + foreach ($r as $data) + { + $return[$tagdata['appid']]['data'][] = $data; + $return[$tagdata['appid']]['type'] = $type; + $count++; + if ($count >= $nums[$tagdata['appid']]) + { + break; + } + } + } + } + $apparray = array_diff($apparray, $apparraynew); + } + else + { + foreach ($apparray as $appid) + { + $_ENV['tag']->formatcache($appid, $tagname); + } + } + if ($apparray) + { + $this->load('note'); + $_ENV['note']->add('gettag', "id=$tagname", '', $appadd, -1); + } + return $return; + } + +} diff --git a/extend/fast/ucenter/client/uc_client/control/user.php b/extend/fast/ucenter/client/uc_client/control/user.php new file mode 100644 index 0000000..42d0b4e --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/control/user.php @@ -0,0 +1,443 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: user.php 1174 2014-11-03 04:38:12Z hypowang $ + */ +!defined('IN_UC') && exit('Access Denied'); + +define('UC_USER_CHECK_USERNAME_FAILED', -1); +define('UC_USER_USERNAME_BADWORD', -2); +define('UC_USER_USERNAME_EXISTS', -3); +define('UC_USER_EMAIL_FORMAT_ILLEGAL', -4); +define('UC_USER_EMAIL_ACCESS_ILLEGAL', -5); +define('UC_USER_EMAIL_EXISTS', -6); +define('UC_USER_MOBILE_FORMAT_ILLEGAL', -7); +define('UC_USER_MOBILE_ACCESS_ILLEGAL', -8); +define('UC_USER_MOBILE_EXISTS', -9); + +class usercontrol extends base +{ + + function __construct() + { + $this->usercontrol(); + } + + function usercontrol() + { + parent::__construct(); + $this->load('user'); + $this->app = $this->cache['apps'][UC_APPID]; + } + + // 同步注册 + function onsynregister() + { + $this->init_input(); + $uid = $this->input('uid'); + $password = $this->input('password'); + if ($this->app['synlogin']) + { + if ($this->user = $_ENV['user']->get_user_by_uid($uid)) + { + $params = 'action=synregister' . + '&username=' . $this->user['username'] . + '&uid=' . $this->user['uid'] . + '&password=' . $password . + '&email=' . $this->user['email'] . + '&mobile=' . $this->user['mobile'] . + '&time=' . $this->time; + $synstr = ''; + foreach ($this->cache['apps'] as $appid => $app) + { + if ($app['synlogin'] && $app['appid'] != $this->app['appid']) + { + $synstr .= '<script type="text/javascript" src="' . $app['url'] . '/api/uc.php?time=' . $this->time . '&code=' . urlencode($this->authcode($params, 'ENCODE', $app['authkey'])) . '"></script>'; + } + } + return $synstr; + } + } + return ''; + } + + // 同步登录 + function onsynlogin() + { + $this->init_input(); + $uid = $this->input('uid'); + if ($this->app['synlogin']) + { + if ($this->user = $_ENV['user']->get_user_by_uid($uid)) + { + $params = 'action=synlogin' . + '&username=' . $this->user['username'] . + '&uid=' . $this->user['uid'] . + '&password=' . $this->user['password'] . + '&time=' . $this->time; + $synstr = ''; + foreach ($this->cache['apps'] as $appid => $app) + { + if ($app['synlogin'] && $app['appid'] != $this->app['appid']) + { + $synstr .= '<script type="text/javascript" src="' . $app['url'] . '/api/uc.php?time=' . $this->time . '&code=' . urlencode($this->authcode($params, 'ENCODE', $app['authkey'])) . '"></script>'; + } + } + return $synstr; + } + } + return ''; + } + + // 同步退出 + function onsynlogout() + { + $this->init_input(); + if ($this->app['synlogin']) + { + $synstr = ''; + foreach ($this->cache['apps'] as $appid => $app) + { + if ($app['synlogin'] && $app['appid'] != $this->app['appid']) + { + $synstr .= '<script type="text/javascript" src="' . $app['url'] . '/api/uc.php?time=' . $this->time . '&code=' . urlencode($this->authcode('action=synlogout&time=' . $this->time, 'ENCODE', $app['authkey'])) . '"></script>'; + } + } + return $synstr; + } + return ''; + } + + // 同步注册 + function onregister() + { + $this->init_input(); + $username = $this->input('username'); + $password = $this->input('password'); + $email = $this->input('email'); + $mobile = $this->input('mobile'); + $extend = $this->input('extend'); + $extend = $extend ? $extend : []; + if (($status = $this->_check_username($username)) < 0) + { + return $status; + } + if ($email && ($status = $this->_check_email($email)) < 0) + { + return $status; + } + if ($mobile && ($status = $this->_check_mobile($mobile)) < 0) + { + return $status; + } + $uid = $_ENV['user']->add_user($username, $password, $email, $mobile, 0, $extend); + return $uid; + } + + // 编辑ucenter中信息 + function onedit() + { + $this->init_input(); + $uid = intval($this->input('uid')); + $username = $this->input('username'); + $password = $this->input('password'); + $email = $this->input('email'); + $mobile = $this->input('mobile'); + $extend = $this->input('extend'); + $extend = $extend ? $extend : []; + + $status = $_ENV['user']->edit_user($username, $password, $email, $mobile, $uid, $extend); + + if ($status > 0) + { + if (@include UC_ROOT . './data/cache/apps.php') + { + if (count($_CACHE['apps']) > 1) + { + //手动调用一次同步到所有应用 + uc_api_post('user', 'edit', $this->input); + } + } + return $status; + $this->load('note'); + $_ENV['note']->add('updateinfo', http_build_query($this->input)); + } + return $status; + } + + // 登录ucenter账号 + function onlogin() + { + $this->init_input(); + $username = $this->input('username'); + $password = $this->input('password'); + $isuid = $this->input('isuid'); //0用户名 1UID 2邮箱 3手机 + + if ($isuid == 1) + { + $user = $_ENV['user']->get_user_by_uid($username); + } + elseif ($isuid == 2) + { + $user = $_ENV['user']->get_user_by_email($username); + } + elseif ($isuid == 3) + { + $user = $_ENV['user']->get_user_by_mobile($username); + } + else + { + $user = $_ENV['user']->get_user_by_username($username); + } + + $passwordmd5 = preg_match('/^\w{32}$/', $password) ? $password : md5($password); + if (empty($user)) + { + $status = -1; + } + elseif ($user['password'] != md5($passwordmd5 . $user['salt'])) + { + $status = -2; + } + else + { + $status = $user['uid']; + } + $merge = $status != -1 && !$isuid && $_ENV['user']->check_mergeuser($username) ? 1 : 0; + return [ + 'status' => $status, + 'uid' => isset($user['uid']) ? $user['uid'] : 0, + 'username' => isset($user['username']) ? $user['username'] : '', + 'password' => $password, + 'email' => isset($user['email']) ? $user['email'] : '', + 'mobile' => isset($user['mobile']) ? $user['mobile'] : '', + 'merge' => $merge + ]; + } + + function onlogincheck() + { + $this->init_input(); + $username = $this->input('username'); + $ip = $this->input('ip'); + return $_ENV['user']->can_do_login($username, $ip); + } + + function oncheck_email() + { + $this->init_input(); + $email = $this->input('email'); + return $this->_check_email($email); + } + + function oncheck_username() + { + $this->init_input(); + $username = $this->input('username'); + if (($status = $this->_check_username($username)) < 0) + { + return $status; + } + else + { + return 1; + } + } + + function onget_user() + { + $this->init_input(); + $username = $this->input('username'); + $isuid = $this->input('isuid'); //0用户名 1UID 2邮箱 3手机 + if ($isuid == 1) + { + $member = $_ENV['user']->get_user_by_uid($username); + } + else if ($isuid == 2) + { + $member = $_ENV['user']->get_user_by_email($username); + } + else if ($isuid == 3) + { + $member = $_ENV['user']->get_user_by_mobile($username); + } + else + { + $member = $_ENV['user']->get_user_by_username($username); + } + if ($member) + { + // 加载扩展表 + $memberfields = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "memberfields WHERE uid='{$member['uid']}'"); + + $memberfields = $memberfields ? $memberfields : []; + $member = [ + 'uid' => $member['uid'], + 'username' => $member['username'], + 'email' => $member['email'], + 'mobile' => $member['mobile'] + ]; + return array_merge($member, $memberfields); + } + else + { + return 0; + } + } + + function ongetprotected() + { + $this->init_input(); + $protectedmembers = $this->db->fetch_all("SELECT uid,username FROM " . UC_DBTABLEPRE . "protectedmembers GROUP BY username"); + return $protectedmembers; + } + + function ondelete() + { + $this->init_input(); + $uid = $this->input('uid'); + return $_ENV['user']->delete_user($uid); + } + + function onaddprotected() + { + $this->init_input(); + $username = $this->input('username'); + $admin = $this->input('admin'); + $appid = $this->app['appid']; + $usernames = (array) $username; + foreach ($usernames as $username) + { + $user = $_ENV['user']->get_user_by_username($username); + $uid = $user['uid']; + $this->db->query("REPLACE INTO " . UC_DBTABLEPRE . "protectedmembers SET uid='$uid', username='$username', appid='$appid', dateline='{$this->time}', admin='$admin'", 'SILENT'); + } + return $this->db->errno() ? -1 : 1; + } + + function ondeleteprotected() + { + $this->init_input(); + $username = $this->input('username'); + $appid = $this->app['appid']; + $usernames = (array) $username; + foreach ($usernames as $username) + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "protectedmembers WHERE username='$username' AND appid='$appid'"); + } + return $this->db->errno() ? -1 : 1; + } + + function onmerge() + { + $this->init_input(); + $uid = $this->input('uid'); + $oldusername = $this->input('oldusername'); + $newusername = $this->input('newusername'); + $password = $this->input('password'); + $email = $this->input('email'); + $mobile = $this->input('mobile'); + $extend = $this->input('extend'); + $extend = $extend ? $extend : []; + if (($status = $this->_check_username($newusername)) < 0) + { + return $status; + } + $uid = $_ENV['user']->add_user($newusername, $password, $email, $mobile, $uid, $extend); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "mergemembers WHERE appid='" . $this->app['appid'] . "' AND username='$oldusername'"); + return $uid; + } + + function onmerge_remove() + { + $this->init_input(); + $username = $this->input('username'); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "mergemembers WHERE appid='" . $this->app['appid'] . "' AND username='$username'"); + return NULL; + } + + function _check_username($username) + { + $username = addslashes(trim(stripslashes($username))); + if (!$_ENV['user']->check_username($username)) + { + return UC_USER_CHECK_USERNAME_FAILED; + } + elseif (!$_ENV['user']->check_usernamecensor($username)) + { + return UC_USER_USERNAME_BADWORD; + } + elseif ($_ENV['user']->check_usernameexists($username)) + { + return UC_USER_USERNAME_EXISTS; + } + return 1; + } + + function _check_email($email, $username = '') + { + if (empty($this->settings)) + { + $this->settings = $this->cache('settings'); + } + if (!$_ENV['user']->check_emailformat($email)) + { + return UC_USER_EMAIL_FORMAT_ILLEGAL; + } + elseif (!$_ENV['user']->check_emailaccess($email)) + { + return UC_USER_EMAIL_ACCESS_ILLEGAL; + } + elseif (!$this->settings['doublee'] && $_ENV['user']->check_emailexists($email, $username)) + { + return UC_USER_EMAIL_EXISTS; + } + else + { + return 1; + } + } + + function _check_mobile($mobile, $username = '') + { + if (empty($this->settings)) + { + $this->settings = $this->cache('settings'); + } + if (!$_ENV['user']->check_mobileformat($mobile)) + { + return UC_USER_EMAIL_FORMAT_ILLEGAL; + } + elseif (!$_ENV['user']->check_mobileaccess($mobile)) + { + return UC_USER_EMAIL_ACCESS_ILLEGAL; + } + elseif (!$this->settings['doublee'] && $_ENV['user']->check_mobileexists($mobile, $username)) + { + return UC_USER_EMAIL_EXISTS; + } + else + { + return 1; + } + } + + function onuploadavatar() + { + + } + + function onrectavatar() + { + + } + + function flashdata_decode($s) + { + + } + +} diff --git a/extend/fast/ucenter/client/uc_client/data/cache/apps.php b/extend/fast/ucenter/client/uc_client/data/cache/apps.php new file mode 100644 index 0000000..eddad2f --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/data/cache/apps.php @@ -0,0 +1,40 @@ +<?php +$_CACHE['apps'] = array ( + 1 => + array ( + 'appid' => '1', + 'type' => 'OTHER', + 'name' => 'FastAdmin', + 'url' => 'http://www.tp.com/index/ucenter', + 'ip' => '', + 'viewprourl' => '', + 'apifilename' => 'index', + 'charset' => '', + 'synlogin' => '1', + 'extra' => + array ( + 'apppath' => '', + 'extraurl' => ' ', + ), + 'recvnote' => '1', + ), + 2 => + array ( + 'appid' => '2', + 'type' => 'DISCUZX', + 'name' => 'Discuz!', + 'url' => 'http://www.discuz.com', + 'ip' => '', + 'viewprourl' => '', + 'apifilename' => 'uc.php', + 'charset' => 'utf-8', + 'synlogin' => '1', + 'extra' => + array ( + 'apppath' => '', + 'extraurl' => ' ', + ), + 'recvnote' => '1', + ), + 'UC_API' => 'http://www.ucenter.com', +); diff --git a/extend/fast/ucenter/client/uc_client/data/cache/badwords.php b/extend/fast/ucenter/client/uc_client/data/cache/badwords.php new file mode 100644 index 0000000..c3ca52b --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/data/cache/badwords.php @@ -0,0 +1,5 @@ +<?php +$_CACHE['badwords'] = array ( +); + +?> \ No newline at end of file diff --git a/extend/fast/ucenter/client/uc_client/data/cache/index.htm b/extend/fast/ucenter/client/uc_client/data/cache/index.htm new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/data/cache/index.htm diff --git a/extend/fast/ucenter/client/uc_client/data/cache/settings.php b/extend/fast/ucenter/client/uc_client/data/cache/settings.php new file mode 100644 index 0000000..069021e --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/data/cache/settings.php @@ -0,0 +1,32 @@ +<?php +$_CACHE['settings'] = array ( + 'accessemail' => '', + 'censoremail' => '', + 'censorusername' => '', + 'dateformat' => 'y-n-j', + 'doublee' => '0', + 'nextnotetime' => '0', + 'timeoffset' => '28800', + 'privatepmthreadlimit' => '25', + 'chatpmthreadlimit' => '30', + 'chatpmmemberlimit' => '35', + 'pmfloodctrl' => '15', + 'pmcenter' => '1', + 'sendpmseccode' => '1', + 'pmsendregdays' => '0', + 'maildefault' => 'username@21cn.com', + 'mailsend' => '1', + 'mailserver' => 'smtp.21cn.com', + 'mailport' => '25', + 'mailauth' => '1', + 'mailfrom' => 'UCenter <username@21cn.com>', + 'mailauth_username' => 'username@21cn.com', + 'mailauth_password' => 'password', + 'maildelimiter' => '0', + 'mailusername' => '1', + 'mailsilent' => '1', + 'version' => '1.6.0', + 'credits' => 'N;', +); + +?> \ No newline at end of file diff --git a/extend/fast/ucenter/client/uc_client/data/index.htm b/extend/fast/ucenter/client/uc_client/data/index.htm new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/data/index.htm diff --git a/extend/fast/ucenter/client/uc_client/index.htm b/extend/fast/ucenter/client/uc_client/index.htm new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/index.htm @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extend/fast/ucenter/client/uc_client/lib/db.class.php b/extend/fast/ucenter/client/uc_client/lib/db.class.php new file mode 100644 index 0000000..0c1f20b --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/lib/db.class.php @@ -0,0 +1,210 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: db.class.php 1171 2014-11-03 03:33:47Z hypowang $ + */ + +class ucclient_db +{ + + var $querynum = 0; + var $link; + var $histories; + var $dbhost; + var $dbuser; + var $dbpw; + var $dbcharset; + var $pconnect; + var $tablepre; + var $time; + var $goneaway = 5; + + function connect($dbhost, $dbuser, $dbpw, $dbname = '', $dbcharset = '', $pconnect = 0, $tablepre = '', $time = 0) + { + $this->dbhost = $dbhost; + $this->dbuser = $dbuser; + $this->dbpw = $dbpw; + $this->dbname = $dbname; + $this->dbcharset = $dbcharset; + $this->pconnect = $pconnect; + $this->tablepre = $tablepre; + $this->time = $time; + + if ($pconnect) + { + if (!$this->link = mysql_pconnect($dbhost, $dbuser, $dbpw)) + { + $this->halt('Can not connect to MySQL server'); + } + } + else + { + if (!$this->link = mysql_connect($dbhost, $dbuser, $dbpw)) + { + $this->halt('Can not connect to MySQL server'); + } + } + + if ($this->version() > '4.1') + { + if ($dbcharset) + { + mysql_query("SET character_set_connection=" . $dbcharset . ", character_set_results=" . $dbcharset . ", character_set_client=binary", $this->link); + } + + if ($this->version() > '5.0.1') + { + mysql_query("SET sql_mode=''", $this->link); + } + } + + if ($dbname) + { + mysql_select_db($dbname, $this->link); + } + } + + function fetch_array($query, $result_type = MYSQL_ASSOC) + { + return mysql_fetch_array($query, $result_type); + } + + function result_first($sql) + { + $query = $this->query($sql); + return $this->result($query, 0); + } + + function fetch_first($sql) + { + $query = $this->query($sql); + return $this->fetch_array($query); + } + + function fetch_all($sql, $id = '') + { + $arr = array(); + $query = $this->query($sql); + while ($data = $this->fetch_array($query)) + { + $id ? $arr[$data[$id]] = $data : $arr[] = $data; + } + return $arr; + } + + function cache_gc() + { + $this->query("DELETE FROM {$this->tablepre}sqlcaches WHERE expiry<$this->time"); + } + + function query($sql, $type = '', $cachetime = FALSE) + { + $func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ? 'mysql_unbuffered_query' : 'mysql_query'; + if (!($query = $func($sql, $this->link)) && $type != 'SILENT') + { + $this->halt('MySQL Query Error', $sql); + } + $this->querynum++; + $this->histories[] = $sql; + return $query; + } + + function affected_rows() + { + return mysql_affected_rows($this->link); + } + + function error() + { + return (($this->link) ? mysql_error($this->link) : mysql_error()); + } + + function errno() + { + return intval(($this->link) ? mysql_errno($this->link) : mysql_errno()); + } + + function result($query, $row) + { + $query = @mysql_result($query, $row); + return $query; + } + + function num_rows($query) + { + $query = mysql_num_rows($query); + return $query; + } + + function num_fields($query) + { + return mysql_num_fields($query); + } + + function free_result($query) + { + return mysql_free_result($query); + } + + function insert_id() + { + return ($id = mysql_insert_id($this->link)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0); + } + + function fetch_row($query) + { + $query = mysql_fetch_row($query); + return $query; + } + + function fetch_fields($query) + { + return mysql_fetch_field($query); + } + + function version() + { + return mysql_get_server_info($this->link); + } + + function escape_string($str) + { + return mysql_escape_string($str); + } + + function close() + { + return mysql_close($this->link); + } + + function halt($message = '', $sql = '') + { + $error = mysql_error(); + $errorno = mysql_errno(); + if ($errorno == 2006 && $this->goneaway-- > 0) + { + $this->connect($this->dbhost, $this->dbuser, $this->dbpw, $this->dbname, $this->dbcharset, $this->pconnect, $this->tablepre, $this->time); + $this->query($sql); + } + else + { + $s = ''; + if ($message) + { + $s = "<b>UCenter info:</b> $message<br />"; + } + if ($sql) + { + $s .= '<b>SQL:</b>' . htmlspecialchars($sql) . '<br />'; + } + $s .= '<b>Error:</b>' . $error . '<br />'; + $s .= '<b>Errno:</b>' . $errorno . '<br />'; + $s = str_replace(UC_DBTABLEPRE, '[Table]', $s); + exit($s); + } + } + +} diff --git a/extend/fast/ucenter/client/uc_client/lib/dbi.class.php b/extend/fast/ucenter/client/uc_client/lib/dbi.class.php new file mode 100644 index 0000000..2972e92 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/lib/dbi.class.php @@ -0,0 +1,200 @@ +<?php + +/* + [UCenter] (C)2001-2009 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: db.class.php 922 2009-02-19 01:30:22Z zhaoxiongfei $ + */ + +class ucclient_db +{ + + var $querynum = 0; + var $link; + var $histories; + var $dbhost; + var $dbuser; + var $dbpw; + var $dbcharset; + var $pconnect; + var $tablepre; + var $time; + var $goneaway = 5; + + function connect($dbhost, $dbuser, $dbpw, $dbname = '', $dbcharset = '', $pconnect = 0, $tablepre = '', $time = 0) + { + $this->dbhost = $dbhost; + $this->dbuser = $dbuser; + $this->dbpw = $dbpw; + $this->dbname = $dbname; + $this->dbcharset = $dbcharset; + $this->pconnect = $pconnect; + $this->tablepre = $tablepre; + $this->time = $time; + + if (!$this->link = new mysqli($dbhost, $dbuser, $dbpw, $dbname)) + { + $this->halt('Can not connect to MySQL server'); + } + + if ($this->version() > '4.1') + { + if ($dbcharset) + { + $this->link->set_charset($dbcharset); + } + + if ($this->version() > '5.0.1') + { + $this->link->query("SET sql_mode=''"); + } + } + } + + function fetch_array($query, $result_type = MYSQLI_ASSOC) + { + return $query ? $query->fetch_array($result_type) : null; + } + + function result_first($sql) + { + $query = $this->query($sql); + return $this->result($query, 0); + } + + function fetch_first($sql) + { + $query = $this->query($sql); + return $this->fetch_array($query); + } + + function fetch_all($sql, $id = '') + { + $arr = array(); + $query = $this->query($sql); + while ($data = $this->fetch_array($query)) + { + $id ? $arr[$data[$id]] = $data : $arr[] = $data; + } + return $arr; + } + + function cache_gc() + { + $this->query("DELETE FROM {$this->tablepre}sqlcaches WHERE expiry<$this->time"); + } + + function query($sql, $type = '', $cachetime = FALSE) + { + $resultmode = $type == 'UNBUFFERED' ? MYSQLI_USE_RESULT : MYSQLI_STORE_RESULT; + if (!($query = $this->link->query($sql, $resultmode)) && $type != 'SILENT') + { + $this->halt('MySQL Query Error', $sql); + } + $this->querynum++; + $this->histories[] = $sql; + return $query; + } + + function affected_rows() + { + return $this->link->affected_rows; + } + + function error() + { + return (($this->link) ? $this->link->error : mysqli_error()); + } + + function errno() + { + return intval(($this->link) ? $this->link->errno : mysqli_errno()); + } + + function result($query, $row) + { + if (!$query || $query->num_rows == 0) + { + return null; + } + $query->data_seek($row); + $assocs = $query->fetch_row(); + return $assocs[0]; + } + + function num_rows($query) + { + $query = $query ? $query->num_rows : 0; + return $query; + } + + function num_fields($query) + { + return $query ? $query->field_count : 0; + } + + function free_result($query) + { + return $query ? $query->free() : false; + } + + function insert_id() + { + return ($id = $this->link->insert_id) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0); + } + + function fetch_row($query) + { + $query = $query ? $query->fetch_row() : null; + return $query; + } + + function fetch_fields($query) + { + return $query ? $query->fetch_field() : null; + } + + function version() + { + return $this->link->server_info; + } + + function escape_string($str) + { + return $this->link->escape_string($str); + } + + function close() + { + return $this->link->close(); + } + + function halt($message = '', $sql = '') + { + $error = $this->error(); + $errorno = $this->errno(); + if ($errorno == 2006 && $this->goneaway-- > 0) + { + $this->connect($this->dbhost, $this->dbuser, $this->dbpw, $this->dbname, $this->dbcharset, $this->pconnect, $this->tablepre, $this->time); + $this->query($sql); + } + else + { + $s = ''; + if ($message) + { + $s = "<b>UCenter info:</b> $message<br />"; + } + if ($sql) + { + $s .= '<b>SQL:</b>' . htmlspecialchars($sql) . '<br />'; + } + $s .= '<b>Error:</b>' . $error . '<br />'; + $s .= '<b>Errno:</b>' . $errorno . '<br />'; + $s = str_replace(UC_DBTABLEPRE, '[Table]', $s); + exit($s); + } + } + +} diff --git a/extend/fast/ucenter/client/uc_client/lib/index.htm b/extend/fast/ucenter/client/uc_client/lib/index.htm new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/lib/index.htm @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extend/fast/ucenter/client/uc_client/lib/sendmail.inc.php b/extend/fast/ucenter/client/uc_client/lib/sendmail.inc.php new file mode 100644 index 0000000..dcc165d --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/lib/sendmail.inc.php @@ -0,0 +1,159 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: sendmail.inc.php 1124 2011-12-06 11:03:23Z svn_project_zhangjie $ + */ +!defined('IN_UC') && exit('Access Denied'); + +if ($mail_setting['mailsilent']) +{ + error_reporting(0); +} + +$maildelimiter = $mail_setting['maildelimiter'] == 1 ? "\r\n" : ($mail_setting['maildelimiter'] == 2 ? "\r" : "\n"); +$mailusername = isset($mail_setting['mailusername']) ? $mail_setting['mailusername'] : 1; +$appname = $this->base->cache['apps'][$mail['appid']]['name']; +$mail['subject'] = '=?' . $mail['charset'] . '?B?' . base64_encode(str_replace("\r", '', str_replace("\n", '', '[' . $appname . '] ' . $mail['subject']))) . '?='; +$mail['message'] = chunk_split(base64_encode(str_replace("\r\n.", " \r\n..", str_replace("\n", "\r\n", str_replace("\r", "\n", str_replace("\r\n", "\n", str_replace("\n\r", "\r", $mail['message']))))))); + +$email_from = $mail['frommail'] == '' ? '=?' . $mail['charset'] . '?B?' . base64_encode($appname) . "?= <$mail_setting[maildefault]>" : (preg_match('/^(.+?) \<(.+?)\>$/', $email_from, $from) ? '=?' . $mail['charset'] . '?B?' . base64_encode($from[1]) . "?= <$from[2]>" : $mail['frommail']); + +foreach (explode(',', $mail['email_to']) as $touser) +{ + $tousers[] = preg_match('/^(.+?) \<(.+?)\>$/', $touser, $to) ? ($mailusername ? '=?' . $mail['charset'] . '?B?' . base64_encode($to[1]) . "?= <$to[2]>" : $to[2]) : $touser; +} + +$mail['email_to'] = implode(',', $tousers); + +$headers = "From: $email_from{$maildelimiter}X-Priority: 3{$maildelimiter}X-Mailer: Discuz! $version{$maildelimiter}MIME-Version: 1.0{$maildelimiter}Content-type: text/" . ($mail['htmlon'] ? 'html' : 'plain') . "; charset=$mail[charset]{$maildelimiter}Content-Transfer-Encoding: base64{$maildelimiter}"; + +$mail_setting['mailport'] = $mail_setting['mailport'] ? $mail_setting['mailport'] : 25; + +if ($mail_setting['mailsend'] == 1 && function_exists('mail')) +{ + + return @mail($mail['email_to'], $mail['subject'], $mail['message'], $headers); +} +elseif ($mail_setting['mailsend'] == 2) +{ + + if (!$fp = fsocketopen($mail_setting['mailserver'], $mail_setting['mailport'], $errno, $errstr, 30)) + { + return false; + } + + stream_set_blocking($fp, true); + + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != '220') + { + return false; + } + + fputs($fp, ($mail_setting['mailauth'] ? 'EHLO' : 'HELO') . " discuz\r\n"); + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != 220 && substr($lastmessage, 0, 3) != 250) + { + return false; + } + + while (1) + { + if (substr($lastmessage, 3, 1) != '-' || empty($lastmessage)) + { + break; + } + $lastmessage = fgets($fp, 512); + } + + if ($mail_setting['mailauth']) + { + fputs($fp, "AUTH LOGIN\r\n"); + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != 334) + { + return false; + } + + fputs($fp, base64_encode($mail_setting['mailauth_username']) . "\r\n"); + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != 334) + { + return false; + } + + fputs($fp, base64_encode($mail_setting['mailauth_password']) . "\r\n"); + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != 235) + { + return false; + } + + $email_from = $mail_setting['mailfrom']; + } + + fputs($fp, "MAIL FROM: <" . preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from) . ">\r\n"); + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != 250) + { + fputs($fp, "MAIL FROM: <" . preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from) . ">\r\n"); + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != 250) + { + return false; + } + } + + $email_tos = array(); + foreach (explode(',', $mail['email_to']) as $touser) + { + $touser = trim($touser); + if ($touser) + { + fputs($fp, "RCPT TO: <" . preg_replace("/.*\<(.+?)\>.*/", "\\1", $touser) . ">\r\n"); + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != 250) + { + fputs($fp, "RCPT TO: <" . preg_replace("/.*\<(.+?)\>.*/", "\\1", $touser) . ">\r\n"); + $lastmessage = fgets($fp, 512); + return false; + } + } + } + + fputs($fp, "DATA\r\n"); + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != 354) + { + return false; + } + + $headers .= 'Message-ID: <' . gmdate('YmdHs') . '.' . substr(md5($mail['message'] . microtime()), 0, 6) . rand(100000, 999999) . '@' . $_SERVER['HTTP_HOST'] . ">{$maildelimiter}"; + + fputs($fp, "Date: " . gmdate('r') . "\r\n"); + fputs($fp, "To: " . $mail['email_to'] . "\r\n"); + fputs($fp, "Subject: " . $mail['subject'] . "\r\n"); + fputs($fp, $headers . "\r\n"); + fputs($fp, "\r\n\r\n"); + fputs($fp, "$mail[message]\r\n.\r\n"); + $lastmessage = fgets($fp, 512); + if (substr($lastmessage, 0, 3) != 250) + { + return false; + } + + fputs($fp, "QUIT\r\n"); + return true; +} +elseif ($mail_setting['mailsend'] == 3) +{ + + ini_set('SMTP', $mail_setting['mailserver']); + ini_set('smtp_port', $mail_setting['mailport']); + ini_set('sendmail_from', $email_from); + + return @mail($mail['email_to'], $mail['subject'], $mail['message'], $headers); +} \ No newline at end of file diff --git a/extend/fast/ucenter/client/uc_client/lib/uccode.class.php b/extend/fast/ucenter/client/uc_client/lib/uccode.class.php new file mode 100644 index 0000000..47150b5 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/lib/uccode.class.php @@ -0,0 +1,174 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: uccode.class.php 1166 2014-11-03 01:49:32Z hypowang $ + */ + +class uccode +{ + + var $uccodes; + + function __construct() + { + $this->uccode(); + } + + function uccode() + { + $this->uccode = array( + 'pcodecount' => -1, + 'codecount' => 0, + 'codehtml' => '' + ); + } + + function codedisp($code) + { + $this->uccode['pcodecount'] ++; + $code = str_replace('\\"', '"', preg_replace("/^[\n\r]*(.+?)[\n\r]*$/is", "\\1", $code)); + $this->uccode['codehtml'][$this->uccode['pcodecount']] = $this->tpl_codedisp($code); + $this->uccode['codecount'] ++; + return "[\tUCENTER_CODE_" . $this->uccode[pcodecount] . "\t]"; + } + + function complie($message) + { + $message = dhtmlspecialchars($message); + if (strpos($message, '[/code]') !== FALSE) + { + $message = preg_replace("/\s*\[code\](.+?)\[\/code\]\s*/ies", "\$this->codedisp('\\1')", $message); + } + if (strpos($message, '[/url]') !== FALSE) + { + $message = preg_replace("/\[url(=((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|ed2k|thunder|synacast){1}:\/\/|www\.)([^\[\"']+?))?\](.+?)\[\/url\]/ies", "\$this->parseurl('\\1', '\\5')", $message); + } + if (strpos($message, '[/email]') !== FALSE) + { + $message = preg_replace("/\[email(=([a-z0-9\-_.+]+)@([a-z0-9\-_]+[.][a-z0-9\-_.]+))?\](.+?)\[\/email\]/ies", "\$this->parseemail('\\1', '\\4')", $message); + } + $message = str_replace(array( + '[/color]', '[/size]', '[/font]', '[/align]', '[b]', '[/b]', + '[i]', '[/i]', '[u]', '[/u]', '[list]', '[list=1]', '[list=a]', + '[list=A]', '[*]', '[/list]', '[indent]', '[/indent]', '[/float]' + ), array( + '</font>', '</font>', '</font>', '</p>', '<strong>', '</strong>', '<i>', + '</i>', '<u>', '</u>', '<ul>', '<ul type="1">', '<ul type="a">', + '<ul type="A">', '<li>', '</ul>', '<blockquote>', '</blockquote>', '</span>' + ), preg_replace(array( + "/\[color=([#\w]+?)\]/i", + "/\[size=(\d+?)\]/i", + "/\[size=(\d+(\.\d+)?(px|pt|in|cm|mm|pc|em|ex|%)+?)\]/i", + "/\[font=([^\[\<]+?)\]/i", + "/\[align=(left|center|right)\]/i", + "/\[float=(left|right)\]/i" + ), array( + "<font color=\"\\1\">", + "<font size=\"\\1\">", + "<font style=\"font-size: \\1\">", + "<font face=\"\\1 \">", + "<p align=\"\\1\">", + "<span style=\"float: \\1;\">" + ), $message)); + if (strpos($message, '[/quote]') !== FALSE) + { + $message = preg_replace("/\s*\[quote\][\n\r]*(.+?)[\n\r]*\[\/quote\]\s*/is", $this->tpl_quote(), $message); + } + if (strpos($message, '[/img]') !== FALSE) + { + $message = preg_replace(array( + "/\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/ies", + "/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/ies" + ), array( + "\$this->bbcodeurl('\\1', '<img src=\"%s\" border=\"0\" alt=\"\" />')", + "\$this->bbcodeurl('\\3', '<img width=\"\\1\" height=\"\\2\" src=\"%s\" border=\"0\" alt=\"\" />')" + ), $message); + } + for ($i = 0; $i <= $this->uccode['pcodecount']; $i++) + { + $message = str_replace("[\tUCENTER_CODE_$i\t]", $this->uccode['codehtml'][$i], $message); + } + return nl2br(str_replace(array("\t", ' ', ' '), array(' ', ' ', ' '), $message)); + } + + function parseurl($url, $text) + { + if (!$url && preg_match("/((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|ed2k|thunder|synacast){1}:\/\/|www\.)[^\[\"']+/i", trim($text), $matches)) + { + $url = $matches[0]; + $length = 65; + if (strlen($url) > $length) + { + $text = substr($url, 0, intval($length * 0.5)) . ' ... ' . substr($url, - intval($length * 0.3)); + } + return '<a href="' . (substr(strtolower($url), 0, 4) == 'www.' ? 'http://' . $url : $url) . '" target="_blank">' . $text . '</a>'; + } + else + { + $url = substr($url, 1); + if (substr(strtolower($url), 0, 4) == 'www.') + { + $url = 'http://' . $url; + } + return '<a href="' . $url . '" target="_blank">' . $text . '</a>'; + } + } + + function parseemail($email, $text) + { + $text = str_replace('\"', '"', $text); + if (!$email && preg_match("/\s*([a-z0-9\-_.+]+)@([a-z0-9\-_]+[.][a-z0-9\-_.]+)\s*/i", $text, $matches)) + { + $email = trim($matches[0]); + return '<a href="mailto:' . $email . '">' . $email . '</a>'; + } + else + { + return '<a href="mailto:' . substr($email, 1) . '">' . $text . '</a>'; + } + } + + function bbcodeurl($url, $tags) + { + if (!preg_match("/<.+?>/s", $url)) + { + if (!in_array(strtolower(substr($url, 0, 6)), array('http:/', 'https:', 'ftp://', 'rtsp:/', 'mms://'))) + { + $url = 'http://' . $url; + } + return str_replace(array('submit', 'logging.php'), array('', ''), sprintf($tags, $url, addslashes($url))); + } + else + { + return ' ' . $url; + } + } + + function tpl_codedisp($code) + { + return '<div class="blockcode"><code id="code' . $this->uccodes['codecount'] . '">' . $code . '</code></div>'; + } + + function tpl_quote() + { + return '<div class="quote"><blockquote>\\1</blockquote></div>'; + } + +} + +/* + +Usage: +$str = <<<EOF +1 +2 +3 +EOF; +require_once 'lib/uccode.class.php'; +$this->uccode = new uccode(); +echo $this->uccode->complie($str); + +*/ \ No newline at end of file diff --git a/extend/fast/ucenter/client/uc_client/lib/xml.class.php b/extend/fast/ucenter/client/uc_client/lib/xml.class.php new file mode 100644 index 0000000..73c528b --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/lib/xml.class.php @@ -0,0 +1,129 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: xml.class.php 1059 2011-03-01 07:25:09Z monkey $ + */ + +function xml_unserialize(&$xml, $isnormal = FALSE) +{ + $xml_parser = new XML($isnormal); + $data = $xml_parser->parse($xml); + $xml_parser->destruct(); + return $data; +} + +function xml_serialize($arr, $htmlon = FALSE, $isnormal = FALSE, $level = 1) +{ + $s = $level == 1 ? "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<root>\r\n" : ''; + $space = str_repeat("\t", $level); + foreach ($arr as $k => $v) + { + if (!is_array($v)) + { + $s .= $space . "<item id=\"$k\">" . ($htmlon ? '<![CDATA[' : '') . $v . ($htmlon ? ']]>' : '') . "</item>\r\n"; + } + else + { + $s .= $space . "<item id=\"$k\">\r\n" . xml_serialize($v, $htmlon, $isnormal, $level + 1) . $space . "</item>\r\n"; + } + } + $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s); + return $level == 1 ? $s . "</root>" : $s; +} + +class XML +{ + + var $parser; + var $document; + var $stack; + var $data; + var $last_opened_tag; + var $isnormal; + var $attrs = array(); + var $failed = FALSE; + + function __construct($isnormal) + { + $this->XML($isnormal); + } + + function XML($isnormal) + { + $this->isnormal = $isnormal; + $this->parser = xml_parser_create('ISO-8859-1'); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false); + xml_set_object($this->parser, $this); + xml_set_element_handler($this->parser, 'open', 'close'); + xml_set_character_data_handler($this->parser, 'data'); + } + + function destruct() + { + xml_parser_free($this->parser); + } + + function parse(&$data) + { + $this->document = array(); + $this->stack = array(); + return xml_parse($this->parser, $data, true) && !$this->failed ? $this->document : ''; + } + + function open(&$parser, $tag, $attributes) + { + $this->data = ''; + $this->failed = FALSE; + if (!$this->isnormal) + { + if (isset($attributes['id']) && !is_string($this->document[$attributes['id']])) + { + $this->document = &$this->document[$attributes['id']]; + } + else + { + $this->failed = TRUE; + } + } + else + { + if (!isset($this->document[$tag]) || !is_string($this->document[$tag])) + { + $this->document = &$this->document[$tag]; + } + else + { + $this->failed = TRUE; + } + } + $this->stack[] = &$this->document; + $this->last_opened_tag = $tag; + $this->attrs = $attributes; + } + + function data(&$parser, $data) + { + if ($this->last_opened_tag != NULL) + { + $this->data .= $data; + } + } + + function close(&$parser, $tag) + { + if ($this->last_opened_tag == $tag) + { + $this->document = $this->data; + $this->last_opened_tag = NULL; + } + array_pop($this->stack); + if ($this->stack) + { + $this->document = &$this->stack[count($this->stack) - 1]; + } + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/app.php b/extend/fast/ucenter/client/uc_client/model/app.php new file mode 100644 index 0000000..a3fdac5 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/app.php @@ -0,0 +1,40 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: app.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class appmodel +{ + + var $db; + var $base; + + function __construct(&$base) + { + $this->appmodel($base); + } + + function appmodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + } + + function get_apps($col = '*', $where = '') + { + $arr = $this->db->fetch_all("SELECT $col FROM " . UC_DBTABLEPRE . "applications" . ($where ? ' WHERE ' . $where : ''), 'appid'); + foreach ($arr as $k => $v) + { + isset($v['extra']) && !empty($v['extra']) && $v['extra'] = unserialize($v['extra']); + unset($v['authkey']); + $arr[$k] = $v; + } + return $arr; + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/base.php b/extend/fast/ucenter/client/uc_client/model/base.php new file mode 100644 index 0000000..32dcf16 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/base.php @@ -0,0 +1,347 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: base.php 1167 2014-11-03 03:06:21Z hypowang $ + */ +!defined('IN_UC') && exit('Access Denied'); + +if (!function_exists('getgpc')) +{ + + function getgpc($k, $var = 'G') + { + switch ($var) + { + case 'G': $var = &$_GET; + break; + case 'P': $var = &$_POST; + break; + case 'C': $var = &$_COOKIE; + break; + case 'R': $var = &$_REQUEST; + break; + } + return isset($var[$k]) ? $var[$k] : NULL; + } + +} + +class base +{ + + var $sid; + var $time; + var $onlineip; + var $db; + var $key; + var $settings = array(); + var $cache = array(); + var $app = array(); + var $user = array(); + var $input = array(); + + function __construct() + { + $this->base(); + } + + function base() + { + $this->init_var(); + $this->init_db(); + $this->init_cache(); + $this->init_note(); + $this->init_mail(); + } + + function init_var() + { + $this->time = time(); + $cip = getenv('HTTP_CLIENT_IP'); + $xip = getenv('HTTP_X_FORWARDED_FOR'); + $rip = getenv('REMOTE_ADDR'); + $srip = $_SERVER['REMOTE_ADDR']; + if ($cip && strcasecmp($cip, 'unknown')) + { + $this->onlineip = $cip; + } + elseif ($xip && strcasecmp($xip, 'unknown')) + { + $this->onlineip = $xip; + } + elseif ($rip && strcasecmp($rip, 'unknown')) + { + $this->onlineip = $rip; + } + elseif ($srip && strcasecmp($srip, 'unknown')) + { + $this->onlineip = $srip; + } + preg_match("/[\d\.]{7,15}/", $this->onlineip, $match); + $this->onlineip = $match[0] ? $match[0] : 'unknown'; + $this->app['appid'] = UC_APPID; + } + + function init_input() + { + + } + + function init_db() + { + if (function_exists("mysqli_connect")) + { + require_once UC_ROOT . 'lib/dbi.class.php'; + } + else + { + require_once UC_ROOT . 'lib/db.class.php'; + } + $this->db = new ucclient_db(); + $this->db->connect(UC_DBHOST, UC_DBUSER, UC_DBPW, '', UC_DBCHARSET, UC_DBCONNECT, UC_DBTABLEPRE); + } + + function load($model, $base = NULL) + { + $base = $base ? $base : $this; + if (empty($_ENV[$model])) + { + require_once UC_ROOT . "./model/{$model}.php"; + $classname = $model . 'model'; + $_ENV[$model] = new $classname($base); + } + return $_ENV[$model]; + } + + function date($time, $type = 3) + { + if (!$this->settings) + { + $this->settings = $this->cache('settings'); + } + $format[] = $type & 2 ? (!empty($this->settings['dateformat']) ? $this->settings['dateformat'] : 'Y-n-j') : ''; + $format[] = $type & 1 ? (!empty($this->settings['timeformat']) ? $this->settings['timeformat'] : 'H:i') : ''; + return gmdate(implode(' ', $format), $time + $this->settings['timeoffset']); + } + + function page_get_start($page, $ppp, $totalnum) + { + $totalpage = ceil($totalnum / $ppp); + $page = max(1, min($totalpage, intval($page))); + return ($page - 1) * $ppp; + } + + function implode($arr) + { + return "'" . implode("','", (array) $arr) . "'"; + } + + function &cache($cachefile) + { + static $_CACHE = array(); + if (!isset($_CACHE[$cachefile])) + { + $cachepath = UC_DATADIR . './cache/' . $cachefile . '.php'; + if (!file_exists($cachepath)) + { + $this->load('cache'); + $_ENV['cache']->updatedata($cachefile); + } + else + { + include_once $cachepath; + } + } + return $_CACHE[$cachefile]; + } + + function get_setting($k = array(), $decode = FALSE) + { + $return = array(); + $sqladd = $k ? "WHERE k IN (" . $this->implode($k) . ")" : ''; + $settings = $this->db->fetch_all("SELECT * FROM " . UC_DBTABLEPRE . "settings $sqladd"); + if (is_array($settings)) + { + foreach ($settings as $arr) + { + $return[$arr['k']] = $decode ? unserialize($arr['v']) : $arr['v']; + } + } + return $return; + } + + function init_cache() + { + $this->settings = $this->cache('settings'); + $this->cache['apps'] = $this->cache('apps'); + + if (PHP_VERSION > '5.1') + { + $timeoffset = intval($this->settings['timeoffset'] / 3600); + @date_default_timezone_set('Etc/GMT' . ($timeoffset > 0 ? '-' : '+') . (abs($timeoffset))); + } + } + + function cutstr($string, $length, $dot = ' ...') + { + if (strlen($string) <= $length) + { + return $string; + } + + $string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string); + + $strcut = ''; + if (strtolower(UC_CHARSET) == 'utf-8') + { + + $n = $tn = $noc = 0; + while ($n < strlen($string)) + { + + $t = ord($string[$n]); + if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) + { + $tn = 1; + $n++; + $noc++; + } + elseif (194 <= $t && $t <= 223) + { + $tn = 2; + $n += 2; + $noc += 2; + } + elseif (224 <= $t && $t < 239) + { + $tn = 3; + $n += 3; + $noc += 2; + } + elseif (240 <= $t && $t <= 247) + { + $tn = 4; + $n += 4; + $noc += 2; + } + elseif (248 <= $t && $t <= 251) + { + $tn = 5; + $n += 5; + $noc += 2; + } + elseif ($t == 252 || $t == 253) + { + $tn = 6; + $n += 6; + $noc += 2; + } + else + { + $n++; + } + + if ($noc >= $length) + { + break; + } + } + if ($noc > $length) + { + $n -= $tn; + } + + $strcut = substr($string, 0, $n); + } + else + { + for ($i = 0; $i < $length; $i++) + { + $strcut .= ord($string[$i]) > 127 ? $string[$i] . $string[++$i] : $string[$i]; + } + } + + $strcut = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $strcut); + + return $strcut . $dot; + } + + function init_note() + { + if ($this->note_exists()) + { + $this->load('note'); + $_ENV['note']->send(); + } + } + + function note_exists() + { + $noteexists = $this->db->result_first("SELECT value FROM " . UC_DBTABLEPRE . "vars WHERE name='noteexists" . UC_APPID . "'"); + if (empty($noteexists)) + { + return FALSE; + } + else + { + return TRUE; + } + } + + function init_mail() + { + if ($this->mail_exists() && !getgpc('inajax')) + { + $this->load('mail'); + $_ENV['mail']->send(); + } + } + + function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) + { + return uc_authcode($string, $operation, $key, $expiry); + } + + function unserialize($s) + { + return uc_unserialize($s); + } + + function input($k) + { + return isset($this->input[$k]) ? (is_array($this->input[$k]) ? $this->input[$k] : trim($this->input[$k])) : NULL; + } + + function mail_exists() + { + $mailexists = $this->db->result_first("SELECT value FROM " . UC_DBTABLEPRE . "vars WHERE name='mailexists'"); + if (empty($mailexists)) + { + return FALSE; + } + else + { + return TRUE; + } + } + + function dstripslashes($string) + { + if (is_array($string)) + { + foreach ($string as $key => $val) + { + $string[$key] = $this->dstripslashes($val); + } + } + else + { + $string = stripslashes($string); + } + return $string; + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/cache.php b/extend/fast/ucenter/client/uc_client/model/cache.php new file mode 100644 index 0000000..d0851ed --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/cache.php @@ -0,0 +1,119 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: cache.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +if (!function_exists('file_put_contents')) +{ + + function file_put_contents($filename, $s) + { + $fp = @fopen($filename, 'w'); + @fwrite($fp, $s); + @fclose($fp); + } + +} + +class cachemodel +{ + + var $db; + var $base; + var $map; + + function __construct(&$base) + { + $this->cachemodel($base); + } + + function cachemodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + $this->map = array( + 'settings' => array('settings'), + 'badwords' => array('badwords'), + 'apps' => array('apps') + ); + } + + function updatedata($cachefile = '') + { + if ($cachefile) + { + foreach ((array) $this->map[$cachefile] as $modules) + { + $s = "<?php\r\n"; + foreach ((array) $modules as $m) + { + $method = "_get_$m"; + $s .= '$_CACHE[\'' . $m . '\'] = ' . var_export($this->$method(), TRUE) . ";\r\n"; + } + $s .= "\r\n?>"; + @file_put_contents(UC_DATADIR . "./cache/$cachefile.php", $s); + } + } + else + { + foreach ((array) $this->map as $file => $modules) + { + $s = "<?php\r\n"; + foreach ($modules as $m) + { + $method = "_get_$m"; + $s .= '$_CACHE[\'' . $m . '\'] = ' . var_export($this->$method(), TRUE) . ";\r\n"; + } + $s .= "\r\n?>"; + @file_put_contents(UC_DATADIR . "./cache/$file.php", $s); + } + } + } + + function updatetpl() + { + + } + + function _get_badwords() + { + $data = $this->db->fetch_all("SELECT * FROM " . UC_DBTABLEPRE . "badwords"); + $return = array(); + if (is_array($data)) + { + foreach ($data as $k => $v) + { + $return['findpattern'][$k] = $v['findpattern']; + $return['replace'][$k] = $v['replacement']; + } + } + return $return; + } + + function _get_apps() + { + $this->base->load('app'); + $apps = $_ENV['app']->get_apps(); + $apps2 = array(); + if (is_array($apps)) + { + foreach ($apps as $v) + { + $v['extra'] = unserialize($v['extra']); + $apps2[$v['appid']] = $v; + } + } + return $apps2; + } + + function _get_settings() + { + return $this->base->get_setting(); + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/domain.php b/extend/fast/ucenter/client/uc_client/model/domain.php new file mode 100644 index 0000000..6fc966f --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/domain.php @@ -0,0 +1,63 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: domain.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class domainmodel +{ + + var $db; + var $base; + + function __construct(&$base) + { + $this->domainmodel($base); + } + + function domainmodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + } + + function add_domain($domain, $ip) + { + if ($domain) + { + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "domains SET domain='$domain', ip='$ip'"); + } + return $this->db->insert_id(); + } + + function get_total_num() + { + $data = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "domains"); + return $data; + } + + function get_list($page, $ppp, $totalnum) + { + $start = $this->base->page_get_start($page, $ppp, $totalnum); + $data = $this->db->fetch_all("SELECT * FROM " . UC_DBTABLEPRE . "domains LIMIT $start, $ppp"); + return $data; + } + + function delete_domain($arr) + { + $domainids = $this->base->implode($arr); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "domains WHERE id IN ($domainids)"); + return $this->db->affected_rows(); + } + + function update_domain($domain, $ip, $id) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "domains SET domain='$domain', ip='$ip' WHERE id='$id'"); + return $this->db->affected_rows(); + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/friend.php b/extend/fast/ucenter/client/uc_client/model/friend.php new file mode 100644 index 0000000..58c641a --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/friend.php @@ -0,0 +1,148 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: friend.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class friendmodel +{ + + var $db; + var $base; + + function __construct(&$base) + { + $this->friendmodel($base); + } + + function friendmodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + } + + function add($uid, $friendid, $comment = '') + { + $direction = $this->db->result_first("SELECT direction FROM " . UC_DBTABLEPRE . "friends WHERE uid='$friendid' AND friendid='$uid' LIMIT 1"); + if ($direction == 1) + { + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "friends SET uid='$uid', friendid='$friendid', comment='$comment', direction='3'", 'SILENT'); + $this->db->query("UPDATE " . UC_DBTABLEPRE . "friends SET direction='3' WHERE uid='$friendid' AND friendid='$uid'"); + return 1; + } + elseif ($direction == 2) + { + return 1; + } + elseif ($direction == 3) + { + return -1; + } + else + { + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "friends SET uid='$uid', friendid='$friendid', comment='$comment', direction='1'", 'SILENT'); + return $this->db->insert_id(); + } + } + + function delete($uid, $friendids) + { + $friendids = $this->base->implode($friendids); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "friends WHERE uid='$uid' AND friendid IN ($friendids)"); + $affectedrows = $this->db->affected_rows(); + if ($affectedrows > 0) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "friends SET direction=1 WHERE uid IN ($friendids) AND friendid='$uid' AND direction='3'"); + } + return $affectedrows; + } + + function get_totalnum_by_uid($uid, $direction = 0) + { + $sqladd = ''; + if ($direction == 0) + { + $sqladd = "uid='$uid'"; + } + elseif ($direction == 1) + { + $sqladd = "uid='$uid' AND direction='1'"; + } + elseif ($direction == 2) + { + $sqladd = "friendid='$uid' AND direction='1'"; + } + elseif ($direction == 3) + { + $sqladd = "uid='$uid' AND direction='3'"; + } + $totalnum = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "friends WHERE $sqladd"); + return $totalnum; + } + + function get_list($uid, $page, $pagesize, $totalnum, $direction = 0) + { + $start = $this->base->page_get_start($page, $pagesize, $totalnum); + $sqladd = ''; + if ($direction == 0) + { + $sqladd = "f.uid='$uid'"; + } + elseif ($direction == 1) + { + $sqladd = "f.uid='$uid' AND f.direction='1'"; + } + elseif ($direction == 2) + { + $sqladd = "f.friendid='$uid' AND f.direction='1'"; + } + elseif ($direction == 3) + { + $sqladd = "f.uid='$uid' AND f.direction='3'"; + } + if ($sqladd) + { + $data = $this->db->fetch_all("SELECT f.*, m.username FROM " . UC_DBTABLEPRE . "friends f LEFT JOIN " . UC_DBTABLEPRE . "members m ON f.friendid=m.uid WHERE $sqladd LIMIT $start, $pagesize"); + return $data; + } + else + { + return array(); + } + } + + function is_friend($uid, $friendids, $direction = 0) + { + $friendid_str = implode("', '", $friendids); + $sqladd = ''; + if ($direction == 0) + { + $sqladd = "uid='$uid'"; + } + elseif ($direction == 1) + { + $sqladd = "uid='$uid' AND friendid IN ('$friendid_str') AND direction='1'"; + } + elseif ($direction == 2) + { + $sqladd = "friendid='$uid' AND uid IN ('$friendid_str') AND direction='1'"; + } + elseif ($direction == 3) + { + $sqladd = "uid='$uid' AND friendid IN ('$friendid_str') AND direction='3'"; + } + if ($this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "friends WHERE $sqladd") == count($friendids)) + { + return true; + } + else + { + return false; + } + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/index.htm b/extend/fast/ucenter/client/uc_client/model/index.htm new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/index.htm @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extend/fast/ucenter/client/uc_client/model/mail.php b/extend/fast/ucenter/client/uc_client/model/mail.php new file mode 100644 index 0000000..46e9983 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/mail.php @@ -0,0 +1,181 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: mail.php 1139 2012-05-08 09:02:11Z liulanbo $ + */ +!defined('IN_UC') && exit('Access Denied'); + +define('UC_MAIL_REPEAT', 5); + +class mailmodel +{ + + var $db; + var $base; + var $apps; + + function __construct(&$base) + { + $this->mailmodel($base); + } + + function mailmodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + $this->apps = &$this->base->cache['apps']; + } + + function get_total_num() + { + $data = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "mailqueue"); + return $data; + } + + function get_list($page, $ppp, $totalnum) + { + $start = $this->base->page_get_start($page, $ppp, $totalnum); + $data = $this->db->fetch_all("SELECT m.*, u.username, u.email FROM " . UC_DBTABLEPRE . "mailqueue m LEFT JOIN " . UC_DBTABLEPRE . "members u ON m.touid=u.uid ORDER BY dateline DESC LIMIT $start, $ppp"); + foreach ((array) $data as $k => $v) + { + $data[$k]['subject'] = dhtmlspecialchars($v['subject']); + $data[$k]['tomail'] = empty($v['tomail']) ? $v['email'] : $v['tomail']; + $data[$k]['dateline'] = $v['dateline'] ? $this->base->date($data[$k]['dateline']) : ''; + $data[$k]['appname'] = $this->base->cache['apps'][$v['appid']]['name']; + } + return $data; + } + + function delete_mail($ids) + { + $ids = $this->base->implode($ids); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "mailqueue WHERE mailid IN ($ids)"); + return $this->db->affected_rows(); + } + + function add($mail) + { + if ($mail['level']) + { + $sql = "INSERT INTO " . UC_DBTABLEPRE . "mailqueue (touid, tomail, subject, message, frommail, charset, htmlon, level, dateline, failures, appid) VALUES "; + $values_arr = array(); + foreach ($mail['uids'] as $uid) + { + if (empty($uid)) + continue; + $values_arr[] = "('$uid', '', '$mail[subject]', '$mail[message]', '$mail[frommail]', '$mail[charset]', '$mail[htmlon]', '$mail[level]', '$mail[dateline]', '0', '$mail[appid]')"; + } + foreach ($mail['emails'] as $email) + { + if (empty($email)) + continue; + $values_arr[] = "('', '$email', '$mail[subject]', '$mail[message]', '$mail[frommail]', '$mail[charset]', '$mail[htmlon]', '$mail[level]', '$mail[dateline]', '0', '$mail[appid]')"; + } + $sql .= implode(',', $values_arr); + $this->db->query($sql); + $insert_id = $this->db->insert_id(); + $insert_id && $this->db->query("REPLACE INTO " . UC_DBTABLEPRE . "vars SET name='mailexists', value='1'"); + return $insert_id; + } else + { + $mail['email_to'] = array(); + $uids = 0; + foreach ($mail['uids'] as $uid) + { + if (empty($uid)) + continue; + $uids .= ',' . $uid; + } + $users = $this->db->fetch_all("SELECT uid, username, email FROM " . UC_DBTABLEPRE . "members WHERE uid IN ($uids)"); + foreach ($users as $v) + { + $mail['email_to'][] = $v['username'] . '<' . $v['email'] . '>'; + } + foreach ($mail['emails'] as $email) + { + if (empty($email)) + continue; + $mail['email_to'][] = $email; + } + $mail['message'] = str_replace('\"', '"', $mail['message']); + $mail['email_to'] = implode(',', $mail['email_to']); + return $this->send_one_mail($mail); + } + } + + function send() + { + register_shutdown_function(array($this, '_send')); + } + + function _send() + { + + $mail = $this->_get_mail(); + if (empty($mail)) + { + $this->db->query("REPLACE INTO " . UC_DBTABLEPRE . "vars SET name='mailexists', value='0'"); + return NULL; + } + else + { + $mail['email_to'] = $mail['tomail'] ? $mail['tomail'] : $mail['username'] . '<' . $mail['email'] . '>'; + if ($this->send_one_mail($mail)) + { + $this->_delete_one_mail($mail['mailid']); + return true; + } + else + { + $this->_update_failures($mail['mailid']); + return false; + } + } + } + + function send_by_id($mailid) + { + if ($this->send_one_mail($this->_get_mail_by_id($mailid))) + { + $this->_delete_one_mail($mailid); + return true; + } + } + + function send_one_mail($mail) + { + if (empty($mail)) + return; + $mail['email_to'] = $mail['email_to'] ? $mail['email_to'] : $mail['username'] . '<' . $mail['email'] . '>'; + $mail_setting = $this->base->settings; + return include UC_ROOT . 'lib/sendmail.inc.php'; + } + + function _get_mail() + { + $data = $this->db->fetch_first("SELECT m.*, u.username, u.email FROM " . UC_DBTABLEPRE . "mailqueue m LEFT JOIN " . UC_DBTABLEPRE . "members u ON m.touid=u.uid WHERE failures<'" . UC_MAIL_REPEAT . "' ORDER BY level DESC, mailid ASC LIMIT 1"); + return $data; + } + + function _get_mail_by_id($mailid) + { + $data = $this->db->fetch_first("SELECT m.*, u.username, u.email FROM " . UC_DBTABLEPRE . "mailqueue m LEFT JOIN " . UC_DBTABLEPRE . "members u ON m.touid=u.uid WHERE mailid='$mailid'"); + return $data; + } + + function _delete_one_mail($mailid) + { + $mailid = intval($mailid); + return $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "mailqueue WHERE mailid='$mailid'"); + } + + function _update_failures($mailid) + { + $mailid = intval($mailid); + return $this->db->query("UPDATE " . UC_DBTABLEPRE . "mailqueue SET failures=failures+1 WHERE mailid='$mailid'"); + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/misc.php b/extend/fast/ucenter/client/uc_client/model/misc.php new file mode 100644 index 0000000..bb83ab5 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/misc.php @@ -0,0 +1,198 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: misc.php 1182 2014-11-17 08:57:52Z andyzheng $ + */ +!defined('IN_UC') && exit('Access Denied'); + +define('UC_ARRAY_SEP_1', 'UC_ARRAY_SEP_1'); +define('UC_ARRAY_SEP_2', 'UC_ARRAY_SEP_2'); + +class miscmodel +{ + + var $db; + var $base; + + function __construct(&$base) + { + $this->miscmodel($base); + } + + function miscmodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + } + + function get_apps($col = '*', $where = '') + { + $arr = $this->db->fetch_all("SELECT $col FROM " . UC_DBTABLEPRE . "applications" . ($where ? ' WHERE ' . $where : '')); + return $arr; + } + + function delete_apps($appids) + { + + } + + function update_app($appid, $name, $url, $authkey, $charset, $dbcharset) + { + + } + + function alter_app_table($appid, $operation = 'ADD') + { + + } + + function get_host_by_url($url) + { + + } + + function check_url($url) + { + + } + + function check_ip($url) + { + + } + + function test_api($url, $ip = '') + { + + } + + function dfopen2($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE, $encodetype = 'URLENCODE') + { + $__times__ = isset($_GET['__times__']) ? intval($_GET['__times__']) + 1 : 1; + if ($__times__ > 2) + { + return ''; + } + $url .= (strpos($url, '?') === FALSE ? '?' : '&') . "__times__=$__times__"; + return $this->dfopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block, $encodetype); + } + + function dfopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE, $encodetype = 'URLENCODE') + { + $return = ''; + $matches = parse_url($url); + $scheme = $matches['scheme']; + $host = $matches['host']; + $path = $matches['path'] ? $matches['path'] . ($matches['query'] ? '?' . $matches['query'] : '') : '/'; + $port = !empty($matches['port']) ? $matches['port'] : 80; + + if ($post) + { + $out = "POST $path HTTP/1.0\r\n"; + $header = "Accept: */*\r\n"; + $header .= "Accept-Language: zh-cn\r\n"; + $boundary = $encodetype == 'URLENCODE' ? '' : ';' . substr($post, 0, trim(strpos($post, "\n"))); + $header .= $encodetype == 'URLENCODE' ? "Content-Type: application/x-www-form-urlencoded\r\n" : "Content-Type: multipart/form-data$boundary\r\n"; + $header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n"; + $header .= "Host: $host:$port\r\n"; + $header .= 'Content-Length: ' . strlen($post) . "\r\n"; + $header .= "Connection: Close\r\n"; + $header .= "Cache-Control: no-cache\r\n"; + $header .= "Cookie: $cookie\r\n\r\n"; + $out .= $header . $post; + } + else + { + $out = "GET $path HTTP/1.0\r\n"; + $header = "Accept: */*\r\n"; + $header .= "Accept-Language: zh-cn\r\n"; + $header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n"; + $header .= "Host: $host:$port\r\n"; + $header .= "Connection: Close\r\n"; + $header .= "Cookie: $cookie\r\n\r\n"; + $out .= $header; + } + + $fpflag = 0; + if (!$fp = @fsocketopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout)) + { + $context = array( + 'http' => array( + 'method' => $post ? 'POST' : 'GET', + 'header' => $header, + 'content' => $post, + 'timeout' => $timeout, + ), + ); + $context = stream_context_create($context); + $fp = @fopen($scheme . '://' . ($ip ? $ip : $host) . ':' . $port . $path, 'b', false, $context); + $fpflag = 1; + } + + if (!$fp) + { + return ''; + } + else + { + stream_set_blocking($fp, $block); + stream_set_timeout($fp, $timeout); + @fwrite($fp, $out); + $status = stream_get_meta_data($fp); + if (!$status['timed_out']) + { + while (!feof($fp) && !$fpflag) + { + if (($header = @fgets($fp)) && ($header == "\r\n" || $header == "\n")) + { + break; + } + } + + $stop = false; + while (!feof($fp) && !$stop) + { + $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit)); + $return .= $data; + if ($limit) + { + $limit -= strlen($data); + $stop = $limit <= 0; + } + } + } + @fclose($fp); + return $return; + } + } + + function array2string($arr) + { + $s = $sep = ''; + if ($arr && is_array($arr)) + { + foreach ($arr as $k => $v) + { + $s .= $sep . addslashes($k) . UC_ARRAY_SEP_1 . $v; + $sep = UC_ARRAY_SEP_2; + } + } + return $s; + } + + function string2array($s) + { + $arr = explode(UC_ARRAY_SEP_2, $s); + $arr2 = array(); + foreach ($arr as $k => $v) + { + list($key, $val) = explode(UC_ARRAY_SEP_1, $v); + $arr2[$key] = $val; + } + return $arr2; + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/note.php b/extend/fast/ucenter/client/uc_client/model/note.php new file mode 100644 index 0000000..0ca5141 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/note.php @@ -0,0 +1,230 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: note.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +define('UC_NOTE_REPEAT', 5); +define('UC_NOTE_TIMEOUT', 15); +define('UC_NOTE_GC', 10000); + +define('API_RETURN_FAILED', '-1'); + +class notemodel +{ + + var $db; + var $base; + var $apps; + var $noteid; + var $operations = array(); + var $notetype = 'HTTP'; + + function __construct(&$base) + { + $this->notemodel($base); + } + + function notemodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + $this->apps = $this->base->cache('apps'); + $this->operations = array( + 'test' => array('', 'action=test'), + 'deleteuser' => array('', 'action=deleteuser'), + 'deletefriend' => array('', 'action=deletefriend'), + 'gettag' => array('', 'action=gettag', 'tag', 'updatedata'), + 'getcreditsettings' => array('', 'action=getcreditsettings'), + 'getcredit' => array('', 'action=getcredit'), + 'updatecreditsettings' => array('', 'action=updatecreditsettings'), + 'updateclient' => array('', 'action=updateclient'), + 'updatepw' => array('', 'action=updatepw'), + 'updateinfo' => array('', 'action=updateinfo'), + 'updatebadwords' => array('', 'action=updatebadwords'), + 'updatehosts' => array('', 'action=updatehosts'), + 'updateapps' => array('', 'action=updateapps'), + 'updatecredit' => array('', 'action=updatecredit'), + ); + } + + function get_total_num($all = TRUE) + { + + } + + function get_list($page, $ppp, $totalnum, $all = TRUE) + { + + } + + function delete_note($ids) + { + + } + + function add($operation, $getdata = '', $postdata = '', $appids = array(), $pri = 0) + { + $extra = $varextra = ''; + $appadd = $varadd = array(); + foreach ((array) $this->apps as $appid => $app) + { + $appid = $app['appid']; + if ($appid == intval($appid)) + { + if ($appids && !in_array($appid, $appids)) + { + $appadd[] = 'app' . $appid . "='1'"; + } + else + { + $varadd[] = "('noteexists{$appid}', '1')"; + } + } + } + if ($appadd) + { + $extra = implode(',', $appadd); + $extra = $extra ? ', ' . $extra : ''; + } + if ($varadd) + { + $varextra = implode(', ', $varadd); + $varextra = $varextra ? ', ' . $varextra : ''; + } + + $getdata = addslashes($getdata); + $postdata = addslashes($postdata); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "notelist SET getdata='$getdata', operation='$operation', pri='$pri', postdata='$postdata'$extra"); + $insert_id = $this->db->insert_id(); + $insert_id && $this->db->query("REPLACE INTO " . UC_DBTABLEPRE . "vars (name, value) VALUES ('noteexists', '1')$varextra"); + $this->noteid = $insert_id; + return $insert_id; + } + + function send() + { + register_shutdown_function(array($this, '_send')); + } + + function _send() + { + $note = $this->_get_note(); + if (empty($note)) + { + $this->db->query("REPLACE INTO " . UC_DBTABLEPRE . "vars SET name='noteexists" . UC_APPID . "', value='0'"); + return NULL; + } + $this->sendone(UC_APPID, 0, $note); + $this->_gc(); + } + + function sendone($appid, $noteid = 0, $note = '') + { + require_once UC_ROOT . './lib/xml.class.php'; + $return = FALSE; + $app = $this->apps[$appid]; + if ($noteid) + { + $note = $this->_get_note_by_id($noteid); + } + $this->base->load('misc'); + $apifilename = isset($app['apifilename']) && $app['apifilename'] ? $app['apifilename'] : 'uc.php'; + if ($app['extra']['apppath'] && @include $app['extra']['apppath'] . './api/' . $apifilename) + { + $uc_note = new uc_note(); + $method = $note['operation']; + if (is_string($method) && !empty($method)) + { + parse_str($note['getdata'], $note['getdata']); + if (get_magic_quotes_gpc()) + { + $note['getdata'] = $this->base->dstripslashes($note['getdata']); + } + $note['postdata'] = @xml_unserialize($note['postdata']); + $response = $uc_note->$method($note['getdata'], $note['postdata']); + } + unset($uc_note); + } + else + { + $url = $this->get_url_code($note['operation'], $note['getdata'], $appid); + $note['postdata'] = str_replace(array("\n", "\r"), '', $note['postdata']); + $response = trim($_ENV['misc']->dfopen2($url, 0, $note['postdata'], '', 1, $app['ip'], UC_NOTE_TIMEOUT, TRUE)); + } + + $returnsucceed = $response != '' && ($response == 1 || is_array(@xml_unserialize($response))); + + $closedsqladd = $this->_close_note($note, $this->apps, $returnsucceed, $appid) ? ",closed='1'" : ''; + + if ($returnsucceed) + { + if ($this->operations[$note['operation']][2]) + { + $this->base->load($this->operations[$note['operation']][2]); + $func = $this->operations[$note['operation']][3]; + $_ENV[$this->operations[$note['operation']][2]]->$func($appid, $response); + } + $this->db->query("UPDATE " . UC_DBTABLEPRE . "notelist SET app$appid='1', totalnum=totalnum+1, succeednum=succeednum+1, dateline='{$this->base->time}' $closedsqladd WHERE noteid='$note[noteid]'", 'SILENT'); + $return = TRUE; + } + else + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "notelist SET app$appid = app$appid-'1', totalnum=totalnum+1, dateline='{$this->base->time}' $closedsqladd WHERE noteid='$note[noteid]'", 'SILENT'); + $return = FALSE; + } + return $return; + } + + function _get_note() + { + $app_field = 'app' . UC_APPID; + $data = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "notelist WHERE closed='0' AND $app_field<'1' AND $app_field>'-" . UC_NOTE_REPEAT . "' LIMIT 1"); + return $data; + } + + function _gc() + { + rand(0, UC_NOTE_GC) == 0 && $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "notelist WHERE closed='1'"); + } + + function _close_note($note, $apps, $returnsucceed, $appid) + { + $note['app' . $appid] = $returnsucceed ? 1 : $note['app' . $appid] - 1; + $appcount = count($apps); + foreach ($apps as $key => $app) + { + $appstatus = $note['app' . $app['appid']]; + if (!$app['recvnote'] || $appstatus == 1 || $appstatus <= -UC_NOTE_REPEAT) + { + $appcount--; + } + } + if ($appcount < 1) + { + return TRUE; + } + } + + function _get_note_by_id($noteid) + { + $data = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "notelist WHERE noteid='$noteid'"); + return $data; + } + + function get_url_code($operation, $getdata, $appid) + { + $app = $this->apps[$appid]; + $authkey = UC_KEY; + $url = $app['url']; + $apifilename = isset($app['apifilename']) && $app['apifilename'] ? $app['apifilename'] : 'uc.php'; + $action = $this->operations[$operation][1]; + $code = urlencode($this->base->authcode("$action&" . ($getdata ? "$getdata&" : '') . "time=" . $this->base->time, 'ENCODE', $authkey)); + return $url . "/api/$apifilename?code=$code"; + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/pm.php b/extend/fast/ucenter/client/uc_client/model/pm.php new file mode 100644 index 0000000..672ec0f --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/pm.php @@ -0,0 +1,1261 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: pm.php 1160 2013-10-24 08:04:45Z jeffjzhang $ + */ +!defined('IN_UC') && exit('Access Denied'); + +define('PMINBALCKLIST_ERROR', -6); +define('PMSENDSELF_ERROR', -8); +define('PMSENDNONE_ERROR', -9); +define('PMSENDCHATNUM_ERROR', -10); +define('PMTHREADNONE_ERROR', -11); +define('PMPRIVILEGENONE_ERROR', -12); +define('PMCHATTYPE_ERROR', -13); +define('PMUIDTYPE_ERROR', -14); +define('PMDATA_ERROR', -15); + +class pmmodel +{ + + var $db; + var $base; + + function __construct(&$base) + { + $this->pmmodel($base); + } + + function pmmodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + } + + function pmintval($pmid) + { + return @is_numeric($pmid) ? $pmid : 0; + } + + function getpmbypmid($uid, $pmid) + { + if (!$pmid) + { + return array(); + } + $arr = array(); + $pm = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "pm_indexes i LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON t.plid=i.plid WHERE i.pmid='$pmid'"); + if ($this->isprivilege($pm['plid'], $uid)) + { + $pms = $this->db->fetch_all("SELECT t.*, p.*, t.authorid as founderuid, t.dateline as founddateline FROM " . UC_DBTABLEPRE . $this->getposttablename($pm['plid']) . " p LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON t.plid=p.plid WHERE p.pmid='$pm[pmid]'"); + $arr = $this->getpostlist($pms); + } + return $arr; + } + + function isprivilege($plid, $uid) + { + if (!$plid || !$uid) + { + return true; + } + $query = $this->db->query("SELECT * FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$plid' AND uid='$uid'"); + if ($this->db->fetch_array($query)) + { + return true; + } + else + { + return false; + } + } + + function getpmbyplid($uid, $plid, $starttime, $endtime, $start, $ppp, $type = 0) + { + if (!$type) + { + $pm = $this->getprivatepmbyplid($uid, $plid, $starttime, $endtime, $start, $ppp); + } + else + { + $pm = $this->getchatpmbyplid($uid, $plid, $starttime, $endtime, $start, $ppp); + } + return $this->getpostlist($pm); + } + + function getpostlist($list) + { + if (empty($list)) + { + return array(); + } + $authoridarr = $authorarr = array(); + foreach ($list as $key => $value) + { + $authoridarr[$value['authorid']] = $value['authorid']; + } + if ($authoridarr) + { + $this->base->load('user'); + $authorarr = $_ENV['user']->id2name($authoridarr); + } + foreach ($list as $key => $value) + { + if ($value['pmtype'] == 1) + { + $users = explode('_', $value['min_max']); + if ($value['authorid'] == $users[0]) + { + $value['touid'] = $users[1]; + } + else + { + $value['touid'] = $users[0]; + } + } + else + { + $value['touid'] = 0; + } + $value['author'] = $authorarr[$value['authorid']]; + + $value['msgfromid'] = $value['authorid']; + $value['msgfrom'] = $value['author']; + $value['msgtoid'] = $value['touid']; + + unset($value['min_max']); + unset($value['delstatus']); + unset($value['lastmessage']); + $list[$key] = $value; + } + return $list; + } + + function setpmstatus($uid, $touids, $plids, $status = 0) + { + if (!$uid) + { + return false; + } + if (!$status) + { + $oldstatus = 1; + $newstatus = 0; + } + else + { + $oldstatus = 0; + $newstatus = 1; + } + if ($touids) + { + foreach ($touids as $key => $value) + { + if ($uid == $value || !$value) + { + return false; + } + $relastionship[] = $this->relationship($uid, $value); + } + $plid = $plidpostarr = array(); + $query = $this->db->query("SELECT plid FROM " . UC_DBTABLEPRE . "pm_lists WHERE min_max IN (" . $this->base->implode($relationship) . ")"); + while ($thread = $this->db->fetch_array($query)) + { + $plidarr[] = $thread['plid']; + } + if ($plidarr) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew='$newstatus' WHERE plid IN (" . $this->base->implode($plidarr) . ") AND uid='$uid' AND isnew='$oldstatus'"); + } + } + if ($plids) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew='$newstatus' WHERE plid IN (" . $this->base->implode($plids) . ") AND uid='$uid' AND isnew='$oldstatus'"); + } + return true; + } + + function set_ignore($uid) + { + return $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "newpm WHERE uid='$uid'"); + } + + function isnewpm($uid) + { + return $this->db->result_first("SELECT uid FROM " . UC_DBTABLEPRE . "newpm WHERE uid='$uid'"); + } + + function lastpm($uid) + { + $lastpm = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "pm_members m LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON m.plid=t.plid WHERE m.uid='$uid' ORDER BY m.lastdateline DESC LIMIT 1"); + $lastmessage = unserialize($lastpm['lastmessage']); + if ($lastmessage['lastauthorid']) + { + $lastpm['lastauthorid'] = $lastmessage['lastauthorid']; + $lastpm['lastauthor'] = $lastmessage['lastauthor']; + $lastpm['lastsummary'] = $lastmessage['lastsummary']; + } + else + { + $lastpm['lastauthorid'] = $lastmessage['firstauthorid']; + $lastpm['lastauthor'] = $lastmessage['firstauthor']; + $lastpm['lastsummary'] = $lastmessage['firstsummary']; + } + return $lastpm; + } + + function getpmnum($uid, $type = 0, $isnew = 0) + { + $newsql = ''; + $newnum = 0; + + if ($isnew) + { + $newsql = 'AND m.isnew=1'; + } + if (!$type) + { + $newnum = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "pm_members m WHERE m.uid='$uid' $newsql"); + } + else + { + $newnum = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "pm_members m LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON t.plid=m.plid WHERE m.uid='$uid' $newsql AND t.pmtype='$type'"); + } + return $newnum; + } + + function getpmnumbyplid($uid, $plid) + { + return $this->db->result_first("SELECT pmnum FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$plid' AND uid='$uid'"); + } + + function sendpm($fromuid, $fromusername, $touids, $subject, $message, $type = 0) + { + if (!$fromuid || !$fromusername || !$touids || !$message) + { + return 0; + } + $touids = array_unique($touids); + $relationship = $existplid = $pm_member_insertsql = array(); + $this->base->load('user'); + $tmptouidarr = $touids; + $blackls = $this->get_blackls($fromuid, $touids); + + foreach ($tmptouidarr as $key => $value) + { + if ($fromuid == $value || !$value) + { + return PMSENDSELF_ERROR; + } + + if (in_array('{ALL}', $blackls[$value])) + { + unset($touids[$key]); + continue; + } + $blackls[$value] = $_ENV['user']->name2id($blackls[$value]); + if (!(isset($blackls[$value]) && !in_array($fromuid, $blackls[$value]))) + { + unset($touids[$key]); + } + else + { + $relationship[$value] = $this->relationship($fromuid, $value); + } + } + if (empty($touids)) + { + return PMSENDNONE_ERROR; + } + if ($type == 1 && count($touids) < 2) + { + return PMSENDCHATNUM_ERROR; + } + + $_CACHE['badwords'] = $this->base->cache('badwords'); + if ($_CACHE['badwords']['findpattern']) + { + $subject = @preg_replace($_CACHE['badwords']['findpattern'], $_CACHE['badwords']['replace'], $subject); + $message = @preg_replace($_CACHE['badwords']['findpattern'], $_CACHE['badwords']['replace'], $message); + } + if (!$subject) + { + $subject = $this->removecode(trim($message), 80); + } + else + { + $subject = dhtmlspecialchars($subject); + } + $lastsummary = $this->removecode(trim(stripslashes($message)), 150); + + if (!$type) + { + $query = $this->db->query("SELECT plid, min_max FROM " . UC_DBTABLEPRE . "pm_lists WHERE min_max IN (" . $this->base->implode($relationship) . ")"); + while ($thread = $this->db->fetch_array($query)) + { + $existplid[$thread['min_max']] = $thread['plid']; + } + $lastmessage = array('lastauthorid' => $fromuid, 'lastauthor' => $fromusername, 'lastsummary' => $lastsummary); + $lastmessage = addslashes(serialize($lastmessage)); + foreach ($relationship as $key => $value) + { + if (!isset($existplid[$value])) + { + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_lists(authorid, pmtype, subject, members, min_max, dateline, lastmessage) VALUES('$fromuid', '1', '$subject', 2, '$value', '" . $this->base->time . "', '$lastmessage')"); + $plid = $this->db->insert_id(); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_indexes(plid) VALUES('$plid')"); + $pmid = $this->db->insert_id(); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . $this->getposttablename($plid) . "(pmid, plid, authorid, message, dateline, delstatus) VALUES('$pmid', '$plid', '$fromuid', '$message', '" . $this->base->time . "', 0)"); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_members(plid, uid, isnew, pmnum, lastupdate, lastdateline) VALUES('$plid', '$key', '1', '1', '0', '" . $this->base->time . "')"); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_members(plid, uid, isnew, pmnum, lastupdate, lastdateline) VALUES('$plid', '$fromuid', '0', '1', '" . $this->base->time . "', '" . $this->base->time . "')"); + } + else + { + $plid = $existplid[$value]; + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_indexes(plid) VALUES('$plid')"); + $pmid = $this->db->insert_id(); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . $this->getposttablename($plid) . "(pmid, plid, authorid, message, dateline, delstatus) VALUES('$pmid', '$plid', '$fromuid', '$message', '" . $this->base->time . "', 0)"); + $result = $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_members(plid, uid, isnew, pmnum, lastupdate, lastdateline) VALUES('$plid', '$key', '1', '1', '0', '" . $this->base->time . "')", 'SILENT'); + if (!$result) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew=1, pmnum=pmnum+1, lastdateline='" . $this->base->time . "' WHERE plid='$plid' AND uid='$key'"); + } + $result = $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_members(plid, uid, isnew, pmnum, lastupdate, lastdateline) VALUES('$plid', '$fromuid', '0', '1', '" . $this->base->time . "', '" . $this->base->time . "')", 'SILENT'); + if (!$result) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew=0, pmnum=pmnum+1, lastupdate='" . $this->base->time . "', lastdateline='" . $this->base->time . "' WHERE plid='$plid' AND uid='$fromuid'"); + } + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_lists SET lastmessage='$lastmessage' WHERE plid='$plid'"); + } + } + } + else + { + $lastmessage = array('firstauthorid' => $fromuid, 'firstauthor' => $fromusername, 'firstsummary' => $lastsummary); + $lastmessage = addslashes(serialize($lastmessage)); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_lists(authorid, pmtype, subject, members, min_max, dateline, lastmessage) VALUES('$fromuid', '2', '$subject', '" . (count($touids) + 1) . "', '', '" . $this->base->time . "', '$lastmessage')"); + $plid = $this->db->insert_id(); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_indexes(plid) VALUES('$plid')"); + $pmid = $this->db->insert_id(); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . $this->getposttablename($plid) . "(pmid, plid, authorid, message, dateline, delstatus) VALUES('$pmid', '$plid', '$fromuid', '$message', '" . $this->base->time . "', 0)"); + $pm_member_insertsql[] = "('$plid', '$fromuid', '0', '1', '" . $this->base->time . "', '" . $this->base->time . "')"; + foreach ($touids as $key => $value) + { + $pm_member_insertsql[] = "('$plid', '$value', '1', '1', '0', '" . $this->base->time . "')"; + } + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_members(plid, uid, isnew, pmnum, lastupdate, lastdateline) VALUES " . implode(',', $pm_member_insertsql)); + } + + $newpm = array(); + foreach ($touids as $key => $value) + { + $newpm[] = "('$value')"; + } + $this->db->query("REPLACE INTO " . UC_DBTABLEPRE . "newpm(uid) VALUES " . implode(',', $newpm)); + return $pmid; + } + + function replypm($plid, $fromuid, $fromusername, $message) + { + if (!$plid || !$fromuid || !$fromusername || !$message) + { + return 0; + } + + $threadpm = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "pm_lists WHERE plid='$plid'"); + if (empty($threadpm)) + { + return PMTHREADNONE_ERROR; + } + + if ($threadpm['pmtype'] == 1) + { + $users = explode('_', $threadpm['min_max']); + if ($users[0] == $fromuid) + { + $touid = $users[1]; + } + elseif ($users[1] == $fromuid) + { + $touid = $users[0]; + } + else + { + return PMPRIVILEGENONE_ERROR; + } + + $blackls = $this->get_blackls($fromuid, $touid); + if (in_array('{ALL}', $blackls[$touid])) + { + return PMINBALCKLIST_ERROR; + } + $this->base->load('user'); + $blackls[$touid] = $_ENV['user']->name2id($blackls[$touid]); + if (!(isset($blackls[$touid]) && !in_array($fromuid, $blackls[$touid]))) + { + return PMINBALCKLIST_ERROR; + } + } + + $memberuid = array(); + $query = $this->db->query("SELECT * FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$plid'"); + while ($member = $this->db->fetch_array($query)) + { + $memberuid[$member['uid']] = "('$member[uid]')"; + } + if (!isset($memberuid[$fromuid])) + { + return PMPRIVILEGENONE_ERROR; + } + + $_CACHE['badwords'] = $this->base->cache('badwords'); + if ($_CACHE['badwords']['findpattern']) + { + $message = @preg_replace($_CACHE['badwords']['findpattern'], $_CACHE['badwords']['replace'], $message); + } + $lastsummary = $this->removecode(trim(stripslashes($message)), 150); + + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_indexes(plid) VALUES('$plid')"); + $pmid = $this->db->insert_id(); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . $this->getposttablename($plid) . "(pmid, plid, authorid, message, dateline, delstatus) VALUES('$pmid', '$plid', '$fromuid', '$message', '" . $this->base->time . "', 0)"); + if ($threadpm['pmtype'] == 1) + { + $lastmessage = array('lastauthorid' => $fromuid, 'lastauthor' => $fromusername, 'lastsummary' => $lastsummary); + $lastmessage = addslashes(serialize($lastmessage)); + $result = $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_members(plid, uid, isnew, pmnum, lastupdate, lastdateline) VALUES('$plid', '$touid', '1', '1', '0', '" . $this->base->time . "')", 'SILENT'); + if (!$result) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew=1, pmnum=pmnum+1, lastdateline='" . $this->base->time . "' WHERE plid='$plid' AND uid='$touid'"); + } + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew=0, pmnum=pmnum+1, lastupdate='" . $this->base->time . "', lastdateline='" . $this->base->time . "' WHERE plid='$plid' AND uid='$fromuid'"); + } + else + { + $lastmessage = unserialize($threadpm['lastmessage']); + $lastmessage = array('firstauthorid' => $lastmessage['firstauthorid'], 'firstauthor' => $lastmessage['firstauthor'], 'firstsummary' => $lastmessage['firstsummary'], 'lastauthorid' => $fromuid, 'lastauthor' => $fromusername, 'lastsummary' => $lastsummary); + $lastmessage = addslashes(serialize($lastmessage)); + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew=1, pmnum=pmnum+1, lastdateline='" . $this->base->time . "' WHERE plid='$plid'"); + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew=0, lastupdate='" . $this->base->time . "' WHERE plid='$plid' AND uid='$fromuid'"); + } + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_lists SET lastmessage='$lastmessage' WHERE plid='$plid'"); + + $this->db->query("REPLACE INTO " . UC_DBTABLEPRE . "newpm(uid) VALUES " . implode(',', $memberuid) . ""); + + return $pmid; + } + + function appendchatpm($plid, $uid, $touid) + { + if (!$plid || !$uid || !$touid) + { + return 0; + } + $threadpm = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "pm_lists WHERE plid='$plid'"); + if (empty($threadpm)) + { + return PMTHREADNONE_ERROR; + } + if ($threadpm['pmtype'] != 2) + { + return PMCHATTYPE_ERROR; + } + if ($threadpm['authorid'] != $uid) + { + return PMPRIVILEGENONE_ERROR; + } + + $blackls = $this->get_blackls($uid, $touid); + if (in_array('{ALL}', $blackls[$touid])) + { + return PMINBALCKLIST_ERROR; + } + $this->base->load('user'); + $blackls[$touid] = $_ENV['user']->name2id($blackls[$touid]); + if (!(isset($blackls[$touid]) && !in_array($uid, $blackls[$touid]))) + { + return PMINBALCKLIST_ERROR; + } + + $pmnum = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . $this->getposttablename($plid) . " WHERE plid='$plid'"); + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "pm_members(plid, uid, isnew, pmnum, lastupdate, lastdateline) VALUES('$plid', '$touid', '1', '$pmnum', '0', '0')", 'SILENT'); + $num = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$plid'"); + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_lists SET members='$num' WHERE plid='$plid'"); + + return 1; + } + + function kickchatpm($plid, $uid, $touid) + { + if (!$uid || !$touid || !$plid || $uid == $touid) + { + return 0; + } + $threadpm = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "pm_lists WHERE plid='$plid'"); + if ($threadpm['pmtype'] != 2) + { + return PMCHATTYPE_ERROR; + } + if ($threadpm['authorid'] != $uid) + { + return PMPRIVILEGENONE_ERROR; + } + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$plid' AND uid='$touid'"); + $num = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$plid'"); + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_lists SET members='$num' WHERE plid='$plid'"); + return 1; + } + + function quitchatpm($uid, $plids) + { + if (!$uid || !$plids) + { + return 0; + } + $list = array(); + $query = $this->db->query("SELECT * FROM " . UC_DBTABLEPRE . "pm_members m LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON m.plid=t.plid WHERE m.plid IN (" . $this->base->implode($plids) . ") AND m.uid='$uid'"); + while ($threadpm = $this->db->fetch_array($query)) + { + if ($threadpm['pmtype'] != 2) + { + return PMCHATTYPE_ERROR; + } + if ($threadpm['authorid'] == $uid) + { + return PMPRIVILEGENONE_ERROR; + } + $list[] = $threadpm['plid']; + } + + if ($list) + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_members WHERE plid IN (" . $this->base->implode($list) . ") AND uid='$uid'"); + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_lists SET members=members-1 WHERE plid IN (" . $this->base->implode($list) . ")"); + } + + return 1; + } + + function deletepmbypmid($uid, $pmid) + { + if (!$uid || !$pmid) + { + return 0; + } + $index = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "pm_indexes i LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON i.plid=t.plid WHERE i.pmid='$pmid'"); + if ($index['pmtype'] != 1) + { + return PMUIDTYPE_ERROR; + } + $users = explode('_', $index['min_max']); + if (!in_array($uid, $users)) + { + return PMPRIVILEGENONE_ERROR; + } + if ($index['authorid'] != $uid) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . $this->getposttablename($index['plid']) . " SET delstatus=2 WHERE pmid='$pmid' AND delstatus=0"); + $updatenum = $this->db->affected_rows(); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . $this->getposttablename($index['plid']) . " WHERE pmid='$pmid' AND delstatus=1"); + $deletenum = $this->db->affected_rows(); + } + else + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . $this->getposttablename($index['plid']) . " SET delstatus=1 WHERE pmid='$pmid' AND delstatus=0"); + $updatenum = $this->db->affected_rows(); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . $this->getposttablename($index['plid']) . " WHERE pmid='$pmid' AND delstatus=2"); + $deletenum = $this->db->affected_rows(); + } + + if (!$this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . $this->getposttablename($index['plid']) . " WHERE plid='$index[plid]'")) + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_lists WHERE plid='$index[plid]'"); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$index[plid]'"); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_indexes WHERE plid='$index[plid]'"); + } + else + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET pmnum=pmnum-" . ($updatenum + $deletenum) . " WHERE plid='" . $index['plid'] . "' AND uid='$uid'"); + } + return 1; + } + + function deletepmbypmids($uid, $pmids) + { + if ($pmids) + { + foreach ($pmids as $key => $pmid) + { + $this->deletepmbypmid($uid, $pmid); + } + } + return 1; + } + + /* + function deletepmbypmids($uid, $pmids) { + if(!$uid || !$pmids) { + return 0; + } + $pmplid = $delstatus1pm = $delstatus2pm = $pmplidpost = array(); + $existplid = array(); + $query = $this->db->query("SELECT * FROM ".UC_DBTABLEPRE."pm_indexes i LEFT JOIN ".UC_DBTABLEPRE."pm_lists t ON i.plid=t.plid WHERE i.pmid IN (".$this->base->implode($pmids).") AND t.pmtype=1"); + while($index = $this->db->fetch_array($query)) { + $users = explode('_', $index['min_max']); + if(!in_array($uid, $users)) { + return PMPRIVILEGENONE_ERROR; + } + if($index['authorid'] == $uid) { + $delstatus1pm[$this->getposttablename($index['plid'])][] = $index['pmid']; + } else { + $delstatus2pm[$this->getposttablename($index['plid'])][] = $index['pmid']; + } + $pmplidpost[$this->getposttablename($index['plid'])][] = $index['plid']; + $pmplid[$index['plid']] = $index['plid']; + } + if(empty($pmplidpost)) { + return 0; + } + + if($delstatus1pm) { + foreach($delstatus1pm as $key => $value) { + $this->db->query("UPDATE ".UC_DBTABLEPRE."$key SET delstatus=1 WHERE pmid IN (".$this->base->implode($value).") AND delstatus=0"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."$key WHERE pmid IN (".$this->base->implode($value).") AND delstatus=2"); + } + } + + if($delstatus2pm) { + foreach($delstatus2pm as $key => $value) { + $this->db->query("UPDATE ".UC_DBTABLEPRE."$key SET delstatus=2 WHERE pmid IN (".$this->base->implode($value).") AND delstatus=0"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."$key WHERE pmid IN (".$this->base->implode($value).") AND delstatus=1"); + } + } + + foreach($pmplidpost as $key => $value) { + $query = $this->db->query("SELECT DISTINCT plid FROM ".UC_DBTABLEPRE."$key WHERE plid IN (".$this->base->implode($value).")"); + while($pmpostarr = $this->db->fetch_array($query)) { + $existplid[] = $pmpostarr['plid']; + } + } + $pmplid = array_diff($pmplid, $existplid); + if($pmplid) { + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_lists WHERE plid IN (".$this->base->implode($pmplid).")"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_members WHERE plid IN (".$this->base->implode($pmplid).")"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_indexes WHERE plid IN (".$this->base->implode($pmplid).")"); + } + return 1; + } + */ + + function deletepmbyplid($uid, $plid, $isuser = 0) + { + if (!$uid || !$plid) + { + return 0; + } + + if ($isuser) + { + $relationship = $this->relationship($uid, $plid); + $sql = "SELECT * FROM " . UC_DBTABLEPRE . "pm_lists WHERE min_max='$relationship'"; + } + else + { + $sql = "SELECT * FROM " . UC_DBTABLEPRE . "pm_lists WHERE plid='$plid'"; + } + + $query = $this->db->query($sql); + if ($list = $this->db->fetch_array($query)) + { + if ($list['pmtype'] == 1) + { + $user = explode('_', $list['min_max']); + if (!in_array($uid, $user)) + { + return PMPRIVILEGENONE_ERROR; + } + } + else + { + if ($uid != $list['authorid']) + { + return PMPRIVILEGENONE_ERROR; + } + } + } + else + { + return PMTHREADNONE_ERROR; + } + + if ($list['pmtype'] == 1) + { + if ($uid == $list['authorid']) + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . $this->getposttablename($list['plid']) . " WHERE plid='$list[plid]' AND delstatus=2"); + $this->db->query("UPDATE " . UC_DBTABLEPRE . $this->getposttablename($list['plid']) . " SET delstatus=1 WHERE plid='$list[plid]' AND delstatus=0"); + } + else + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . $this->getposttablename($list['plid']) . " WHERE plid='$list[plid]' AND delstatus=1"); + $this->db->query("UPDATE " . UC_DBTABLEPRE . $this->getposttablename($list['plid']) . " SET delstatus=2 WHERE plid='$list[plid]' AND delstatus=0"); + } + $count = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . $this->getposttablename($list['plid']) . " WHERE plid='$list[plid]'"); + if (!$count) + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_lists WHERE plid='$list[plid]'"); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$list[plid]'"); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_indexes WHERE plid='$list[plid]'"); + } + else + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$list[plid]' AND uid='$uid'"); + } + } + else + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . $this->getposttablename($list['plid']) . " WHERE plid='$list[plid]'"); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_lists WHERE plid='$list[plid]'"); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$list[plid]'"); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "pm_indexes WHERE plid='$list[plid]'"); + } + return 1; + } + + function deletepmbyplids($uid, $plids, $isuser = 0) + { + if ($plids) + { + foreach ($plids as $key => $plid) + { + $this->deletepmbyplid($uid, $plid, $isuser); + } + } + return 1; + } + + /* + function deletepmbyplid($uid, $plids, $isuser = 0) { + if(!$uid || !$plids) { + return 0; + } + + $privatepm = $chatpm = array(); + $privatepmauthorpost = $privatepmpost = $privatepmpostall = array(); + $existplid = array(); + if($isuser) { + $relationship = array(); + foreach($plids as $key => $value) { + if($uid == $value || !$value) { + return PMDATA_ERROR; + } + $relationship[] = $this->relationship($uid, $value); + } + $sql = "SELECT * FROM ".UC_DBTABLEPRE."pm_lists WHERE min_max IN (".$this->base->implode($relationship).")"; + } else { + $sql = "SELECT * FROM ".UC_DBTABLEPRE."pm_lists WHERE plid IN (".$this->base->implode($plids).")"; + } + $query = $this->db->query($sql); + while($threadpm = $this->db->fetch_array($query)) { + if($threadpm['pmtype'] == 1) { + $users = explode('_', $threadpm['min_max']); + if($users[0] == $uid) { + $touid = $users[1]; + } elseif($users[1] == $uid) { + $touid = $users[0]; + } else { + continue; + } + + if($threadpm['authorid'] == $uid) { + $privatepmauthorpost[$this->getposttablename($threadpm['plid'])][] = $threadpm['plid']; + } else { + $privatepmpost[$this->getposttablename($threadpm['plid'])][] = $threadpm['plid']; + } + $privatepmpostall[$this->getposttablename($threadpm['plid'])][] = $threadpm['plid']; + $privatepm[] = $threadpm['plid']; + } else { + if($uid != $threadpm['authorid']) { + continue; + } + $chatpm[] = $threadpm['plid']; + $chatpmpost[$this->getposttablename($threadpm['plid'])][] = $threadpm['plid']; + } + } + + if($privatepmauthorpost) { + foreach($privatepmauthorpost as $key => $value) { + $this->db->query("UPDATE ".UC_DBTABLEPRE."$key SET delstatus=1 WHERE plid IN (".$this->base->implode($value).") AND delstatus=0"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."$key WHERE plid IN (".$this->base->implode($value).") AND delstatus=2"); + } + } + + if($privatepmpost) { + foreach($privatepmpost as $key => $value) { + $this->db->query("UPDATE ".UC_DBTABLEPRE."$key SET delstatus=2 WHERE plid IN (".$this->base->implode($value).") AND delstatus=0"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."$key WHERE plid IN (".$this->base->implode($value).") AND delstatus=1"); + } + } + if($privatepmpostall) { + foreach($privatepmpostall as $key => $value) { + $query = $this->db->query("SELECT DISTINCT plid FROM ".UC_DBTABLEPRE."$key WHERE plid IN (".$this->base->implode($value).")"); + while($postpm = $this->db->fetch_array($query)) { + $existplid[] = $postpm['plid']; + } + } + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_members WHERE plid IN (".$this->base->implode($privatepm).") AND uid='$uid'"); + $privatepm = array_diff($privatepm, $existplid); + if(!empty($privatepm)) { + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_lists WHERE plid IN (".$this->base->implode($privatepm).")"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_members WHERE plid IN (".$this->base->implode($privatepm).")"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_indexes WHERE plid IN (".$this->base->implode($privatepm).")"); + } + } + if($chatpmpost) { + foreach($chatpmpost as $key => $value) { + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."$key WHERE plid IN (".$this->base->implode($value).")"); + } + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_lists WHERE plid IN (".$this->base->implode($chatpm).")"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_members WHERE plid IN (".$this->base->implode($chatpm).")"); + $this->db->query("DELETE FROM ".UC_DBTABLEPRE."pm_indexes WHERE plid IN (".$this->base->implode($chatpm).")"); + } + return 1; + } + */ + + function getprivatepmbyplid($uid, $plid, $starttime = 0, $endtime = 0, $start = 0, $ppp = 0) + { + if (!$uid || !$plid) + { + return 0; + } + if (!$this->isprivilege($plid, $uid)) + { + return 0; + } + $thread = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "pm_lists WHERE plid='$plid'"); + if ($thread['pmtype'] != 1) + { + return 0; + } + $pms = $addsql = array(); + $addsql[] = "p.plid='$plid'"; + if ($thread['authorid'] == $uid) + { + $addsql[] = 'p.delstatus IN (0,2)'; + } + else + { + $addsql[] = 'p.delstatus IN (0,1)'; + } + if ($starttime) + { + $addsql[] = "p.dateline>'$starttime'"; + } + if ($endtime) + { + $addsql[] = "p.dateline<'$endtime'"; + } + if ($addsql) + { + $addsql = implode(' AND ', $addsql); + } + else + { + $addsql = ''; + } + if ($ppp) + { + $limitsql = 'LIMIT ' . intval($start) . ', ' . intval($ppp); + } + else + { + $limitsql = ''; + } + $pms = $this->db->fetch_all("SELECT t.*, p.*, t.authorid as founderuid, t.dateline as founddateline FROM " . UC_DBTABLEPRE . $this->getposttablename($plid) . " p LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON p.plid=t.plid WHERE $addsql ORDER BY p.dateline DESC $limitsql"); + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew=0 WHERE plid='$plid' AND uid='$uid' AND isnew=1"); + return array_reverse($pms); + } + + function getchatpmbyplid($uid, $plid, $starttime = 0, $endtime = 0, $start = 0, $ppp = 0) + { + if (!$uid || !$plid) + { + return 0; + } + if (!$this->isprivilege($plid, $uid)) + { + return 0; + } + $pms = $addsql = array(); + $addsql[] = "p.plid='$plid'"; + if ($starttime) + { + $addsql[] = "p.dateline>'$starttime'"; + } + if ($endtime) + { + $addsql[] = "p.dateline<'$endtime'"; + } + if ($addsql) + { + $addsql = implode(' AND ', $addsql); + } + else + { + $addsql = ''; + } + if ($ppp) + { + $limitsql = 'LIMIT ' . intval($start) . ', ' . intval($ppp); + } + else + { + $limitsql = ''; + } + $query = $this->db->query("SELECT t.*, p.*, t.authorid as founderuid, t.dateline as founddateline FROM " . UC_DBTABLEPRE . $this->getposttablename($plid) . " p LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON p.plid=t.plid WHERE $addsql ORDER BY p.dateline DESC $limitsql"); + while ($pm = $this->db->fetch_array($query)) + { + if ($pm['pmtype'] != 2) + { + return 0; + } + $pms[] = $pm; + } + $this->db->query("UPDATE " . UC_DBTABLEPRE . "pm_members SET isnew=0 WHERE plid='$plid' AND uid='$uid' AND isnew=1"); + return array_reverse($pms); + } + + function getpmlist($uid, $filter, $start, $ppp = 10) + { + if (!$uid) + { + return 0; + } + $members = $touidarr = $tousernamearr = array(); + + if ($filter == 'newpm') + { + $addsql = 'm.isnew=1 AND '; + } + else + { + $addsql = ''; + } + $query = $this->db->query("SELECT * FROM " . UC_DBTABLEPRE . "pm_members m LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON t.plid=m.plid WHERE $addsql m.uid='$uid' ORDER BY m.lastdateline DESC LIMIT $start, $ppp"); + while ($member = $this->db->fetch_array($query)) + { + if ($member['pmtype'] == 1) + { + $users = explode('_', $member['min_max']); + $member['touid'] = $users[0] == $uid ? $users[1] : $users[0]; + } + else + { + $member['touid'] = 0; + } + $touidarr[$member['touid']] = $member['touid']; + $members[] = $member; + } + + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "newpm WHERE uid='$uid'"); + + $array = array(); + if ($members) + { + $today = $this->base->time - $this->base->time % 86400; + $this->base->load('user'); + $tousernamearr = $_ENV['user']->id2name($touidarr); + foreach ($members as $key => $data) + { + + $daterange = 5; + $data['founddateline'] = $data['dateline']; + $data['dateline'] = $data['lastdateline']; + $data['pmid'] = $data['plid']; + $lastmessage = unserialize($data['lastmessage']); + if ($lastmessage['firstauthorid']) + { + $data['firstauthorid'] = $lastmessage['firstauthorid']; + $data['firstauthor'] = $lastmessage['firstauthor']; + $data['firstsummary'] = $lastmessage['firstsummary']; + } + if ($lastmessage['lastauthorid']) + { + $data['lastauthorid'] = $lastmessage['lastauthorid']; + $data['lastauthor'] = $lastmessage['lastauthor']; + $data['lastsummary'] = $lastmessage['lastsummary']; + } + $data['msgfromid'] = $lastmessage['lastauthorid']; + $data['msgfrom'] = $lastmessage['lastauthor']; + $data['message'] = $lastmessage['lastsummary']; + + $data['new'] = $data['isnew']; + + $data['msgtoid'] = $data['touid']; + if ($data['lastdateline'] >= $today) + { + $daterange = 1; + } + elseif ($data['lastdateline'] >= $today - 86400) + { + $daterange = 2; + } + elseif ($data['lastdateline'] >= $today - 172800) + { + $daterange = 3; + } + elseif ($data['lastdateline'] >= $today - 604800) + { + $daterange = 4; + } + $data['daterange'] = $daterange; + + $data['tousername'] = $tousernamearr[$data['touid']]; + unset($data['min_max']); + $array[] = $data; + } + } + return $array; + } + + function getplidbypmid($pmid) + { + if (!$pmid) + { + return false; + } + return $this->db->result_first("SELECT plid FROM " . UC_DBTABLEPRE . "pm_indexes WHERE pmid='$pmid'"); + } + + function getplidbytouid($uid, $touid) + { + if (!$uid || !$touid) + { + return 0; + } + return $this->db->result_first("SELECT plid FROM " . UC_DBTABLEPRE . "pm_lists WHERE min_max='" . $this->relationship($uid, $touid) . "'"); + } + + function getuidbyplid($plid) + { + if (!$plid) + { + return array(); + } + $uidarr = array(); + $query = $this->db->query("SELECT uid FROM " . UC_DBTABLEPRE . "pm_members WHERE plid='$plid'"); + while ($uid = $this->db->fetch_array($query)) + { + $uidarr[$uid['uid']] = $uid['uid']; + } + return $uidarr; + } + + function chatpmmemberlist($uid, $plid) + { + if (!$uid || !$plid) + { + return 0; + } + $uidarr = $this->getuidbyplid($plid); + if (empty($uidarr)) + { + return 0; + } + if (!isset($uidarr[$uid])) + { + return 0; + } + $authorid = $this->db->result_first("SELECT authorid FROM " . UC_DBTABLEPRE . "pm_lists WHERE plid='$plid'"); + return array('author' => $authorid, 'member' => $uidarr); + } + + function relationship($fromuid, $touid) + { + if ($fromuid < $touid) + { + return $fromuid . '_' . $touid; + } + elseif ($fromuid > $touid) + { + return $touid . '_' . $fromuid; + } + else + { + return ''; + } + } + + function getposttablename($plid) + { + $id = substr((string) $plid, -1, 1); + return 'pm_messages_' . intval($id); + } + + function get_blackls($uid, $uids = array()) + { + if (!$uids) + { + $blackls = $this->db->result_first("SELECT blacklist FROM " . UC_DBTABLEPRE . "memberfields WHERE uid='$uid'"); + } + else + { + $uids = $this->base->implode($uids); + $blackls = array(); + $query = $this->db->query("SELECT uid, blacklist FROM " . UC_DBTABLEPRE . "memberfields WHERE uid IN ($uids)"); + while ($data = $this->db->fetch_array($query)) + { + $blackls[$data['uid']] = explode(',', $data['blacklist']); + } + } + return $blackls; + } + + function set_blackls($uid, $blackls) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "memberfields SET blacklist='$blackls' WHERE uid='$uid'"); + return $this->db->affected_rows(); + } + + function update_blackls($uid, $username, $action = 1) + { + $username = !is_array($username) ? array($username) : $username; + if ($action == 1) + { + if (!in_array('{ALL}', $username)) + { + $usernames = $this->base->implode($username); + $query = $this->db->query("SELECT username FROM " . UC_DBTABLEPRE . "members WHERE username IN ($usernames)"); + $usernames = array(); + while ($data = $this->db->fetch_array($query)) + { + $usernames[addslashes($data['username'])] = addslashes($data['username']); + } + if (!$usernames) + { + return 0; + } + $blackls = addslashes($this->db->result_first("SELECT blacklist FROM " . UC_DBTABLEPRE . "memberfields WHERE uid='$uid'")); + if ($blackls) + { + $list = explode(',', $blackls); + foreach ($list as $k => $v) + { + if (in_array($v, $usernames)) + { + unset($usernames[$v]); + } + } + } + if (!$usernames) + { + return 1; + } + $listnew = implode(',', $usernames); + $blackls .= $blackls !== '' ? ',' . $listnew : $listnew; + } + else + { + $blackls = addslashes($this->db->result_first("SELECT blacklist FROM " . UC_DBTABLEPRE . "memberfields WHERE uid='$uid'")); + $blackls .= ',{ALL}'; + } + } + else + { + $blackls = addslashes($this->db->result_first("SELECT blacklist FROM " . UC_DBTABLEPRE . "memberfields WHERE uid='$uid'")); + $list = $blackls = explode(',', $blackls); + foreach ($list as $k => $v) + { + if (in_array($v, $username)) + { + unset($blackls[$k]); + } + } + $blackls = implode(',', $blackls); + } + $this->db->query("UPDATE " . UC_DBTABLEPRE . "memberfields SET blacklist='$blackls' WHERE uid='$uid'"); + return 1; + } + + function removecode($str, $length) + { + static $uccode = null; + if ($uccode === null) + { + require_once UC_ROOT . 'lib/uccode.class.php'; + $uccode = new uccode(); + } + $str = $uccode->complie($str); + return trim($this->base->cutstr(strip_tags($str), $length)); + } + + function ispminterval($uid, $interval = 0) + { + if (!$uid) + { + return 0; + } + $interval = intval($interval); + if (!$interval) + { + return 1; + } + $lastupdate = $this->db->result_first("SELECT lastupdate FROM " . UC_DBTABLEPRE . "pm_members WHERE uid='$uid' ORDER BY lastupdate DESC LIMIT 1"); + if (($this->base->time - $lastupdate) > $interval) + { + return 1; + } + else + { + return 0; + } + } + + function isprivatepmthreadlimit($uid, $maxnum = 0) + { + if (!$uid) + { + return 0; + } + $maxnum = intval($maxnum); + if (!$maxnum) + { + return 1; + } + $num = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "pm_members m LEFT JOIN " . UC_DBTABLEPRE . "pm_lists t ON m.plid=t.plid WHERE uid='$uid' AND lastupdate>'" . ($this->base->time - 86400) . "' AND t.pmtype=1"); + if ($maxnum - $num < 0) + { + return 0; + } + else + { + return 1; + } + } + + function ischatpmthreadlimit($uid, $maxnum = 0) + { + if (!$uid) + { + return 0; + } + $maxnum = intval($maxnum); + if (!$maxnum) + { + return 1; + } + $num = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "pm_lists WHERE authorid='$uid' AND dateline>'" . ($this->base->time - 86400) . "'"); + if ($maxnum - $num < 0) + { + return 0; + } + else + { + return 1; + } + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/tag.php b/extend/fast/ucenter/client/uc_client/model/tag.php new file mode 100644 index 0000000..4a8261f --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/tag.php @@ -0,0 +1,84 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: tag.php 1059 2011-03-01 07:25:09Z monkey $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class tagmodel +{ + + var $db; + var $base; + + function __construct(&$base) + { + $this->tagmodel($base); + } + + function tagmodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + } + + function get_tag_by_name($tagname) + { + $arr = $this->db->fetch_all("SELECT * FROM " . UC_DBTABLEPRE . "tags WHERE tagname='$tagname'"); + return $arr; + } + + function get_template($appid) + { + $result = $this->db->result_first("SELECT tagtemplates FROM " . UC_DBTABLEPRE . "applications WHERE appid='$appid'"); + return $result; + } + + function updatedata($appid, $data) + { + $appid = intval($appid); + include_once UC_ROOT . 'lib/xml.class.php'; + $data = @xml_unserialize($data); + $this->base->load('app'); + $data[0] = addslashes($data[0]); + $datanew = array(); + if (is_array($data[1])) + { + foreach ($data[1] as $r) + { + $datanew[] = $_ENV['misc']->array2string($r); + } + } + $tmp = $_ENV['app']->get_apps('type', "appid='$appid'"); + $datanew = addslashes($tmp[0]['type'] . "\t" . implode("\t", $datanew)); + if (!empty($data[0])) + { + $return = $this->db->result_first("SELECT count(*) FROM " . UC_DBTABLEPRE . "tags WHERE tagname='$data[0]' AND appid='$appid'"); + if ($return) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "tags SET data='$datanew', expiration='" . $this->base->time . "' WHERE tagname='$data[0]' AND appid='$appid'"); + } + else + { + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "tags (tagname, appid, data, expiration) VALUES ('$data[0]', '$appid', '$datanew', '" . $this->base->time . "')"); + } + } + } + + function formatcache($appid, $tagname) + { + $return = $this->db->result_first("SELECT count(*) FROM " . UC_DBTABLEPRE . "tags WHERE tagname='$tagname' AND appid='$appid'"); + if ($return) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "tags SET expiration='0' WHERE tagname='$tagname' AND appid='$appid'"); + } + else + { + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "tags (tagname, appid, expiration) VALUES ('$tagname', '$appid', '0')"); + } + } + +} diff --git a/extend/fast/ucenter/client/uc_client/model/user.php b/extend/fast/ucenter/client/uc_client/model/user.php new file mode 100644 index 0000000..0766227 --- /dev/null +++ b/extend/fast/ucenter/client/uc_client/model/user.php @@ -0,0 +1,439 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: user.php 1179 2014-11-03 07:11:25Z hypowang $ + */ +!defined('IN_UC') && exit('Access Denied'); + +class usermodel +{ + + var $db; + var $base; + + function __construct(&$base) + { + $this->usermodel($base); + } + + function usermodel(&$base) + { + $this->base = $base; + $this->db = $base->db; + } + + function get_user_by_uid($uid) + { + $arr = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "members WHERE uid='$uid'"); + return $arr; + } + + function get_user_by_username($username) + { + $arr = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "members WHERE username='$username'"); + return $arr; + } + + function get_user_by_email($email) + { + $arr = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "members WHERE email='$email'"); + return $arr; + } + + function get_user_by_mobile($mobile) + { + $arr = $this->db->fetch_first("SELECT * FROM " . UC_DBTABLEPRE . "members WHERE mobile='$mobile'"); + return $arr; + } + + function check_username($username) + { + $guestexp = '\xA1\xA1|\xAC\xA3|^Guest|^\xD3\xCE\xBF\xCD|\xB9\x43\xAB\xC8'; + $len = $this->dstrlen($username); + if ($len > 15 || $len < 3 || preg_match("/\s+|^c:\\con\\con|[%,\*\"\s\<\>\&]|$guestexp/is", $username)) + { + return FALSE; + } + else + { + return TRUE; + } + } + + function dstrlen($str) + { + if (strtolower(UC_CHARSET) != 'utf-8') + { + return strlen($str); + } + $count = 0; + for ($i = 0; $i < strlen($str); $i++) + { + $value = ord($str[$i]); + if ($value > 127) + { + $count++; + if ($value >= 192 && $value <= 223) + $i++; + elseif ($value >= 224 && $value <= 239) + $i = $i + 2; + elseif ($value >= 240 && $value <= 247) + $i = $i + 3; + } + $count++; + } + return $count; + } + + function check_mergeuser($username) + { + $data = $this->db->result_first("SELECT count(*) FROM " . UC_DBTABLEPRE . "mergemembers WHERE appid='" . $this->base->app['appid'] . "' AND username='$username'"); + return $data; + } + + function check_usernamecensor($username) + { + $_CACHE['badwords'] = $this->base->cache('badwords'); + $censorusername = $this->base->get_setting('censorusername'); + $censorusername = $censorusername['censorusername']; + $censorexp = '/^(' . str_replace(array('\\*', "\r\n", ' '), array('.*', '|', ''), preg_quote(($censorusername = trim($censorusername)), '/')) . ')$/i'; + $usernamereplaced = isset($_CACHE['badwords']['findpattern']) && !empty($_CACHE['badwords']['findpattern']) ? @preg_replace($_CACHE['badwords']['findpattern'], $_CACHE['badwords']['replace'], $username) : $username; + return !(($usernamereplaced != $username) || ($censorusername && preg_match($censorexp, $username))); + } + + function check_usernameexists($username) + { + $data = $this->db->result_first("SELECT username FROM " . UC_DBTABLEPRE . "members WHERE username='$username'"); + return $data; + } + + function check_emailformat($email) + { + return strlen($email) > 6 && strlen($email) <= 32 && preg_match("/^([a-z0-9\-_.+]+)@([a-z0-9\-]+[.][a-z0-9\-.]+)$/", $email); + } + + function check_emailaccess($email) + { + $setting = $this->base->get_setting(array('accessemail', 'censoremail')); + $accessemail = $setting['accessemail']; + $censoremail = $setting['censoremail']; + $accessexp = '/(' . str_replace("\r\n", '|', preg_quote(trim($accessemail), '/')) . ')$/i'; + $censorexp = '/(' . str_replace("\r\n", '|', preg_quote(trim($censoremail), '/')) . ')$/i'; + if ($accessemail || $censoremail) + { + return !(($accessemail && !preg_match($accessexp, $email)) || ($censoremail && preg_match($censorexp, $email))); + } + else + { + return TRUE; + } + } + + function check_emailexists($email, $username = '') + { + $sqladd = $username !== '' ? "AND username<>'$username'" : ''; + $email = $this->db->result_first("SELECT email FROM " . UC_DBTABLEPRE . "members WHERE email='$email' $sqladd"); + return $email; + } + + function check_mobileformat($mobile) + { + return strlen($mobile) >= 11 && preg_match("/^1[34578]\d{9}$/", $mobile); + } + + function check_mobileaccess($mobile) + { + $setting = $this->base->get_setting(array('accessmobile', 'censormobile')); + $accessmobile = $setting['accessmobile']; + $censormobile = $setting['censormobile']; + $accessexp = '/(' . str_replace("\r\n", '|', preg_quote(trim($accessmobile), '/')) . ')$/i'; + $censorexp = '/(' . str_replace("\r\n", '|', preg_quote(trim($censormobile), '/')) . ')$/i'; + if ($accessmobile || $censormobile) + { + return !(($accessmobile && !preg_match($accessexp, $mobile)) || ($censormobile && preg_match($censorexp, $mobile))); + } + else + { + return TRUE; + } + } + + function check_mobileexists($mobile, $username = '') + { + $sqladd = $username !== '' ? "AND username<>'$username'" : ''; + $mobile = $this->db->result_first("SELECT mobile FROM " . UC_DBTABLEPRE . "members WHERE mobile='$mobile' $sqladd"); + return $mobile; + } + + /** + * 检测是否登录 + * @param string $username + * @param string $password + * @param array $user + * @return int + */ + function check_login($username, $password, &$user) + { + $user = $this->get_user_by_username($username); + if (empty($user['username'])) + { + return -1; + } + elseif ($user['password'] != md5(md5($password) . $user['salt'])) + { + return -2; + } + return $user['uid']; + } + + /** + * 在Ucenter中添加一个账号 + * @param string $username + * @param string $password + * @param string $email + * @param string $mobile + * @param int $uid + * @param array $extend + * @return int + */ + function add_user($username, $password, $email = '', $mobile = '', $uid = 0, $extend = []) + { + $regip = $this->base->onlineip; + $salt = substr(uniqid(rand()), -6); + $password = md5(md5($password) . $salt); + + $values = $uid ? "uid='" . intval($uid) . "'," : ''; + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "members SET $values username='$username', password='$password', email='$email', regip='$regip', regdate='" . $this->base->time . "', salt='$salt'"); + $uid = $this->db->insert_id(); + $extendfields = []; + foreach ($extend as $k => $v) + { + $extendfields[] = "{$k} = '{$v}'"; + } + $extendfields = $extendfields ? ',' . implode(',', $extendfields) : ''; + $this->db->query("INSERT INTO " . UC_DBTABLEPRE . "memberfields SET uid='$uid' {$extendfields}"); + return $uid; + } + + /** + * 编辑Ucenter中的账号 + * @param string $username + * @param string $password + * @param string $email + * @param string $mobile + * @return int + */ + function edit_user($username, $password = '', $email = '', $mobile = '', $uid = 0, $extend = []) + { + $uid = intval($uid); + $data = $this->db->fetch_first("SELECT username, uid, password, salt FROM " . UC_DBTABLEPRE . "members WHERE uid='$uid'"); + if (!$data) + { + return -7; + } + $isprotected = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "protectedmembers WHERE uid = '{$data['uid']}'"); + if ($isprotected) + { + return -8; + } + $fields = []; + if ($username) + $fields[] = "username = '{$username}'"; + if ($email) + $fields[] = "email = '{$email}'"; + if ($mobile) + $fields[] = "mobile = '{$mobile}'"; + if ($password) + $fields[] = "password = '" . md5(md5($password) . $data['salt']) . "'"; + $values = implode(',', $fields); + if ($values || $extend) + { + if ($values) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "members SET $values WHERE uid='{$data['uid']}'"); + } + $extendfields = []; + foreach ($extend as $k => $v) + { + $extendfields[] = "{$k} = '{$v}'"; + } + $extendfields = $extendfields ? implode(',', $extendfields) : ''; + if ($extendfields) + { + $this->db->query("UPDATE " . UC_DBTABLEPRE . "memberfields SET {$extendfields} WHERE uid='{$data['uid']}'"); + } + return 1; + } + else + { + return -7; + } + } + + /** + * 删除一个账号 + * @param array $uidsarr + * @return int + */ + function delete_user($uidsarr) + { + $uidsarr = (array) $uidsarr; + if (!$uidsarr) + { + return 0; + } + $uids = $this->base->implode($uidsarr); + $arr = $this->db->fetch_all("SELECT uid FROM " . UC_DBTABLEPRE . "protectedmembers WHERE uid IN ($uids)"); + $puids = array(); + foreach ((array) $arr as $member) + { + $puids[] = $member['uid']; + } + $uids = $this->base->implode(array_diff($uidsarr, $puids)); + if ($uids) + { + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "members WHERE uid IN($uids)"); + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "memberfields WHERE uid IN($uids)"); + uc_user_deleteavatar($uidsarr); + $this->base->load('note'); + $_ENV['note']->add('deleteuser', "ids=$uids"); + return $this->db->affected_rows(); + } + else + { + return 0; + } + } + + function delete_useravatar($uidsarr) + { + $uidsarr = (array) $uidsarr; + foreach ((array) $uidsarr as $uid) + { + file_exists($avatar_file = UC_DATADIR . './avatar/' . $this->base->get_avatar($uid, 'big', 'real')) && unlink($avatar_file); + file_exists($avatar_file = UC_DATADIR . './avatar/' . $this->base->get_avatar($uid, 'middle', 'real')) && unlink($avatar_file); + file_exists($avatar_file = UC_DATADIR . './avatar/' . $this->base->get_avatar($uid, 'small', 'real')) && unlink($avatar_file); + file_exists($avatar_file = UC_DATADIR . './avatar/' . $this->base->get_avatar($uid, 'big')) && unlink($avatar_file); + file_exists($avatar_file = UC_DATADIR . './avatar/' . $this->base->get_avatar($uid, 'middle')) && unlink($avatar_file); + file_exists($avatar_file = UC_DATADIR . './avatar/' . $this->base->get_avatar($uid, 'small')) && unlink($avatar_file); + } + } + + /** + * 获取账号总数 + * @param string $sqladd + * @return int + */ + function get_total_num($sqladd = '') + { + $data = $this->db->result_first("SELECT COUNT(*) FROM " . UC_DBTABLEPRE . "members $sqladd"); + return $data; + } + + /** + * 获取列表 + * @param int $page + * @param int $ppp + * @param int $totalnum + * @param string $sqladd + * @return array + */ + function get_list($page, $ppp, $totalnum, $sqladd) + { + $start = $this->base->page_get_start($page, $ppp, $totalnum); + $data = $this->db->fetch_all("SELECT * FROM " . UC_DBTABLEPRE . "members $sqladd LIMIT $start, $ppp"); + return $data; + } + + function name2id($usernamesarr) + { + $usernamesarr = uc_addslashes($usernamesarr, 1, TRUE); + $usernames = $this->base->implode($usernamesarr); + $query = $this->db->query("SELECT uid FROM " . UC_DBTABLEPRE . "members WHERE username IN($usernames)"); + $arr = array(); + while ($user = $this->db->fetch_array($query)) + { + $arr[] = $user['uid']; + } + return $arr; + } + + function id2name($uidarr) + { + $arr = array(); + $query = $this->db->query("SELECT uid, username FROM " . UC_DBTABLEPRE . "members WHERE uid IN (" . $this->base->implode($uidarr) . ")"); + while ($user = $this->db->fetch_array($query)) + { + $arr[$user['uid']] = $user['username']; + } + return $arr; + } + + function quescrypt($questionid, $answer) + { + return $questionid > 0 && $answer != '' ? substr(md5($answer . md5($questionid)), 16, 8) : ''; + } + + function can_do_login($username, $ip = '') + { + + $check_times = $this->base->settings['login_failedtime'] < 1 ? 5 : $this->base->settings['login_failedtime']; + + $username = substr(md5($username), 8, 15); + $expire = 15 * 60; + if (!$ip) + { + $ip = $this->base->onlineip; + } + + $ip_check = $user_check = array(); + $query = $this->db->query("SELECT * FROM " . UC_DBTABLEPRE . "failedlogins WHERE ip='" . $ip . "' OR ip='$username'"); + while ($row = $this->db->fetch_array($query)) + { + if ($row['ip'] === $username) + { + $user_check = $row; + } + elseif ($row['ip'] === $ip) + { + $ip_check = $row; + } + } + + if (empty($ip_check) || ($this->base->time - $ip_check['lastupdate'] > $expire)) + { + $ip_check = array(); + $this->db->query("REPLACE INTO " . UC_DBTABLEPRE . "failedlogins (ip, count, lastupdate) VALUES ('{$ip}', '0', '{$this->base->time}')"); + } + + if (empty($user_check) || ($this->base->time - $user_check['lastupdate'] > $expire)) + { + $user_check = array(); + $this->db->query("REPLACE INTO " . UC_DBTABLEPRE . "failedlogins (ip, count, lastupdate) VALUES ('{$username}', '0', '{$this->base->time}')"); + } + + if ($ip_check || $user_check) + { + $time_left = min(($check_times - $ip_check['count']), ($check_times - $user_check['count'])); + return $time_left; + } + + $this->db->query("DELETE FROM " . UC_DBTABLEPRE . "failedlogins WHERE lastupdate<" . ($this->base->time - ($expire + 1)), 'UNBUFFERED'); + + return $check_times; + } + + function loginfailed($username, $ip = '') + { + $username = substr(md5($username), 8, 15); + if (!$ip) + { + $ip = $this->base->onlineip; + } + $this->db->query("UPDATE " . UC_DBTABLEPRE . "failedlogins SET count=count+1, lastupdate='" . $this->base->time . "' WHERE ip='" . $ip . "' OR ip='$username'"); + } + +} diff --git a/extend/fast/ucenter/common/Functions.php b/extend/fast/ucenter/common/Functions.php new file mode 100644 index 0000000..9f9df9d --- /dev/null +++ b/extend/fast/ucenter/common/Functions.php @@ -0,0 +1,98 @@ +<?php + +function _uc_authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) +{ + $ckey_length = 4; + + $key = md5($key ? $key : UC_KEY); + $keya = md5(substr($key, 0, 16)); + $keyb = md5(substr($key, 16, 16)); + $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : ''; + + $cryptkey = $keya . md5($keya . $keyc); + $key_length = strlen($cryptkey); + + $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string; + $string_length = strlen($string); + + $result = ''; + $box = range(0, 255); + + $rndkey = array(); + for ($i = 0; $i <= 255; $i++) + { + $rndkey[$i] = ord($cryptkey[$i % $key_length]); + } + + for ($j = $i = 0; $i < 256; $i++) + { + $j = ($j + $box[$i] + $rndkey[$i]) % 256; + $tmp = $box[$i]; + $box[$i] = $box[$j]; + $box[$j] = $tmp; + } + + for ($a = $j = $i = 0; $i < $string_length; $i++) + { + $a = ($a + 1) % 256; + $j = ($j + $box[$a]) % 256; + $tmp = $box[$a]; + $box[$a] = $box[$j]; + $box[$j] = $tmp; + $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); + } + + if ($operation == 'DECODE') + { + if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) + { + return substr($result, 26); + } + else + { + return ''; + } + } + else + { + return $keyc . str_replace('=', '', base64_encode($result)); + } +} + +function _uc_stripslashes($string) +{ + if (is_array($string)) + { + foreach ($string as $key => $val) + { + $string[$key] = _stripslashes($val); + } + } + else + { + $string = stripslashes($string); + } + return $string; +} + +/** + * 字符串命名风格转换 + * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格 + * @param string $name 字符串 + * @param integer $type 转换类型 + * @return string + */ +function parse_name($name, $type = 0) +{ + if ($type) + { + return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function($match) + { + return strtoupper($match[1]); + }, $name)); + } + else + { + return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); + } +} diff --git a/extend/fast/ucenter/common/XML.php b/extend/fast/ucenter/common/XML.php new file mode 100644 index 0000000..938fbd5 --- /dev/null +++ b/extend/fast/ucenter/common/XML.php @@ -0,0 +1,129 @@ +<?php + +/* + [UCenter] (C)2001-2099 Comsenz Inc. + This is NOT a freeware, use is subject to license terms + + $Id: xml.class.php 1059 2011-03-01 07:25:09Z monkey $ + */ + +function xml_unserialize(&$xml, $isnormal = FALSE) +{ + $xml_parser = new XML($isnormal); + $data = $xml_parser->parse($xml); + $xml_parser->destruct(); + return $data; +} + +function xml_serialize($arr, $htmlon = FALSE, $isnormal = FALSE, $level = 1) +{ + $s = $level == 1 ? "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<root>\r\n" : ''; + $space = str_repeat("\t", $level); + foreach ($arr as $k => $v) + { + if (!is_array($v)) + { + $s .= $space . "<item id=\"$k\">" . ($htmlon ? '<![CDATA[' : '') . $v . ($htmlon ? ']]>' : '') . "</item>\r\n"; + } + else + { + $s .= $space . "<item id=\"$k\">\r\n" . xml_serialize($v, $htmlon, $isnormal, $level + 1) . $space . "</item>\r\n"; + } + } + $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s); + return $level == 1 ? $s . "</root>" : $s; +} + +class XML +{ + + var $parser; + var $document; + var $stack; + var $data; + var $last_opened_tag; + var $isnormal; + var $attrs = array(); + var $failed = FALSE; + + function __construct($isnormal) + { + $this->XML($isnormal); + } + + function XML($isnormal) + { + $this->isnormal = $isnormal; + $this->parser = xml_parser_create('ISO-8859-1'); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false); + xml_set_object($this->parser, $this); + xml_set_element_handler($this->parser, 'open', 'close'); + xml_set_character_data_handler($this->parser, 'data'); + } + + function destruct() + { + xml_parser_free($this->parser); + } + + function parse(&$data) + { + $this->document = array(); + $this->stack = array(); + return xml_parse($this->parser, $data, true) && !$this->failed ? $this->document : ''; + } + + function open(&$parser, $tag, $attributes) + { + $this->data = ''; + $this->failed = FALSE; + if (!$this->isnormal) + { + if (isset($attributes['id']) && !is_string($this->document[$attributes['id']])) + { + $this->document = &$this->document[$attributes['id']]; + } + else + { + $this->failed = TRUE; + } + } + else + { + if (!isset($this->document[$tag]) || !is_string($this->document[$tag])) + { + $this->document = &$this->document[$tag]; + } + else + { + $this->failed = TRUE; + } + } + $this->stack[] = &$this->document; + $this->last_opened_tag = $tag; + $this->attrs = $attributes; + } + + function data(&$parser, $data) + { + if ($this->last_opened_tag != NULL) + { + $this->data .= $data; + } + } + + function close(&$parser, $tag) + { + if ($this->last_opened_tag == $tag) + { + $this->document = $this->data; + $this->last_opened_tag = NULL; + } + array_pop($this->stack); + if ($this->stack) + { + $this->document = &$this->stack[count($this->stack) - 1]; + } + } + +}