', '/:circle',
+ '/:kotow', '/:turn', '/:skip', '/:oY', '/:#-0', '/:hiphot', '/:kiss', '/:<&', '/:&>',
+ );
+ foreach ($emotions as $index => $emotion) {
+ $message = str_replace($emotion, ' ', $message);
+ }
+
+ return $message;
+}
+
+
+function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
+ $ckey_length = 4;
+ $key = md5('' != $key ? $key : $GLOBALS['_W']['config']['setting']['authkey']);
+ $keya = md5(substr($key, 0, 16));
+ $keyb = md5(substr($key, 16, 16));
+ $keyc = $ckey_length ? ('DECODE' == $operation ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
+
+ $cryptkey = $keya . md5($keya . $keyc);
+ $key_length = strlen($cryptkey);
+
+ $string = 'DECODE' == $operation ? 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 ('DECODE' == $operation) {
+ if ((0 == substr($result, 0, 10) || 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 sizecount($size, $unit = false) {
+ if ($size >= 1073741824) {
+ $size = round($size / 1073741824 * 100) / 100 . ' GB';
+ } elseif ($size >= 1048576) {
+ $size = round($size / 1048576 * 100) / 100 . ' MB';
+ } elseif ($size >= 1024) {
+ $size = round($size / 1024 * 100) / 100 . ' KB';
+ } else {
+ $size = $size . ' Bytes';
+ }
+ if ($unit) {
+ $size = preg_replace('/[^0-9\.]/', '', $size);
+ }
+
+ return $size;
+}
+
+
+function bytecount($str) {
+ if ('b' == strtolower($str[strlen($str) - 1])) {
+ $str = substr($str, 0, -1);
+ }
+ if ('k' == strtolower($str[strlen($str) - 1])) {
+ return floatval($str) * 1024;
+ }
+ if ('m' == strtolower($str[strlen($str) - 1])) {
+ return floatval($str) * 1048576;
+ }
+ if ('g' == strtolower($str[strlen($str) - 1])) {
+ return floatval($str) * 1073741824;
+ }
+}
+
+
+function array2xml($arr, $level = 1) {
+ $s = 1 == $level ? '' : '';
+ foreach ($arr as $tagname => $value) {
+ if (is_numeric($tagname)) {
+ $tagname = $value['TagName'];
+ unset($value['TagName']);
+ }
+ if (!is_array($value)) {
+ $s .= "<{$tagname}>" . (!is_numeric($value) ? '' : '') . "{$tagname}>";
+ } else {
+ $s .= "<{$tagname}>" . array2xml($value, $level + 1) . "{$tagname}>";
+ }
+ }
+ $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
+
+ return 1 == $level ? $s . ' ' : $s;
+}
+
+function xml2array($xml) {
+ if (empty($xml)) {
+ return array();
+ }
+ $result = array();
+ $xmlobj = isimplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
+ if ($xmlobj instanceof SimpleXMLElement) {
+ $result = json_decode(json_encode($xmlobj), true);
+ if (is_array($result)) {
+ return $result;
+ } else {
+ return '';
+ }
+ } else {
+ return $result;
+ }
+}
+
+
+function scriptname() {
+ $script_name = basename($_SERVER['SCRIPT_FILENAME']);
+ if (basename($_SERVER['SCRIPT_NAME']) === $script_name) {
+ $script_name = $_SERVER['SCRIPT_NAME'];
+ } else {
+ if (basename($_SERVER['PHP_SELF']) === $script_name) {
+ $script_name = $_SERVER['PHP_SELF'];
+ } else {
+ if (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $script_name) {
+ $script_name = $_SERVER['ORIG_SCRIPT_NAME'];
+ } else {
+ if (false !== ($pos = strpos($_SERVER['PHP_SELF'], '/'))) {
+ $script_name = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $script_name;
+ } else {
+ if (isset($_SERVER['DOCUMENT_ROOT']) && 0 === strpos($_SERVER['SCRIPT_FILENAME'], $_SERVER['DOCUMENT_ROOT'])) {
+ $script_name = str_replace('\\', '/', str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_FILENAME']));
+ } else {
+ $script_name = 'unknown';
+ }
+ }
+ }
+ }
+ }
+
+ return $script_name;
+}
+
+
+function utf8_bytes($cp) {
+ if ($cp > 0x10000) {
+ return chr(0xF0 | (($cp & 0x1C0000) >> 18)) .
+ chr(0x80 | (($cp & 0x3F000) >> 12)) .
+ chr(0x80 | (($cp & 0xFC0) >> 6)) .
+ chr(0x80 | ($cp & 0x3F));
+ } elseif ($cp > 0x800) {
+ return chr(0xE0 | (($cp & 0xF000) >> 12)) .
+ chr(0x80 | (($cp & 0xFC0) >> 6)) .
+ chr(0x80 | ($cp & 0x3F));
+ } elseif ($cp > 0x80) {
+ return chr(0xC0 | (($cp & 0x7C0) >> 6)) .
+ chr(0x80 | ($cp & 0x3F));
+ } else {
+ return chr($cp);
+ }
+}
+
+function media2local($media_id, $all = false) {
+ global $_W;
+ load()->model('material');
+ $data = material_get($media_id);
+ if (!is_error($data)) {
+ $data['attachment'] = tomedia($data['attachment'], true);
+ if (!$all) {
+ return $data['attachment'];
+ }
+
+ return $data;
+ } else {
+ return '';
+ }
+}
+
+function aes_decode($message, $encodingaeskey = '', $appid = '') {
+ $key = base64_decode($encodingaeskey . '=');
+
+ $ciphertext_dec = base64_decode($message);
+ $iv = substr($key, 0, 16);
+ $decrypted = openssl_decrypt($ciphertext_dec, 'AES-256-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
+ $block_size = 32;
+
+ $pad = ord(substr($decrypted, -1));
+ if ($pad < 1 || $pad > 32) {
+ $pad = 0;
+ }
+ $result = substr($decrypted, 0, (strlen($decrypted) - $pad));
+ if (strlen($result) < 16) {
+ return '';
+ }
+ $content = substr($result, 16, strlen($result));
+ $len_list = unpack('N', substr($content, 0, 4));
+ $contentlen = $len_list[1];
+ $content = substr($content, 4, $contentlen);
+ $from_appid = substr($content, $xml_len + 4);
+ if (!empty($appid) && $appid != $from_appid) {
+ return '';
+ }
+
+ return $content;
+}
+
+function aes_encode($message, $encodingaeskey = '', $appid = '') {
+ $key = base64_decode($encodingaeskey . '=');
+ $text = random(16) . pack('N', strlen($message)) . $message . $appid;
+
+ $iv = substr($key, 0, 16);
+
+ $block_size = 32;
+ $text_length = strlen($text);
+ $amount_to_pad = $block_size - ($text_length % $block_size);
+ if (0 == $amount_to_pad) {
+ $amount_to_pad = $block_size;
+ }
+ $pad_chr = chr($amount_to_pad);
+ $tmp = '';
+ for ($index = 0; $index < $amount_to_pad; ++$index) {
+ $tmp .= $pad_chr;
+ }
+ $text = $text . $tmp;
+ $encrypted = openssl_encrypt($text, 'AES-256-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
+ $encrypt_msg = base64_encode($encrypted);
+
+ return $encrypt_msg;
+}
+
+
+function aes_pkcs7_decode($encrypt_data, $key, $iv = false) {
+ load()->library('pkcs7');
+ $encrypt_data = base64_decode($encrypt_data);
+ if (!empty($iv)) {
+ $iv = base64_decode($iv);
+ }
+ $pc = new Prpcrypt($key);
+ $result = $pc->decrypt($encrypt_data, $iv);
+ if (0 != $result[0]) {
+ return error($result[0], '解密失败');
+ }
+
+ return $result[1];
+}
+
+
+function isimplexml_load_string($string, $class_name = 'SimpleXMLElement', $options = 0, $ns = '', $is_prefix = false) {
+ libxml_disable_entity_loader(true);
+ if (preg_match('/(\<\!DOCTYPE|\<\!ENTITY)/i', $string)) {
+ return false;
+ }
+ $string = preg_replace('/[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f\\x7f]/', '', $string); return simplexml_load_string($string, $class_name, $options, $ns, $is_prefix);
+}
+
+function ihtml_entity_decode($str) {
+ $str = str_replace(' ', '#nbsp;', $str);
+
+ return str_replace('#nbsp;', ' ', html_entity_decode(urldecode($str)));
+}
+
+function iarray_change_key_case($array, $case = CASE_LOWER) {
+ if (!is_array($array) || empty($array)) {
+ return array();
+ }
+ $array = array_change_key_case($array, $case);
+ foreach ($array as $key => $value) {
+ if (empty($value) && is_array($value)) {
+ $array[$key] = '';
+ }
+ if (!empty($value) && is_array($value)) {
+ $array[$key] = iarray_change_key_case($value, $case);
+ }
+ }
+
+ return $array;
+}
+
+
+function parse_path($path) {
+ $danger_char = array('../', '{php', 'library('pinyin');
+ $pinyin = new Pinyin_Pinyin();
+ }
+ $first_char = $pinyin->get_first_char($str);
+
+ return $first_char;
+}
+
+
+function strip_emoji($nickname) {
+ $clean_text = '';
+ $regexEmoticons = '/[\x{1F600}-\x{1F64F}]/u';
+ $clean_text = preg_replace($regexEmoticons, '_', $nickname);
+ $regexSymbols = '/[\x{1F300}-\x{1F5FF}]/u';
+ $clean_text = preg_replace($regexSymbols, '_', $clean_text);
+ $regexTransport = '/[\x{1F680}-\x{1F6FF}]/u';
+ $clean_text = preg_replace($regexTransport, '_', $clean_text);
+ $regexMisc = '/[\x{2600}-\x{26FF}]/u';
+ $clean_text = preg_replace($regexMisc, '_', $clean_text);
+ $regexDingbats = '/[\x{2700}-\x{27BF}]/u';
+ $clean_text = preg_replace($regexDingbats, '_', $clean_text);
+
+ $clean_text = str_replace("'", '_', $clean_text);
+ $clean_text = str_replace('"', '_', $clean_text);
+ $clean_text = str_replace('“', '_', $clean_text);
+ $clean_text = str_replace('゛', '_', $clean_text);
+ $search = array(' ', ' ', "\n", "\r", "\t");
+ $replace = array('_', '_', '_', '_', '_');
+
+ return str_replace($search, $replace, $clean_text);
+}
+
+
+function emoji_unicode_decode($string) {
+ preg_match_all('/\[U\+(\\w{4,})\]/i', $string, $match);
+ if (!empty($match[1])) {
+ foreach ($match[1] as $emojiUSB) {
+ $string = str_ireplace("[U+{$emojiUSB}]", utf8_bytes(hexdec($emojiUSB)), $string);
+ }
+ }
+
+ return $string;
+}
+
+function emoji_unicode_encode($string) {
+ $ranges = array(
+ '\\\\ud83c[\\\\udf00-\\\\udfff]', '\\\\ud83d[\\\\udc00-\\\\ude4f]', '\\\\ud83d[\\\\ude80-\\\\udeff]', );
+ preg_match_all('/' . implode('|', $ranges) . '/i', $string, $match);
+ print_r($match);
+ exit;
+}
+
+
+if (!function_exists('starts_with')) {
+ function starts_with($haystack, $needles) {
+ foreach ((array) $needles as $needle) {
+ if ('' != $needle && substr($haystack, 0, strlen($needle)) === (string) $needle) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
+
+
+function icall_user_func($callback) {
+ if (function_exists($callback)) {
+ $args = func_get_args();
+ switch (func_num_args()) {
+ case 1:
+ return call_user_func($callback);
+ break;
+ case 2:
+ return call_user_func($callback, $args[1]);
+ break;
+ case 3:
+ return call_user_func($callback, $args[1], $args[2]);
+ break;
+ case 4:
+ return call_user_func($callback, $args[1], $args[2], $args[3]);
+ break;
+ case 5:
+ return call_user_func($callback, $args[1], $args[2], $args[3], $args[4]);
+ break;
+ }
+ }
+
+ return '';
+}
+
+if (!function_exists('dd')) {
+ function dd($data) {
+ echo "";
+ print_r($data);
+ die();
+ }
+}
+
+load()->func('safe');
+load()->func('system');
\ No newline at end of file
diff --git a/framework/function/logging.func.php b/framework/function/logging.func.php
new file mode 100644
index 0000000..a3084eb
--- /dev/null
+++ b/framework/function/logging.func.php
@@ -0,0 +1,59 @@
+func('file');
+ mkdirs(dirname($filename));
+
+ $logFormat = '%date %type %user %url %context';
+ if (!empty($GLOBALS['_POST'])) {
+ $context[] = logging_implode($GLOBALS['_POST']);
+ }
+
+ if (is_array($log)) {
+ $context[] = logging_implode($log);
+ } else {
+ $context[] = preg_replace('/[ \t\r\n]+/', ' ', $log);
+ }
+
+ $log = str_replace(explode(' ', $logFormat), array(
+ '[' . date('Y-m-d H:i:s', $_W['timestamp']) . ']',
+ $type,
+ $_W['username'],
+ $_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING'],
+ implode("\n", $context),
+ ), $logFormat);
+ if (file_exists($filename)) {
+ $log = $log . "\r\n";
+ } else {
+ $log = "\r\n" . $log . "\r\n";
+ }
+ file_put_contents($filename, $log, FILE_APPEND);
+ return true;
+}
+
+function logging_implode($array, $skip = array()) {
+ $return = '';
+ if (is_array($array) && !empty($array)) {
+ foreach ($array as $key => $value) {
+ if (empty($skip) || !in_array($key, $skip, true)) {
+ if (is_array($value)) {
+ $return .= $key . '={' . logging_implode($value, $skip) . '}; ';
+ } else {
+ $return .= "$key=$value; ";
+ }
+ }
+ }
+ }
+
+ return $return;
+}
\ No newline at end of file
diff --git a/framework/function/pdo.func.php b/framework/function/pdo.func.php
new file mode 100644
index 0000000..35ccbb5
--- /dev/null
+++ b/framework/function/pdo.func.php
@@ -0,0 +1,143 @@
+classs('slave.db');
+ $db = new SlaveDb('master');
+ } else {
+ load()->classs('db');
+ if (empty($_W['config']['db']['master'])) {
+ $_W['config']['db']['master'] = $GLOBALS['_W']['config']['db'];
+ }
+ $db = new DB('master');
+ }
+ }
+
+ return $db;
+}
+
+
+function pdos($table = '') {
+ return load()->singleton('Query');
+}
+
+
+function pdo_query($sql, $params = array()) {
+ return pdo()->query($sql, $params);
+}
+
+
+function pdo_fetchcolumn($sql, $params = array(), $column = 0) {
+ return pdo()->fetchcolumn($sql, $params, $column);
+}
+
+function pdo_fetch($sql, $params = array()) {
+ return pdo()->fetch($sql, $params);
+}
+
+function pdo_fetchall($sql, $params = array(), $keyfield = '') {
+ return pdo()->fetchall($sql, $params, $keyfield);
+}
+
+
+function pdo_get($tablename, $condition = array(), $fields = array()) {
+ return pdo()->get($tablename, $condition, $fields);
+}
+
+function pdo_getall($tablename, $condition = array(), $fields = array(), $keyfield = '', $orderby = array(), $limit = array()) {
+ return pdo()->getall($tablename, $condition, $fields, $keyfield, $orderby, $limit);
+}
+
+function pdo_getslice($tablename, $condition = array(), $limit = array(), &$total = null, $fields = array(), $keyfield = '', $orderby = array()) {
+ return pdo()->getslice($tablename, $condition, $limit, $total, $fields, $keyfield, $orderby);
+}
+
+function pdo_getcolumn($tablename, $condition = array(), $field) {
+ return pdo()->getcolumn($tablename, $condition, $field);
+}
+
+
+function pdo_exists($tablename, $condition = array()) {
+ return pdo()->exists($tablename, $condition);
+}
+
+
+function pdo_count($tablename, $condition = array(), $cachetime = 15) {
+ return pdo()->count($tablename, $condition, $cachetime);
+}
+
+
+function pdo_update($table, $data = array(), $params = array(), $glue = 'AND') {
+ return pdo()->update($table, $data, $params, $glue);
+}
+
+
+function pdo_insert($table, $data = array(), $replace = false) {
+ return pdo()->insert($table, $data, $replace);
+}
+
+
+function pdo_delete($table, $params = array(), $glue = 'AND') {
+ return pdo()->delete($table, $params, $glue);
+}
+
+
+function pdo_insertid() {
+ return pdo()->insertid();
+}
+
+
+function pdo_begin() {
+ pdo()->begin();
+}
+
+
+function pdo_commit() {
+ pdo()->commit();
+}
+
+
+function pdo_rollback() {
+ pdo()->rollBack();
+}
+
+
+function pdo_debug($output = true, $append = array()) {
+ return pdo()->debug($output, $append);
+}
+
+function pdo_run($sql) {
+ return pdo()->run($sql);
+}
+
+
+function pdo_fieldexists($tablename, $fieldname = '') {
+ return pdo()->fieldexists($tablename, $fieldname);
+}
+
+function pdo_fieldmatch($tablename, $fieldname, $datatype = '', $length = '') {
+ return pdo()->fieldmatch($tablename, $fieldname, $datatype, $length);
+}
+
+function pdo_indexexists($tablename, $indexname = '') {
+ return pdo()->indexexists($tablename, $indexname);
+}
+
+
+function pdo_fetchallfields($tablename) {
+ $fields = pdo_fetchall("DESCRIBE {$tablename}", array(), 'Field');
+ $fields = array_keys($fields);
+
+ return $fields;
+}
+
+
+function pdo_tableexists($tablename) {
+ return pdo()->tableexists($tablename);
+}
diff --git a/framework/function/safe.func.php b/framework/function/safe.func.php
new file mode 100644
index 0000000..fb957ed
--- /dev/null
+++ b/framework/function/safe.func.php
@@ -0,0 +1,245 @@
+ $url) {
+ $val = str_replace($url, 'we7_' . $key . '_we7placeholder', $val);
+ $encode_url_list[] = $url;
+ }
+ }
+ $ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'frameset', 'ilayer', 'bgsound', 'base');
+ $ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload', '@import');
+ $ra = array_merge($ra1, $ra2);
+ $found = true;
+ while (true == $found) {
+ $val_before = $val;
+ for ($i = 0; $i < sizeof($ra); ++$i) {
+ $pattern = '/';
+ for ($j = 0; $j < strlen($ra[$i]); ++$j) {
+ if ($j > 0) {
+ $pattern .= '(';
+ $pattern .= '([xX]0{0,8}([9ab]);)';
+ $pattern .= '|';
+ $pattern .= '|({0,8}([9|10|13]);)';
+ $pattern .= ')*';
+ }
+ $pattern .= $ra[$i][$j];
+ }
+ $pattern .= '/i';
+ $replacement = substr($ra[$i], 0, 2) . '' . substr($ra[$i], 2);
+ $val = preg_replace($pattern, $replacement, $val);
+ if ($val_before == $val) {
+ $found = false;
+ }
+ }
+ }
+ if (!empty($encode_url_list) && is_array($encode_url_list)) {
+ foreach ($encode_url_list as $key => $url) {
+ $val = str_replace('we7_' . $key . '_we7placeholder', $url, $val);
+ }
+ }
+
+ return $val;
+}
+
+function safe_bad_str_replace($string)
+{
+ if (empty($string)) {
+ return '';
+ }
+ $badstr = array("\0", '%00', '%3C', '%3E', '', '<%', ' "'|(and|or)\\b.+?(>|<|=|in|like)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)",
+ 'p' => '\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)',
+ 'c' => '\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)',
+ );
+ if (!isset($values)) {
+ return '';
+ }
+ if (is_array($values)) {
+ foreach ($values as $key => $val) {
+ $values[addslashes($key)] = strip_gpc($val, $type);
+ }
+ } else {
+ if (1 == preg_match('/' . $filter[$type] . '/is', $values, $match)) {
+ $values = '';
+ }
+ }
+
+ return $values;
+ }
+}
diff --git a/framework/function/tpl.func.php b/framework/function/tpl.func.php
new file mode 100644
index 0000000..9cd4e2b
--- /dev/null
+++ b/framework/function/tpl.func.php
@@ -0,0 +1,577 @@
+app('tpl');
+} else {
+ load()->web('tpl');
+}
+
+function tpl_form_field_date($name, $value = '', $withtime = false) {
+ return _tpl_form_field_date($name, $value, $withtime);
+}
+
+function tpl_form_field_clock($name, $value = '') {
+ $s = '';
+ if (!defined('TPL_INIT_CLOCK_TIME')) {
+ $s .= '
+
+ ';
+ define('TPL_INIT_CLOCK_TIME', 1);
+ }
+ $time = date('H:i');
+ if (!empty($value)) {
+ if (!strexists($value, ':')) {
+ $time = date('H:i', $value);
+ } else {
+ $time = $value;
+ }
+ }
+ $s .= '
+
+
+
';
+
+ return $s;
+}
+
+
+function tpl_form_field_daterange($name, $value = array(), $time = false, $clear = true) {
+ $s = '';
+
+ if (empty($time) && !defined('TPL_INIT_DATERANGE_DATE')) {
+ $s = '
+
+';
+ define('TPL_INIT_DATERANGE_DATE', true);
+ }
+
+ if (!empty($time) && !defined('TPL_INIT_DATERANGE_TIME')) {
+ $s = '
+
+';
+ define('TPL_INIT_DATERANGE_TIME', true);
+ }
+ if (!empty($value['starttime']) || !empty($value['start'])) {
+ if ($value['start'] && strtotime($value['start'])) {
+ $value['starttime'] = empty($time) ? date('Y-m-d', strtotime($value['start'])) : date('Y-m-d H:i', strtotime($value['start']));
+ }
+ $value['starttime'] = empty($value['starttime']) ? '' : $value['starttime'];
+ } else {
+ $value['starttime'] = '';
+ }
+
+ if (!empty($value['endtime']) || !empty($value['end'])) {
+ if ($value['end'] && strtotime($value['end'])) {
+ $value['endtime'] = empty($time) ? date('Y-m-d', strtotime($value['end'])) : date('Y-m-d H:i', strtotime($value['end']));
+ }
+ $value['endtime'] = empty($value['endtime']) ? $value['starttime'] : $value['endtime'];
+ } else {
+ $value['endtime'] = '';
+ }
+ $s .= '
+
+
+ ' .
+ ($value['starttime'] == "" ? "不限时间" : $value['starttime']) . ($value['starttime'] == "" && $value['endtime'] === "" ? "" : (" 至" . $value['endtime'])) . '
+ ';
+
+ return $s;
+}
+
+
+function tpl_form_field_calendar($name, $values = array()) {
+ $html = '';
+ if (!defined('TPL_INIT_CALENDAR')) {
+ $html .= '
+ ';
+ define('TPL_INIT_CALENDAR', true);
+ }
+
+ if (empty($values) || !is_array($values)) {
+ $values = array(0, 0, 0);
+ }
+ $values['year'] = intval($values['year']);
+ $values['month'] = intval($values['month']);
+ $values['day'] = intval($values['day']);
+
+ if (empty($values['year'])) {
+ $values['year'] = '1980';
+ }
+ $year = array(date('Y'), '1914');
+ $html .= '
+
+
+ 年 ';
+ for ($i = $year[1]; $i <= $year[0]; ++$i) {
+ $html .= '' . $i . ' ';
+ }
+ $html .= '
+
+
+
+ 月 ';
+ for ($i = 1; $i <= 12; ++$i) {
+ $html .= '' . $i . ' ';
+ }
+ $html .= '
+
+
+
+ 日
+
+
+
';
+
+ return $html;
+}
+
+
+function tpl_form_field_district($name, $values = array()) {
+ $html = '';
+ if (!defined('TPL_INIT_DISTRICT')) {
+ $html .= '
+ ';
+ define('TPL_INIT_DISTRICT', true);
+ }
+ if (empty($values) || !is_array($values)) {
+ $values = array('province' => '', 'city' => '', 'district' => '');
+ }
+ if (empty($values['province'])) {
+ $values['province'] = '';
+ }
+ if (empty($values['city'])) {
+ $values['city'] = '';
+ }
+ if (empty($values['district'])) {
+ $values['district'] = '';
+ }
+ $html .= '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
';
+
+ return $html;
+}
+
+
+function tpl_form_field_category_2level($name, $parents, $children, $parentid, $childid) {
+ $html = '
+ ';
+ if (!defined('TPL_INIT_CATEGORY')) {
+ $html .= '
+
+ ';
+ define('TPL_INIT_CATEGORY', true);
+ }
+
+ $html .=
+ '
+
+
+ 请选择一级分类 ';
+ $ops = '';
+ if (!empty($parents)) {
+ foreach ($parents as $row) {
+ $html .= '
+ ' . $row['name'] . ' ';
+ }
+ }
+
+ $html .= '
+
+
+
+
+ 请选择二级分类 ';
+ if (!empty($parentid) && !empty($children[$parentid])) {
+ foreach ($children[$parentid] as $row) {
+ $html .= '
+ ' . $row['name'] . ' ';
+ }
+ }
+ $html .= '
+
+
+
+ ';
+
+ return $html;
+}
+
+
+function tpl_form_field_industry($name, $pvalue = '', $cvalue = '', $parentid = 'industry_1', $childid = 'industry_2') {
+ $html = '
+ ';
+
+ return $html;
+}
+
+
+function tpl_form_field_coordinate($field, $value = array()) {
+ $s = '';
+ if (!defined('TPL_INIT_COORDINATE')) {
+ $s .= '';
+ define('TPL_INIT_COORDINATE', true);
+ }
+ $s .= '
+ ';
+
+ return $s;
+}
+
+
+function tpl_fans_form($field, $value = '') {
+ switch ($field) {
+ case 'avatar':
+ $avatar_url = '../attachment/images/global/avatars/';
+ $html = '';
+ if (!defined('TPL_INIT_AVATAR')) {
+ $html .= '
+ ';
+ define('TPL_INIT_AVATAR', true);
+ }
+ if (!defined('TPL_INIT_IMAGE')) {
+ global $_W;
+ if (defined('IN_MOBILE')) {
+ $html .= <<
+ // in mobile
+ function showImageDialog(elm) {
+ require(["jquery", "util"], function($, util){
+ var btn = $(elm);
+ var ipt = btn.parent().prev();
+ var val = ipt.val();
+ var img = ipt.parent().next().children();
+ util.image(elm, function(url){
+ img.get(0).src = url.url;
+ ipt.val(url.attachment);
+ });
+ });
+ }
+
+EOF;
+ } else {
+ $html .= <<
+ // in web
+ function showImageDialog(elm, opts) {
+ require(["util"], function(util){
+ var btn = $(elm);
+ var ipt = btn.parent().prev();
+ var val = ipt.val();
+ var img = ipt.parent().next().find('img');
+ util.image(val, function(url){
+ img.get(0).src = url.url;
+ ipt.val(url.attachment);
+ }, {multiple:false,type:"image",direct:true}, opts);
+ });
+ }
+
+EOF;
+ }
+ define('TPL_INIT_IMAGE', true);
+ }
+ $val = './resource/images/nopic.jpg';
+ if (!empty($value)) {
+ $val = tomedia($value);
+ }
+ $options = array();
+ $options['width'] = '200';
+ $options['height'] = '200';
+
+ if (defined('IN_MOBILE')) {
+ $html .= <<
+
+
+ 选择图片
+ 系统头像
+
+
+
+EOF;
+ } else {
+ $html .= '
+
+
+
+ 选择图片
+ 系统头像
+
+
+ ';
+ }
+
+ break;
+ case 'birth':
+ case 'birthyear':
+ case 'birthmonth':
+ case 'birthday':
+ $html = tpl_form_field_calendar('birth', $value);
+ break;
+ case 'reside':
+ case 'resideprovince':
+ case 'residecity':
+ case 'residedist':
+ $html = tpl_form_field_district('reside', $value);
+ break;
+ case 'bio':
+ case 'interest':
+ $html = '';
+ break;
+ case 'gender':
+ $html = '
+
+ 保密
+ 男
+ 女
+ ';
+ break;
+ case 'education':
+ case 'constellation':
+ case 'zodiac':
+ case 'bloodtype':
+ if ('bloodtype' == $field) {
+ $options = array('A', 'B', 'AB', 'O', '其它');
+ } elseif ('zodiac' == $field) {
+ $options = array('鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪');
+ } elseif ('constellation' == $field) {
+ $options = array('水瓶座', '双鱼座', '白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座');
+ } elseif ('education' == $field) {
+ $options = array('博士', '硕士', '本科', '专科', '中学', '小学', '其它');
+ }
+ $html = '';
+ foreach ($options as $item) {
+ $html .= '' . $item . ' ';
+ }
+ $html .= ' ';
+ break;
+ case 'nickname':
+ case 'realname':
+ case 'address':
+ case 'mobile':
+ case 'qq':
+ case 'msn':
+ case 'email':
+ case 'telephone':
+ case 'taobao':
+ case 'alipay':
+ case 'studentid':
+ case 'grade':
+ case 'graduateschool':
+ case 'idcard':
+ case 'zipcode':
+ case 'site':
+ case 'affectivestatus':
+ case 'lookingfor':
+ case 'nationality':
+ case 'height':
+ case 'weight':
+ case 'company':
+ case 'occupation':
+ case 'position':
+ case 'revenue':
+ default:
+ $html = ' ';
+ break;
+ }
+
+ return $html;
+}
\ No newline at end of file
diff --git a/framework/library/agent/agent.class.php b/framework/library/agent/agent.class.php
new file mode 100644
index 0000000..6e085d7
--- /dev/null
+++ b/framework/library/agent/agent.class.php
@@ -0,0 +1,193 @@
+ self::deviceType(),
+ 'browserType' => self::browserType(),
+ 'isRetina' => self::isRetina(),
+ 'osType' => self::osType(),
+ 'isIos6' => self::isIos6(),
+ );
+ }
+
+ // 浏览器类型
+ public static function browserType($agent = '')
+ {
+ $agent = self::getAgent($agent);
+ if (stripos($agent, 'baiduboxapp') !== false) {
+ return self::BROWSER_TYPE_XZAPP;
+ }
+
+ if (stripos($agent, 'iphone') !== false) {
+ return self::BROWSER_TYPE_IPHONE;
+ }
+
+ if (stripos($agent, 'ipad') !== false) {
+ return self::BROWSER_TYPE_IPAD;
+ }
+
+ if (stripos($agent, 'ipod') !== false) {
+ return self::BROWSER_TYPE_IPOD;
+ }
+
+ if (stripos($agent, 'android') !== false) {
+ return self::BROWSER_TYPE_ANDROID;
+ }
+
+ return self::BROWSER_TYPE_UNKNOWN;
+ }
+
+ // 系统类型
+ public static function osType($agent = '')
+ {
+ $agent = self::getAgent($agent);
+ $browserType = self::browserType($agent);
+
+ switch ($browserType) {
+ case self::BROWSER_TYPE_IPHONE:
+ case self::BROWSER_TYPE_IPAD:
+ case self::BROWSER_TYPE_IPOD:
+ $osType = self::OS_TYPE_IOS;
+ break;
+ case self::BROWSER_TYPE_ANDROID:
+ $osType = self::OS_TYPE_ANDROID;
+ break;
+ default:
+ $osType = self::OS_TYPE_UNKNOWN;
+ }
+
+ return $osType;
+ }
+
+ // 设备类型
+ public static function deviceType()
+ {
+ if (self::isMobile()) {
+ return self::DEVICE_MOBILE;
+ } else {
+ return self::DEVICE_DESKTOP;
+ }
+ }
+
+ // retina屏
+ public static function isRetina($agent = '')
+ {
+ $agent = self::getAgent($agent);
+ $osType = self::osType($agent);
+
+ if (($osType == self::OS_TYPE_IOS) && (self::isIos6($agent) != 1)) {
+ return self::RETINA_TYPE_YES;
+ } else {
+ return self::RETINA_TYPE_NOT;
+ }
+ }
+
+ // ios6系统的手机(iphone4, iphone4s)
+ public static function isIos6($agent = '')
+ {
+ $agent = self::getAgent($agent);
+
+ if (stripos($agent, 'iPhone OS 6')) {
+ return self::IOS6_YES;
+ } else {
+ return self::IOS6_NOT;
+ }
+ }
+ // 检查是否在微信中打开
+ public static function isMicroMessage($agent = '')
+ {
+ $agent = self::getAgent($agent);
+
+ if (stripos($agent, 'MicroMessenger') !== false) {
+ return self::MICRO_MESSAGE_YES;
+ } else {
+ return self::MICRO_MESSAGE_NOT;
+ }
+ }
+
+ // 已安装APP
+ public static function isAppInstalled()
+ {
+ if (isset($_GET['isappinstalled']) && ($_GET['isappinstalled'] == 1)) {
+ return self::APP_INSTALLED_YES;
+ } else {
+ return self::APP_INSTALLED_NOT;
+ }
+ }
+
+ // 是移动设备访问
+ public static function isMobile()
+ {
+ // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
+ if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
+ return true;
+ }
+ // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
+ if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], "wap")) {
+ return true;
+ }
+ // 脑残法,判断手机发送的客户端标志,兼容性有待提高
+ if (isset ($_SERVER['HTTP_USER_AGENT'])) {
+ $clientkeywords = array('nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp',
+ 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu',
+ 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave',
+ 'nexusone', 'cldc', 'midp', 'wap', 'mobile', 'WindowsWechat');
+ // 从HTTP_USER_AGENT中查找手机浏览器的关键字
+ if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
+ return true;
+ }
+ }
+ // 协议法,因为有可能不准确,放到最后判断
+ if (isset($_SERVER['HTTP_ACCEPT'])) {
+ // 如果只支持wml并且不支持html那一定是移动设备, 如果支持wml和html但是wml在html之前则是移动设备
+ if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static function getAgent($agent = '')
+ {
+ $agent = empty($agent) ? $_SERVER['HTTP_USER_AGENT'] : $agent;
+ return $agent;
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/CHANGELOG.md b/framework/library/alioss/CHANGELOG.md
new file mode 100644
index 0000000..b269c96
--- /dev/null
+++ b/framework/library/alioss/CHANGELOG.md
@@ -0,0 +1,57 @@
+# ChangeLog - Aliyun OSS SDK for PHP
+
+## v2.0.7 / 2016-06-17
+
+* Support append object
+
+## v2.0.6
+
+* Trim access key id/secret and endpoint
+* Refine tests and setup travis CI
+
+## v2.0.5
+
+* 增加Add/Delete/Get BucketCname接口
+
+## v2.0.4
+
+* 增加Put/Get Object Acl接口
+
+## v2.0.3
+
+* 修复Util中的常量定义在低于5.6的PHP版本中报错的问题
+
+## v2.0.2
+
+* 修复multipart上传时无法指定Content-Type的问题
+
+## v2.0.1
+
+* 增加对ListObjects/ListMultipartUploads时特殊字符的处理
+* 提供接口获取OssException中的详细信息
+
+
+## 2015.11.25
+
+* **大版本升级,不再兼容以前接口,新版本对易用性做了很大的改进,建议用户迁移到新版本。**
+
+## 修改内容
+
+* 不再支持PHP 5.2版本
+
+### 新增内容
+
+* 引入命名空间
+* 接口命名修正,采用驼峰式命名
+* 接口入参修改,把常用参数从Options参数中提出来
+* 接口返回结果修改,对返回结果进行处理,用户可以直接得到容易处理的数据结构
+* OssClient的构造函数变更
+* 支持CNAME和IP格式的Endpoint地址
+* 重新整理sample文件组织结构,使用function组织功能点
+* 增加设置连接超时,请求超时的接口
+* 去掉Object Group相关的已经过时的接口
+* OssException中的message改为英文
+
+### 问题修复
+
+* object名称校验不完备
diff --git a/framework/library/alioss/LICENSE.md b/framework/library/alioss/LICENSE.md
new file mode 100644
index 0000000..3183de8
--- /dev/null
+++ b/framework/library/alioss/LICENSE.md
@@ -0,0 +1,21 @@
+#The MIT License (MIT)
+
+Copyright (c) ali-sdk and other contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/framework/library/alioss/README.md b/framework/library/alioss/README.md
new file mode 100644
index 0000000..1549dda
--- /dev/null
+++ b/framework/library/alioss/README.md
@@ -0,0 +1,152 @@
+# Aliyun OSS SDK for PHP
+
+[](https://packagist.org/packages/aliyuncs/oss-sdk-php)
+[](https://travis-ci.org/aliyun/aliyun-oss-php-sdk)
+[](https://coveralls.io/github/aliyun/aliyun-oss-php-sdk?branch=master)
+
+## 概述
+
+阿里云对象存储(Object Storage Service,简称OSS),是阿里云对外提供的海量、安全、低成本、高可靠的云存储服务。用户可以通过调用API,在任何应用、任何时间、任何地点上传和下载数据,也可以通过用户Web控制台对数据进行简单的管理。OSS适合存放任意文件类型,适合各种网站、开发企业及开发者使用。
+
+
+## 运行环境
+- PHP 5.3+
+- cURL extension
+
+提示:
+
+- Ubuntu下可以使用apt-get包管理器安装php的cURL扩展 `sudo apt-get install php5-curl`
+
+## 安装方法
+
+1. 如果您通过composer管理您的项目依赖,可以在你的项目根目录运行:
+
+ $ composer require aliyuncs/oss-sdk-php
+
+ 或者在你的`composer.json`中声明对Aliyun OSS SDK for PHP的依赖:
+
+ "require": {
+ "aliyuncs/oss-sdk-php": "~2.0"
+ }
+
+ 然后通过`composer install`安装依赖。composer安装完成后,在您的PHP代码中引入依赖即可:
+
+ require_once __DIR__ . '/vendor/autoload.php';
+
+2. 您也可以直接下载已经打包好的[phar文件][releases-page],然后在你
+ 的代码中引入这个文件即可:
+
+ require_once '/path/to/oss-sdk-php.phar';
+
+3. 下载SDK源码,在您的代码中引入SDK目录下的`autoload.php`文件:
+
+ require_once '/path/to/oss-sdk/autoload.php';
+
+## 快速使用
+
+### 常用类
+
+| 类名 | 解释 |
+|:------------------|:------------------------------------|
+|OSS\OssClient | OSS客户端类,用户通过OssClient的实例调用接口 |
+|OSS\Core\OssException | OSS异常类,用户在使用的过程中,只需要注意这个异常|
+
+### OssClient初始化
+
+SDK的OSS操作通过OssClient类完成的,下面代码创建一个OssClient对象:
+
+```php
+"; ;
+$accessKeySecret = "<您从OSS获得的AccessKeySecret>";
+$endpoint = "<您选定的OSS数据中心访问域名,例如oss-cn-hangzhou.aliyuncs.com>";
+try {
+ $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
+} catch (OssException $e) {
+ print $e->getMessage();
+}
+```
+
+### 文件操作
+
+文件(又称对象,Object)是OSS中最基本的数据单元,您可以把它简单地理解为文件,用下面代码可以实现一个Object的上传:
+
+```php
+";
+$object = "<您使用的Object名字,注意命名规范>";
+$content = "Hello, OSS!"; // 上传的文件内容
+try {
+ $ossClient->putObject($bucket, $object, $content);
+} catch (OssException $e) {
+ print $e->getMessage();
+}
+```
+
+### 存储空间操作
+
+存储空间(又称Bucket)是一个用户用来管理所存储Object的存储空间,对于用户来说是一个管理Object的单元,所有的Object都必须隶属于某个Bucket。您可以按照下面的代码新建一个Bucket:
+
+```php
+";
+try {
+ $ossClient->createBucket($bucket);
+} catch (OssException $e) {
+ print $e->getMessage();
+}
+```
+
+### 返回结果处理
+
+OssClient提供的接口返回返回数据分为两种:
+
+* Put,Delete类接口,接口返回null,如果没有OssException,即可认为操作成功
+* Get,List类接口,接口返回对应的数据,如果没有OssException,即可认为操作成功,举个例子:
+
+```php
+listBuckets();
+$bucketList = $bucketListInfo->getBucketList();
+foreach($bucketList as $bucket) {
+ print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreatedate() . "\n");
+}
+```
+上面代码中的$bucketListInfo的数据类型是 `OSS\Model\BucketListInfo`
+
+
+### 运行Sample程序
+
+1. 修改 `samples/Config.php`, 补充配置信息
+2. 执行 `cd samples/ && php RunAll.php`
+
+### 运行单元测试
+
+1. 执行`composer install`下载依赖的库
+2. 设置环境变量
+
+ export OSS_ACCESS_KEY_ID=access-key-id
+ export OSS_ACCESS_KEY_SECRET=access-key-secret
+ export OSS_ENDPOINT=endpoint
+ export OSS_BUCKET=bucket-name
+
+3. 执行 `php vendor/bin/phpunit`
+
+## 贡献代码
+
+0. 开发流程参考:https://github.com/rockuw/oss-sdk-status#development-oss-members-only
+1. 提交代码后,确保travis CI是PASS的
+2. 每发布一个新的版本:
+ - 运行`build-phar.sh`生成相应的phar包(需要安装[phar-composer][phar-composer])
+ - 在[Release页面][releases-page]发布一个版本
+ - 将生成的phar包上传到相应的Release下面
+
+## 联系我们
+
+- [阿里云OSS官方网站](http://oss.aliyun.com)
+- [阿里云OSS官方论坛](http://bbs.aliyun.com)
+- [阿里云OSS官方文档中心](http://www.aliyun.com/product/oss#Docs)
+- 阿里云官方技术支持:[提交工单](https://workorder.console.aliyun.com/#/ticket/createIndex)
+
+[releases-page]: https://github.com/aliyun/aliyun-oss-php-sdk/releases
+[phar-composer]: https://github.com/clue/phar-composer
diff --git a/framework/library/alioss/autoload.php b/framework/library/alioss/autoload.php
new file mode 100644
index 0000000..ec13201
--- /dev/null
+++ b/framework/library/alioss/autoload.php
@@ -0,0 +1,11 @@
+ 1) {
+ $ext = strtolower(end($parts));
+ if (isset(self::$mime_types[$ext])) {
+ return self::$mime_types[$ext];
+ }
+ }
+
+ return null;
+ }
+
+ private static $mime_types = array(
+ 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
+ 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
+ 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
+ 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+ 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+ 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
+ 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
+ 'apk' => 'application/vnd.android.package-archive',
+ 'hqx' => 'application/mac-binhex40',
+ 'cpt' => 'application/mac-compactpro',
+ 'doc' => 'application/msword',
+ 'ogg' => 'audio/ogg',
+ 'pdf' => 'application/pdf',
+ 'rtf' => 'text/rtf',
+ 'mif' => 'application/vnd.mif',
+ 'xls' => 'application/vnd.ms-excel',
+ 'ppt' => 'application/vnd.ms-powerpoint',
+ 'odc' => 'application/vnd.oasis.opendocument.chart',
+ 'odb' => 'application/vnd.oasis.opendocument.database',
+ 'odf' => 'application/vnd.oasis.opendocument.formula',
+ 'odg' => 'application/vnd.oasis.opendocument.graphics',
+ 'otg' => 'application/vnd.oasis.opendocument.graphics-template',
+ 'odi' => 'application/vnd.oasis.opendocument.image',
+ 'odp' => 'application/vnd.oasis.opendocument.presentation',
+ 'otp' => 'application/vnd.oasis.opendocument.presentation-template',
+ 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
+ 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
+ 'odt' => 'application/vnd.oasis.opendocument.text',
+ 'odm' => 'application/vnd.oasis.opendocument.text-master',
+ 'ott' => 'application/vnd.oasis.opendocument.text-template',
+ 'oth' => 'application/vnd.oasis.opendocument.text-web',
+ 'sxw' => 'application/vnd.sun.xml.writer',
+ 'stw' => 'application/vnd.sun.xml.writer.template',
+ 'sxc' => 'application/vnd.sun.xml.calc',
+ 'stc' => 'application/vnd.sun.xml.calc.template',
+ 'sxd' => 'application/vnd.sun.xml.draw',
+ 'std' => 'application/vnd.sun.xml.draw.template',
+ 'sxi' => 'application/vnd.sun.xml.impress',
+ 'sti' => 'application/vnd.sun.xml.impress.template',
+ 'sxg' => 'application/vnd.sun.xml.writer.global',
+ 'sxm' => 'application/vnd.sun.xml.math',
+ 'sis' => 'application/vnd.symbian.install',
+ 'wbxml' => 'application/vnd.wap.wbxml',
+ 'wmlc' => 'application/vnd.wap.wmlc',
+ 'wmlsc' => 'application/vnd.wap.wmlscriptc',
+ 'bcpio' => 'application/x-bcpio',
+ 'torrent' => 'application/x-bittorrent',
+ 'bz2' => 'application/x-bzip2',
+ 'vcd' => 'application/x-cdlink',
+ 'pgn' => 'application/x-chess-pgn',
+ 'cpio' => 'application/x-cpio',
+ 'csh' => 'application/x-csh',
+ 'dvi' => 'application/x-dvi',
+ 'spl' => 'application/x-futuresplash',
+ 'gtar' => 'application/x-gtar',
+ 'hdf' => 'application/x-hdf',
+ 'jar' => 'application/java-archive',
+ 'jnlp' => 'application/x-java-jnlp-file',
+ 'js' => 'application/javascript',
+ 'json' => 'application/json',
+ 'ksp' => 'application/x-kspread',
+ 'chrt' => 'application/x-kchart',
+ 'kil' => 'application/x-killustrator',
+ 'latex' => 'application/x-latex',
+ 'rpm' => 'application/x-rpm',
+ 'sh' => 'application/x-sh',
+ 'shar' => 'application/x-shar',
+ 'swf' => 'application/x-shockwave-flash',
+ 'sit' => 'application/x-stuffit',
+ 'sv4cpio' => 'application/x-sv4cpio',
+ 'sv4crc' => 'application/x-sv4crc',
+ 'tar' => 'application/x-tar',
+ 'tcl' => 'application/x-tcl',
+ 'tex' => 'application/x-tex',
+ 'man' => 'application/x-troff-man',
+ 'me' => 'application/x-troff-me',
+ 'ms' => 'application/x-troff-ms',
+ 'ustar' => 'application/x-ustar',
+ 'src' => 'application/x-wais-source',
+ 'zip' => 'application/zip',
+ 'm3u' => 'audio/x-mpegurl',
+ 'ra' => 'audio/x-pn-realaudio',
+ 'wav' => 'audio/x-wav',
+ 'wma' => 'audio/x-ms-wma',
+ 'wax' => 'audio/x-ms-wax',
+ 'pdb' => 'chemical/x-pdb',
+ 'xyz' => 'chemical/x-xyz',
+ 'bmp' => 'image/bmp',
+ 'gif' => 'image/gif',
+ 'ief' => 'image/ief',
+ 'png' => 'image/png',
+ 'wbmp' => 'image/vnd.wap.wbmp',
+ 'ras' => 'image/x-cmu-raster',
+ 'pnm' => 'image/x-portable-anymap',
+ 'pbm' => 'image/x-portable-bitmap',
+ 'pgm' => 'image/x-portable-graymap',
+ 'ppm' => 'image/x-portable-pixmap',
+ 'rgb' => 'image/x-rgb',
+ 'xbm' => 'image/x-xbitmap',
+ 'xpm' => 'image/x-xpixmap',
+ 'xwd' => 'image/x-xwindowdump',
+ 'css' => 'text/css',
+ 'rtx' => 'text/richtext',
+ 'tsv' => 'text/tab-separated-values',
+ 'jad' => 'text/vnd.sun.j2me.app-descriptor',
+ 'wml' => 'text/vnd.wap.wml',
+ 'wmls' => 'text/vnd.wap.wmlscript',
+ 'etx' => 'text/x-setext',
+ 'mxu' => 'video/vnd.mpegurl',
+ 'flv' => 'video/x-flv',
+ 'wm' => 'video/x-ms-wm',
+ 'wmv' => 'video/x-ms-wmv',
+ 'wmx' => 'video/x-ms-wmx',
+ 'wvx' => 'video/x-ms-wvx',
+ 'avi' => 'video/x-msvideo',
+ 'movie' => 'video/x-sgi-movie',
+ 'ice' => 'x-conference/x-cooltalk',
+ '3gp' => 'video/3gpp',
+ 'ai' => 'application/postscript',
+ 'aif' => 'audio/x-aiff',
+ 'aifc' => 'audio/x-aiff',
+ 'aiff' => 'audio/x-aiff',
+ 'asc' => 'text/plain',
+ 'atom' => 'application/atom+xml',
+ 'au' => 'audio/basic',
+ 'bin' => 'application/octet-stream',
+ 'cdf' => 'application/x-netcdf',
+ 'cgm' => 'image/cgm',
+ 'class' => 'application/octet-stream',
+ 'dcr' => 'application/x-director',
+ 'dif' => 'video/x-dv',
+ 'dir' => 'application/x-director',
+ 'djv' => 'image/vnd.djvu',
+ 'djvu' => 'image/vnd.djvu',
+ 'dll' => 'application/octet-stream',
+ 'dmg' => 'application/octet-stream',
+ 'dms' => 'application/octet-stream',
+ 'dtd' => 'application/xml-dtd',
+ 'dv' => 'video/x-dv',
+ 'dxr' => 'application/x-director',
+ 'eps' => 'application/postscript',
+ 'exe' => 'application/octet-stream',
+ 'ez' => 'application/andrew-inset',
+ 'gram' => 'application/srgs',
+ 'grxml' => 'application/srgs+xml',
+ 'gz' => 'application/x-gzip',
+ 'htm' => 'text/html',
+ 'html' => 'text/html',
+ 'ico' => 'image/x-icon',
+ 'ics' => 'text/calendar',
+ 'ifb' => 'text/calendar',
+ 'iges' => 'model/iges',
+ 'igs' => 'model/iges',
+ 'jp2' => 'image/jp2',
+ 'jpe' => 'image/jpeg',
+ 'jpeg' => 'image/jpeg',
+ 'jpg' => 'image/jpeg',
+ 'kar' => 'audio/midi',
+ 'lha' => 'application/octet-stream',
+ 'lzh' => 'application/octet-stream',
+ 'm4a' => 'audio/mp4a-latm',
+ 'm4p' => 'audio/mp4a-latm',
+ 'm4u' => 'video/vnd.mpegurl',
+ 'm4v' => 'video/x-m4v',
+ 'mac' => 'image/x-macpaint',
+ 'mathml' => 'application/mathml+xml',
+ 'mesh' => 'model/mesh',
+ 'mid' => 'audio/midi',
+ 'midi' => 'audio/midi',
+ 'mov' => 'video/quicktime',
+ 'mp2' => 'audio/mpeg',
+ 'mp3' => 'audio/mpeg',
+ 'mp4' => 'video/mp4',
+ 'mpe' => 'video/mpeg',
+ 'mpeg' => 'video/mpeg',
+ 'mpg' => 'video/mpeg',
+ 'mpga' => 'audio/mpeg',
+ 'msh' => 'model/mesh',
+ 'nc' => 'application/x-netcdf',
+ 'oda' => 'application/oda',
+ 'ogv' => 'video/ogv',
+ 'pct' => 'image/pict',
+ 'pic' => 'image/pict',
+ 'pict' => 'image/pict',
+ 'pnt' => 'image/x-macpaint',
+ 'pntg' => 'image/x-macpaint',
+ 'ps' => 'application/postscript',
+ 'qt' => 'video/quicktime',
+ 'qti' => 'image/x-quicktime',
+ 'qtif' => 'image/x-quicktime',
+ 'ram' => 'audio/x-pn-realaudio',
+ 'rdf' => 'application/rdf+xml',
+ 'rm' => 'application/vnd.rn-realmedia',
+ 'roff' => 'application/x-troff',
+ 'sgm' => 'text/sgml',
+ 'sgml' => 'text/sgml',
+ 'silo' => 'model/mesh',
+ 'skd' => 'application/x-koan',
+ 'skm' => 'application/x-koan',
+ 'skp' => 'application/x-koan',
+ 'skt' => 'application/x-koan',
+ 'smi' => 'application/smil',
+ 'smil' => 'application/smil',
+ 'snd' => 'audio/basic',
+ 'so' => 'application/octet-stream',
+ 'svg' => 'image/svg+xml',
+ 't' => 'application/x-troff',
+ 'texi' => 'application/x-texinfo',
+ 'texinfo' => 'application/x-texinfo',
+ 'tif' => 'image/tiff',
+ 'tiff' => 'image/tiff',
+ 'tr' => 'application/x-troff',
+ 'txt' => 'text/plain',
+ 'vrml' => 'model/vrml',
+ 'vxml' => 'application/voicexml+xml',
+ 'webm' => 'video/webm',
+ 'webp' => 'image/webp',
+ 'wrl' => 'model/vrml',
+ 'xht' => 'application/xhtml+xml',
+ 'xhtml' => 'application/xhtml+xml',
+ 'xml' => 'application/xml',
+ 'xsl' => 'application/xml',
+ 'xslt' => 'application/xslt+xml',
+ 'xul' => 'application/vnd.mozilla.xul+xml',
+ );
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Core/OssException.php b/framework/library/alioss/src/OSS/Core/OssException.php
new file mode 100644
index 0000000..b0e9e8b
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Core/OssException.php
@@ -0,0 +1,54 @@
+details = $details;
+ } else {
+ $message = $details;
+ parent::__construct($message);
+ }
+ }
+
+ public function getHTTPStatus()
+ {
+ return isset($this->details['status']) ? $this->details['status'] : '';
+ }
+
+ public function getRequestId()
+ {
+ return isset($this->details['request-id']) ? $this->details['request-id'] : '';
+ }
+
+ public function getErrorCode()
+ {
+ return isset($this->details['code']) ? $this->details['code'] : '';
+ }
+
+ public function getErrorMessage()
+ {
+ return isset($this->details['message']) ? $this->details['message'] : '';
+ }
+
+ public function getDetails()
+ {
+ return isset($this->details['body']) ? $this->details['body'] : '';
+ }
+}
diff --git a/framework/library/alioss/src/OSS/Core/OssUtil.php b/framework/library/alioss/src/OSS/Core/OssUtil.php
new file mode 100644
index 0000000..b70680e
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Core/OssUtil.php
@@ -0,0 +1,448 @@
+ $value) {
+ if (is_string($key) && !is_array($value)) {
+ $temp[] = rawurlencode($key) . '=' . rawurlencode($value);
+ }
+ }
+ return implode('&', $temp);
+ }
+
+ /**
+ * 转义字符替换
+ *
+ * @param string $subject
+ * @return string
+ */
+ public static function sReplace($subject)
+ {
+ $search = array('<', '>', '&', '\'', '"');
+ $replace = array('<', '>', '&', ''', '"');
+ return str_replace($search, $replace, $subject);
+ }
+
+ /**
+ * 检查是否是中文编码
+ *
+ * @param $str
+ * @return int
+ */
+ public static function chkChinese($str)
+ {
+ return preg_match('/[\x80-\xff]./', $str);
+ }
+
+ /**
+ * 检测是否GB2312编码
+ *
+ * @param string $str
+ * @return boolean false UTF-8编码 TRUE GB2312编码
+ */
+ public static function isGb2312($str)
+ {
+ for ($i = 0; $i < strlen($str); $i++) {
+ $v = ord($str[$i]);
+ if ($v > 127) {
+ if (($v >= 228) && ($v <= 233)) {
+ if (($i + 2) >= (strlen($str) - 1)) return true; // not enough characters
+ $v1 = ord($str[$i + 1]);
+ $v2 = ord($str[$i + 2]);
+ if (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191))
+ return false;
+ else
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 检测是否GBK编码
+ *
+ * @param string $str
+ * @param boolean $gbk
+ * @return boolean
+ */
+ public static function checkChar($str, $gbk = true)
+ {
+ for ($i = 0; $i < strlen($str); $i++) {
+ $v = ord($str[$i]);
+ if ($v > 127) {
+ if (($v >= 228) && ($v <= 233)) {
+ if (($i + 2) >= (strlen($str) - 1)) return $gbk ? true : FALSE; // not enough characters
+ $v1 = ord($str[$i + 1]);
+ $v2 = ord($str[$i + 2]);
+ if ($gbk) {
+ return (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) ? FALSE : TRUE;//GBK
+ } else {
+ return (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) ? TRUE : FALSE;
+ }
+ }
+ }
+ }
+ return $gbk ? TRUE : FALSE;
+ }
+
+ /**
+ * 检验bucket名称是否合法
+ * bucket的命名规范:
+ * 1. 只能包括小写字母,数字
+ * 2. 必须以小写字母或者数字开头
+ * 3. 长度必须在3-63字节之间
+ *
+ * @param string $bucket Bucket名称
+ * @return boolean
+ */
+ public static function validateBucket($bucket)
+ {
+ $pattern = '/^[a-z0-9][a-z0-9-]{2,62}$/';
+ if (!preg_match($pattern, $bucket)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 检验object名称是否合法
+ * object命名规范:
+ * 1. 规则长度必须在1-1023字节之间
+ * 2. 使用UTF-8编码
+ * 3. 不能以 "/" "\\"开头
+ *
+ * @param string $object Object名称
+ * @return boolean
+ */
+ public static function validateObject($object)
+ {
+ $pattern = '/^.{1,1023}$/';
+ if (empty($object) || !preg_match($pattern, $object) ||
+ self::startsWith($object, '/') || self::startsWith($object, '\\')
+ ) {
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * 判断字符串$str是不是以$findMe开始
+ *
+ * @param string $str
+ * @param string $findMe
+ * @return bool
+ */
+ public static function startsWith($str, $findMe)
+ {
+ if (strpos($str, $findMe) === 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * 检验$options
+ *
+ * @param array $options
+ * @throws OssException
+ * @return boolean
+ */
+ public static function validateOptions($options)
+ {
+ //$options
+ if ($options != NULL && !is_array($options)) {
+ throw new OssException ($options . ':' . 'option must be array');
+ }
+ }
+
+ /**
+ * 检查上传文件的内容是否合法
+ *
+ * @param $content string
+ * @throws OssException
+ */
+ public static function validateContent($content)
+ {
+ if (empty($content)) {
+ throw new OssException("http body content is invalid");
+ }
+ }
+
+ /**
+ * 校验BUCKET/OBJECT/OBJECT GROUP是否为空
+ *
+ * @param string $name
+ * @param string $errMsg
+ * @throws OssException
+ * @return void
+ */
+ public static function throwOssExceptionWithMessageIfEmpty($name, $errMsg)
+ {
+ if (empty($name)) {
+ throw new OssException($errMsg);
+ }
+ }
+
+ /**
+ * 仅供测试使用的接口,请勿使用
+ *
+ * @param $filename
+ * @param $size
+ */
+ public static function generateFile($filename, $size)
+ {
+ if (file_exists($filename) && $size == filesize($filename)) {
+ echo $filename . " already exists, no need to create again. ";
+ return;
+ }
+ $part_size = 1 * 1024 * 1024;
+ $fp = fopen($filename, "w");
+ $characters = << 0) {
+ if ($size < $part_size) {
+ $write_size = $size;
+ } else {
+ $write_size = $part_size;
+ }
+ $size -= $write_size;
+ $a = $characters[rand(0, $charactersLength - 1)];
+ $content = str_repeat($a, $write_size);
+ $flag = fwrite($fp, $content);
+ if (!$flag) {
+ echo "write to " . $filename . " failed. ";
+ break;
+ }
+ }
+ } else {
+ echo "open " . $filename . " failed. ";
+ }
+ fclose($fp);
+ }
+
+ /**
+ * 得到文件的md5编码
+ *
+ * @param $filename
+ * @param $from_pos
+ * @param $to_pos
+ * @return string
+ */
+ public static function getMd5SumForFile($filename, $from_pos, $to_pos)
+ {
+ $content_md5 = "";
+ if (($to_pos - $from_pos) > self::OSS_MAX_PART_SIZE) {
+ return $content_md5;
+ }
+ $filesize = filesize($filename);
+ if ($from_pos >= $filesize || $to_pos >= $filesize || $from_pos < 0 || $to_pos < 0) {
+ return $content_md5;
+ }
+
+ $total_length = $to_pos - $from_pos + 1;
+ $buffer = 8192;
+ $left_length = $total_length;
+ if (!file_exists($filename)) {
+ return $content_md5;
+ }
+
+ if (false === $fh = fopen($filename, 'rb')) {
+ return $content_md5;
+ }
+
+ fseek($fh, $from_pos);
+ $data = '';
+ while (!feof($fh)) {
+ if ($left_length >= $buffer) {
+ $read_length = $buffer;
+ } else {
+ $read_length = $left_length;
+ }
+ if ($read_length <= 0) {
+ break;
+ } else {
+ $data .= fread($fh, $read_length);
+ $left_length = $left_length - $read_length;
+ }
+ }
+ fclose($fh);
+ $content_md5 = base64_encode(md5($data, true));
+ return $content_md5;
+ }
+
+ /**
+ * 检测是否windows系统,因为windows系统默认编码为GBK
+ *
+ * @return bool
+ */
+ public static function isWin()
+ {
+ return strtoupper(substr(PHP_OS, 0, 3)) == "WIN";
+ }
+
+ /**
+ * 主要是由于windows系统编码是gbk,遇到中文时候,如果不进行转换处理会出现找不到文件的问题
+ *
+ * @param $file_path
+ * @return string
+ */
+ public static function encodePath($file_path)
+ {
+ if (self::chkChinese($file_path) && self::isWin()) {
+ $file_path = iconv('utf-8', 'gbk', $file_path);
+ }
+ return $file_path;
+ }
+
+ /**
+ * 判断用户输入的endpoint是否是 xxx.xxx.xxx.xxx:port 或者 xxx.xxx.xxx.xxx的ip格式
+ *
+ * @param string $endpoint 需要做判断的endpoint
+ * @return boolean
+ */
+ public static function isIPFormat($endpoint)
+ {
+ $ip_array = explode(":", $endpoint);
+ $hostname = $ip_array[0];
+ $ret = filter_var($hostname, FILTER_VALIDATE_IP);
+ if (!$ret) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * 生成DeleteMultiObjects接口的xml消息
+ *
+ * @param string[] $objects
+ * @param bool $quiet
+ * @return string
+ */
+ public static function createDeleteObjectsXmlBody($objects, $quiet)
+ {
+ $xml = new \SimpleXMLElement(' ');
+ $xml->addChild('Quiet', $quiet);
+ foreach ($objects as $object) {
+ $sub_object = $xml->addChild('Object');
+ $object = OssUtil::sReplace($object);
+ $sub_object->addChild('Key', $object);
+ }
+ return $xml->asXML();
+ }
+
+ /**
+ * 生成CompleteMultipartUpload接口的xml消息
+ *
+ * @param array[] $listParts
+ * @return string
+ */
+ public static function createCompleteMultipartUploadXmlBody($listParts)
+ {
+ $xml = new \SimpleXMLElement(' ');
+ foreach ($listParts as $node) {
+ $part = $xml->addChild('Part');
+ $part->addChild('PartNumber', $node['PartNumber']);
+ $part->addChild('ETag', $node['ETag']);
+ }
+ return $xml->asXML();
+ }
+
+ /**
+ * 读取目录
+ *
+ * @param string $dir
+ * @param string $exclude
+ * @param bool $recursive
+ * @return string[]
+ */
+ public static function readDir($dir, $exclude = ".|..|.svn|.git", $recursive = false)
+ {
+ $file_list_array = array();
+ $base_path = $dir;
+ $exclude_array = explode("|", $exclude);
+ $exclude_array = array_unique(array_merge($exclude_array, array('.', '..')));
+
+ if ($recursive) {
+ foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir)) as $new_file) {
+ if ($new_file->isDir()) continue;
+ $object = str_replace($base_path, '', $new_file);
+ if (!in_array(strtolower($object), $exclude_array)) {
+ $object = ltrim($object, '/');
+ if (is_file($new_file)) {
+ $key = md5($new_file . $object, false);
+ $file_list_array[$key] = array('path' => $new_file, 'file' => $object,);
+ }
+ }
+ }
+ } else if ($handle = opendir($dir)) {
+ while (false !== ($file = readdir($handle))) {
+ if (!in_array(strtolower($file), $exclude_array)) {
+ $new_file = $dir . '/' . $file;
+ $object = $file;
+ $object = ltrim($object, '/');
+ if (is_file($new_file)) {
+ $key = md5($new_file . $object, false);
+ $file_list_array[$key] = array('path' => $new_file, 'file' => $object,);
+ }
+ }
+ }
+ closedir($handle);
+ }
+ return $file_list_array;
+ }
+
+ /**
+ * Decode key based on the encoding type
+ *
+ * @param string $key
+ * @param string $encoding
+ * @return string
+ */
+ public static function decodeKey($key, $encoding)
+ {
+ if ($encoding == "") {
+ return $key;
+ }
+
+ if ($encoding == "url") {
+ return rawurldecode($key);
+ } else {
+ throw new OssException("Unrecognized encoding type: " . $encoding);
+ }
+ }
+}
diff --git a/framework/library/alioss/src/OSS/Http/LICENSE b/framework/library/alioss/src/OSS/Http/LICENSE
new file mode 100644
index 0000000..49b38bd
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Http/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2006-2010 Ryan Parman, Foleeo Inc., and contributors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ of conditions and the following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ * Neither the name of Ryan Parman, Foleeo Inc. nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/framework/library/alioss/src/OSS/Http/RequestCore.php b/framework/library/alioss/src/OSS/Http/RequestCore.php
new file mode 100644
index 0000000..8bb87d4
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Http/RequestCore.php
@@ -0,0 +1,937 @@
+).
+ */
+ public $request_class = 'OSS\Http\RequestCore';
+
+ /**
+ * The default class to use for HTTP Responses (defaults to ).
+ */
+ public $response_class = 'OSS\Http\ResponseCore';
+
+ /**
+ * Default useragent string to use.
+ */
+ public $useragent = 'RequestCore/1.4.3';
+
+ /**
+ * File to read from while streaming up.
+ */
+ public $read_file = null;
+
+ /**
+ * The resource to read from while streaming up.
+ */
+ public $read_stream = null;
+
+ /**
+ * The size of the stream to read from.
+ */
+ public $read_stream_size = null;
+
+ /**
+ * The length already read from the stream.
+ */
+ public $read_stream_read = 0;
+
+ /**
+ * File to write to while streaming down.
+ */
+ public $write_file = null;
+
+ /**
+ * The resource to write to while streaming down.
+ */
+ public $write_stream = null;
+
+ /**
+ * Stores the intended starting seek position.
+ */
+ public $seek_position = null;
+
+ /**
+ * The location of the cacert.pem file to use.
+ */
+ public $cacert_location = false;
+
+ /**
+ * The state of SSL certificate verification.
+ */
+ public $ssl_verification = true;
+
+ /**
+ * The user-defined callback function to call when a stream is read from.
+ */
+ public $registered_streaming_read_callback = null;
+
+ /**
+ * The user-defined callback function to call when a stream is written to.
+ */
+ public $registered_streaming_write_callback = null;
+
+ /**
+ * 请求超时时间, 默认是5184000秒,6天
+ *
+ * @var int
+ */
+ public $timeout = 5184000;
+
+ /**
+ * 连接超时时间,默认是10秒
+ *
+ * @var int
+ */
+ public $connect_timeout = 10;
+
+ /*%******************************************************************************************%*/
+ // CONSTANTS
+
+ /**
+ * GET HTTP Method
+ */
+ const HTTP_GET = 'GET';
+
+ /**
+ * POST HTTP Method
+ */
+ const HTTP_POST = 'POST';
+
+ /**
+ * PUT HTTP Method
+ */
+ const HTTP_PUT = 'PUT';
+
+ /**
+ * DELETE HTTP Method
+ */
+ const HTTP_DELETE = 'DELETE';
+
+ /**
+ * HEAD HTTP Method
+ */
+ const HTTP_HEAD = 'HEAD';
+
+
+ /*%******************************************************************************************%*/
+ // CONSTRUCTOR/DESTRUCTOR
+
+ /**
+ * Constructs a new instance of this class.
+ *
+ * @param string $url (Optional) The URL to request or service endpoint to query.
+ * @param string $proxy (Optional) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port`
+ * @param array $helpers (Optional) An associative array of classnames to use for request, and response functionality. Gets passed in automatically by the calling class.
+ * @return $this A reference to the current instance.
+ */
+ public function __construct($url = null, $proxy = null, $helpers = null)
+ {
+ // Set some default values.
+ $this->request_url = $url;
+ $this->method = self::HTTP_GET;
+ $this->request_headers = array();
+ $this->request_body = '';
+
+ // Set a new Request class if one was set.
+ if (isset($helpers['request']) && !empty($helpers['request'])) {
+ $this->request_class = $helpers['request'];
+ }
+
+ // Set a new Request class if one was set.
+ if (isset($helpers['response']) && !empty($helpers['response'])) {
+ $this->response_class = $helpers['response'];
+ }
+
+ if ($proxy) {
+ $this->set_proxy($proxy);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Destructs the instance. Closes opened file handles.
+ *
+ * @return $this A reference to the current instance.
+ */
+ public function __destruct()
+ {
+ if (isset($this->read_file) && isset($this->read_stream)) {
+ fclose($this->read_stream);
+ }
+
+ if (isset($this->write_file) && isset($this->write_stream)) {
+ fclose($this->write_stream);
+ }
+
+ return $this;
+ }
+
+
+ /*%******************************************************************************************%*/
+ // REQUEST METHODS
+
+ /**
+ * Sets the credentials to use for authentication.
+ *
+ * @param string $user (Required) The username to authenticate with.
+ * @param string $pass (Required) The password to authenticate with.
+ * @return $this A reference to the current instance.
+ */
+ public function set_credentials($user, $pass)
+ {
+ $this->username = $user;
+ $this->password = $pass;
+ return $this;
+ }
+
+ /**
+ * Adds a custom HTTP header to the cURL request.
+ *
+ * @param string $key (Required) The custom HTTP header to set.
+ * @param mixed $value (Required) The value to assign to the custom HTTP header.
+ * @return $this A reference to the current instance.
+ */
+ public function add_header($key, $value)
+ {
+ $this->request_headers[$key] = $value;
+ return $this;
+ }
+
+ /**
+ * Removes an HTTP header from the cURL request.
+ *
+ * @param string $key (Required) The custom HTTP header to set.
+ * @return $this A reference to the current instance.
+ */
+ public function remove_header($key)
+ {
+ if (isset($this->request_headers[$key])) {
+ unset($this->request_headers[$key]);
+ }
+ return $this;
+ }
+
+ /**
+ * Set the method type for the request.
+ *
+ * @param string $method (Required) One of the following constants: , , , , .
+ * @return $this A reference to the current instance.
+ */
+ public function set_method($method)
+ {
+ $this->method = strtoupper($method);
+ return $this;
+ }
+
+ /**
+ * Sets a custom useragent string for the class.
+ *
+ * @param string $ua (Required) The useragent string to use.
+ * @return $this A reference to the current instance.
+ */
+ public function set_useragent($ua)
+ {
+ $this->useragent = $ua;
+ return $this;
+ }
+
+ /**
+ * Set the body to send in the request.
+ *
+ * @param string $body (Required) The textual content to send along in the body of the request.
+ * @return $this A reference to the current instance.
+ */
+ public function set_body($body)
+ {
+ $this->request_body = $body;
+ return $this;
+ }
+
+ /**
+ * Set the URL to make the request to.
+ *
+ * @param string $url (Required) The URL to make the request to.
+ * @return $this A reference to the current instance.
+ */
+ public function set_request_url($url)
+ {
+ $this->request_url = $url;
+ return $this;
+ }
+
+ /**
+ * Set additional CURLOPT settings. These will merge with the default settings, and override if
+ * there is a duplicate.
+ *
+ * @param array $curlopts (Optional) A set of key-value pairs that set `CURLOPT` options. These will merge with the existing CURLOPTs, and ones passed here will override the defaults. Keys should be the `CURLOPT_*` constants, not strings.
+ * @return $this A reference to the current instance.
+ */
+ public function set_curlopts($curlopts)
+ {
+ $this->curlopts = $curlopts;
+ return $this;
+ }
+
+ /**
+ * Sets the length in bytes to read from the stream while streaming up.
+ *
+ * @param integer $size (Required) The length in bytes to read from the stream.
+ * @return $this A reference to the current instance.
+ */
+ public function set_read_stream_size($size)
+ {
+ $this->read_stream_size = $size;
+
+ return $this;
+ }
+
+ /**
+ * Sets the resource to read from while streaming up. Reads the stream from its current position until
+ * EOF or `$size` bytes have been read. If `$size` is not given it will be determined by and
+ * .
+ *
+ * @param resource $resource (Required) The readable resource to read from.
+ * @param integer $size (Optional) The size of the stream to read.
+ * @return $this A reference to the current instance.
+ */
+ public function set_read_stream($resource, $size = null)
+ {
+ if (!isset($size) || $size < 0) {
+ $stats = fstat($resource);
+
+ if ($stats && $stats['size'] >= 0) {
+ $position = ftell($resource);
+
+ if ($position !== false && $position >= 0) {
+ $size = $stats['size'] - $position;
+ }
+ }
+ }
+
+ $this->read_stream = $resource;
+
+ return $this->set_read_stream_size($size);
+ }
+
+ /**
+ * Sets the file to read from while streaming up.
+ *
+ * @param string $location (Required) The readable location to read from.
+ * @return $this A reference to the current instance.
+ */
+ public function set_read_file($location)
+ {
+ $this->read_file = $location;
+ $read_file_handle = fopen($location, 'r');
+
+ return $this->set_read_stream($read_file_handle);
+ }
+
+ /**
+ * Sets the resource to write to while streaming down.
+ *
+ * @param resource $resource (Required) The writeable resource to write to.
+ * @return $this A reference to the current instance.
+ */
+ public function set_write_stream($resource)
+ {
+ $this->write_stream = $resource;
+
+ return $this;
+ }
+
+ /**
+ * Sets the file to write to while streaming down.
+ *
+ * @param string $location (Required) The writeable location to write to.
+ * @return $this A reference to the current instance.
+ */
+ public function set_write_file($location)
+ {
+ $this->write_file = $location;
+ $write_file_handle = fopen($location, 'w');
+
+ return $this->set_write_stream($write_file_handle);
+ }
+
+ /**
+ * Set the proxy to use for making requests.
+ *
+ * @param string $proxy (Required) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port`
+ * @return $this A reference to the current instance.
+ */
+ public function set_proxy($proxy)
+ {
+ $proxy = parse_url($proxy);
+ $proxy['user'] = isset($proxy['user']) ? $proxy['user'] : null;
+ $proxy['pass'] = isset($proxy['pass']) ? $proxy['pass'] : null;
+ $proxy['port'] = isset($proxy['port']) ? $proxy['port'] : null;
+ $this->proxy = $proxy;
+ return $this;
+ }
+
+ /**
+ * Set the intended starting seek position.
+ *
+ * @param integer $position (Required) The byte-position of the stream to begin reading from.
+ * @return $this A reference to the current instance.
+ */
+ public function set_seek_position($position)
+ {
+ $this->seek_position = isset($position) ? (integer)$position : null;
+
+ return $this;
+ }
+
+ /**
+ * Register a callback function to execute whenever a data stream is read from using
+ * .
+ *
+ * The user-defined callback function should accept three arguments:
+ *
+ *
+ * $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
+ * $file_handle - resource - Required - The file handle resource that represents the file on the local file system.
+ * $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
+ *
+ *
+ * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
+ * The name of a global function to execute, passed as a string.
+ * A method to execute, passed as array('ClassName', 'MethodName').
+ * An anonymous function (PHP 5.3+).
+ * @return $this A reference to the current instance.
+ */
+ public function register_streaming_read_callback($callback)
+ {
+ $this->registered_streaming_read_callback = $callback;
+
+ return $this;
+ }
+
+ /**
+ * Register a callback function to execute whenever a data stream is written to using
+ * .
+ *
+ * The user-defined callback function should accept two arguments:
+ *
+ *
+ * $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
+ * $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
+ *
+ *
+ * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
+ * The name of a global function to execute, passed as a string.
+ * A method to execute, passed as array('ClassName', 'MethodName').
+ * An anonymous function (PHP 5.3+).
+ * @return $this A reference to the current instance.
+ */
+ public function register_streaming_write_callback($callback)
+ {
+ $this->registered_streaming_write_callback = $callback;
+
+ return $this;
+ }
+
+
+ /*%******************************************************************************************%*/
+ // PREPARE, SEND, AND PROCESS REQUEST
+
+ /**
+ * A callback function that is invoked by cURL for streaming up.
+ *
+ * @param resource $curl_handle (Required) The cURL handle for the request.
+ * @param resource $file_handle (Required) The open file handle resource.
+ * @param integer $length (Required) The maximum number of bytes to read.
+ * @return binary Binary data from a stream.
+ */
+ public function streaming_read_callback($curl_handle, $file_handle, $length)
+ {
+ // Once we've sent as much as we're supposed to send...
+ if ($this->read_stream_read >= $this->read_stream_size) {
+ // Send EOF
+ return '';
+ }
+
+ // If we're at the beginning of an upload and need to seek...
+ if ($this->read_stream_read == 0 && isset($this->seek_position) && $this->seek_position !== ftell($this->read_stream)) {
+ if (fseek($this->read_stream, $this->seek_position) !== 0) {
+ throw new RequestCore_Exception('The stream does not support seeking and is either not at the requested position or the position is unknown.');
+ }
+ }
+
+ $read = fread($this->read_stream, min($this->read_stream_size - $this->read_stream_read, $length)); // Remaining upload data or cURL's requested chunk size
+ $this->read_stream_read += strlen($read);
+
+ $out = $read === false ? '' : $read;
+
+ // Execute callback function
+ if ($this->registered_streaming_read_callback) {
+ call_user_func($this->registered_streaming_read_callback, $curl_handle, $file_handle, $out);
+ }
+
+ return $out;
+ }
+
+ /**
+ * A callback function that is invoked by cURL for streaming down.
+ *
+ * @param resource $curl_handle (Required) The cURL handle for the request.
+ * @param binary $data (Required) The data to write.
+ * @return integer The number of bytes written.
+ */
+ public function streaming_write_callback($curl_handle, $data)
+ {
+ $length = strlen($data);
+ $written_total = 0;
+ $written_last = 0;
+
+ while ($written_total < $length) {
+ $written_last = fwrite($this->write_stream, substr($data, $written_total));
+
+ if ($written_last === false) {
+ return $written_total;
+ }
+
+ $written_total += $written_last;
+ }
+
+ // Execute callback function
+ if ($this->registered_streaming_write_callback) {
+ call_user_func($this->registered_streaming_write_callback, $curl_handle, $written_total);
+ }
+
+ return $written_total;
+ }
+
+ /**
+ * Prepares and adds the details of the cURL request. This can be passed along to a
+ * function.
+ *
+ * @return resource The handle for the cURL object.
+ *
+ */
+ public function prep_request()
+ {
+ $curl_handle = curl_init();
+
+ // Set default options.
+ curl_setopt($curl_handle, CURLOPT_URL, $this->request_url);
+ curl_setopt($curl_handle, CURLOPT_FILETIME, true);
+ curl_setopt($curl_handle, CURLOPT_FRESH_CONNECT, false);
+// curl_setopt($curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
+ curl_setopt($curl_handle, CURLOPT_MAXREDIRS, 5);
+ curl_setopt($curl_handle, CURLOPT_HEADER, true);
+ curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl_handle, CURLOPT_TIMEOUT, $this->timeout);
+ curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, $this->connect_timeout);
+ curl_setopt($curl_handle, CURLOPT_NOSIGNAL, true);
+ curl_setopt($curl_handle, CURLOPT_REFERER, $this->request_url);
+ curl_setopt($curl_handle, CURLOPT_USERAGENT, $this->useragent);
+ curl_setopt($curl_handle, CURLOPT_READFUNCTION, array($this, 'streaming_read_callback'));
+
+ // Verification of the SSL cert
+ if ($this->ssl_verification) {
+ curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, true);
+ curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
+ } else {
+ curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false);
+ }
+
+ // chmod the file as 0755
+ if ($this->cacert_location === true) {
+ curl_setopt($curl_handle, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
+ } elseif (is_string($this->cacert_location)) {
+ curl_setopt($curl_handle, CURLOPT_CAINFO, $this->cacert_location);
+ }
+
+ // Debug mode
+ if ($this->debug_mode) {
+ curl_setopt($curl_handle, CURLOPT_VERBOSE, true);
+ }
+
+ // Handle open_basedir & safe mode
+ if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
+ curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true);
+ }
+
+ // Enable a proxy connection if requested.
+ if ($this->proxy) {
+ curl_setopt($curl_handle, CURLOPT_HTTPPROXYTUNNEL, true);
+
+ $host = $this->proxy['host'];
+ $host .= ($this->proxy['port']) ? ':' . $this->proxy['port'] : '';
+ curl_setopt($curl_handle, CURLOPT_PROXY, $host);
+
+ if (isset($this->proxy['user']) && isset($this->proxy['pass'])) {
+ curl_setopt($curl_handle, CURLOPT_PROXYUSERPWD, $this->proxy['user'] . ':' . $this->proxy['pass']);
+ }
+ }
+
+ // Set credentials for HTTP Basic/Digest Authentication.
+ if ($this->username && $this->password) {
+ curl_setopt($curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+ curl_setopt($curl_handle, CURLOPT_USERPWD, $this->username . ':' . $this->password);
+ }
+
+ // Handle the encoding if we can.
+ if (extension_loaded('zlib')) {
+ curl_setopt($curl_handle, CURLOPT_ENCODING, '');
+ }
+
+ // Process custom headers
+ if (isset($this->request_headers) && count($this->request_headers)) {
+ $temp_headers = array();
+
+ foreach ($this->request_headers as $k => $v) {
+ $temp_headers[] = $k . ': ' . $v;
+ }
+
+ curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $temp_headers);
+ }
+
+ switch ($this->method) {
+ case self::HTTP_PUT:
+ //unset($this->read_stream);
+ curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT');
+ if (isset($this->read_stream)) {
+ if (!isset($this->read_stream_size) || $this->read_stream_size < 0) {
+ throw new RequestCore_Exception('The stream size for the streaming upload cannot be determined.');
+ }
+ curl_setopt($curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size);
+ curl_setopt($curl_handle, CURLOPT_UPLOAD, true);
+ } else {
+ curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body);
+ }
+ break;
+
+ case self::HTTP_POST:
+ curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'POST');
+ if (isset($this->read_stream)) {
+ if (!isset($this->read_stream_size) || $this->read_stream_size < 0) {
+ throw new RequestCore_Exception('The stream size for the streaming upload cannot be determined.');
+ }
+ curl_setopt($curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size);
+ curl_setopt($curl_handle, CURLOPT_UPLOAD, true);
+ } else {
+ curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body);
+ }
+ break;
+
+ case self::HTTP_HEAD:
+ curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, self::HTTP_HEAD);
+ curl_setopt($curl_handle, CURLOPT_NOBODY, 1);
+ break;
+
+ default: // Assumed GET
+ curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, $this->method);
+ if (isset($this->write_stream)) {
+ curl_setopt($curl_handle, CURLOPT_WRITEFUNCTION, array($this, 'streaming_write_callback'));
+ curl_setopt($curl_handle, CURLOPT_HEADER, false);
+ } else {
+ curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body);
+ }
+ break;
+ }
+
+ // Merge in the CURLOPTs
+ if (isset($this->curlopts) && sizeof($this->curlopts) > 0) {
+ foreach ($this->curlopts as $k => $v) {
+ curl_setopt($curl_handle, $k, $v);
+ }
+ }
+
+ return $curl_handle;
+ }
+
+ /**
+ * Take the post-processed cURL data and break it down into useful header/body/info chunks. Uses the
+ * data stored in the `curl_handle` and `response` properties unless replacement data is passed in via
+ * parameters.
+ *
+ * @param resource $curl_handle (Optional) The reference to the already executed cURL request.
+ * @param string $response (Optional) The actual response content itself that needs to be parsed.
+ * @return ResponseCore A object containing a parsed HTTP response.
+ */
+ public function process_response($curl_handle = null, $response = null)
+ {
+ // Accept a custom one if it's passed.
+ if ($curl_handle && $response) {
+ $this->curl_handle = $curl_handle;
+ $this->response = $response;
+ }
+
+ // As long as this came back as a valid resource...
+ if (is_resource($this->curl_handle)) {
+ // Determine what's what.
+ $header_size = curl_getinfo($this->curl_handle, CURLINFO_HEADER_SIZE);
+ $this->response_headers = substr($this->response, 0, $header_size);
+ $this->response_body = substr($this->response, $header_size);
+ $this->response_code = curl_getinfo($this->curl_handle, CURLINFO_HTTP_CODE);
+ $this->response_info = curl_getinfo($this->curl_handle);
+
+ // Parse out the headers
+ $this->response_headers = explode("\r\n\r\n", trim($this->response_headers));
+ $this->response_headers = array_pop($this->response_headers);
+ $this->response_headers = explode("\r\n", $this->response_headers);
+ array_shift($this->response_headers);
+
+ // Loop through and split up the headers.
+ $header_assoc = array();
+ foreach ($this->response_headers as $header) {
+ $kv = explode(': ', $header);
+ $header_assoc[strtolower($kv[0])] = isset($kv[1]) ? $kv[1] : '';
+ }
+
+ // Reset the headers to the appropriate property.
+ $this->response_headers = $header_assoc;
+ $this->response_headers['_info'] = $this->response_info;
+ $this->response_headers['_info']['method'] = $this->method;
+
+ if ($curl_handle && $response) {
+ //return new $this->response_class($this->response_headers, $this->response_body, $this->response_code, $this->curl_handle);
+ return new ResponseCore($this->response_headers, $this->response_body, $this->response_code);
+ }
+ }
+
+ // Return false
+ return false;
+ }
+
+ /**
+ * Sends the request, calling necessary utility functions to update built-in properties.
+ *
+ * @param boolean $parse (Optional) Whether to parse the response with ResponseCore or not.
+ * @return string The resulting unparsed data from the request.
+ */
+ public function send_request($parse = false)
+ {
+ set_time_limit(0);
+
+ $curl_handle = $this->prep_request();
+ $this->response = curl_exec($curl_handle);
+
+ if ($this->response === false) {
+ throw new RequestCore_Exception('cURL resource: ' . (string)$curl_handle . '; cURL error: ' . curl_error($curl_handle) . ' (' . curl_errno($curl_handle) . ')');
+ }
+
+ $parsed_response = $this->process_response($curl_handle, $this->response);
+
+ curl_close($curl_handle);
+
+ if ($parse) {
+ return $parsed_response;
+ }
+
+ return $this->response;
+ }
+
+ /**
+ * Sends the request using , enabling parallel requests. Uses the "rolling" method.
+ *
+ * @param array $handles (Required) An indexed array of cURL handles to process simultaneously.
+ * @param array $opt (Optional) An associative array of parameters that can have the following keys:
+ * callback - string|array - Optional - The string name of a function to pass the response data to. If this is a method, pass an array where the [0] index is the class and the [1] index is the method name.
+ * limit - integer - Optional - The number of simultaneous requests to make. This can be useful for scaling around slow server responses. Defaults to trusting cURLs judgement as to how many to use.
+ * @return array Post-processed cURL responses.
+ */
+ public function send_multi_request($handles, $opt = null)
+ {
+ set_time_limit(0);
+
+ // Skip everything if there are no handles to process.
+ if (count($handles) === 0) return array();
+
+ if (!$opt) $opt = array();
+
+ // Initialize any missing options
+ $limit = isset($opt['limit']) ? $opt['limit'] : -1;
+
+ // Initialize
+ $handle_list = $handles;
+ $http = new $this->request_class();
+ $multi_handle = curl_multi_init();
+ $handles_post = array();
+ $added = count($handles);
+ $last_handle = null;
+ $count = 0;
+ $i = 0;
+
+ // Loop through the cURL handles and add as many as it set by the limit parameter.
+ while ($i < $added) {
+ if ($limit > 0 && $i >= $limit) break;
+ curl_multi_add_handle($multi_handle, array_shift($handles));
+ $i++;
+ }
+
+ do {
+ $active = false;
+
+ // Start executing and wait for a response.
+ while (($status = curl_multi_exec($multi_handle, $active)) === CURLM_CALL_MULTI_PERFORM) {
+ // Start looking for possible responses immediately when we have to add more handles
+ if (count($handles) > 0) break;
+ }
+
+ // Figure out which requests finished.
+ $to_process = array();
+
+ while ($done = curl_multi_info_read($multi_handle)) {
+ // Since curl_errno() isn't reliable for handles that were in multirequests, we check the 'result' of the info read, which contains the curl error number, (listed here http://curl.haxx.se/libcurl/c/libcurl-errors.html )
+ if ($done['result'] > 0) {
+ throw new RequestCore_Exception('cURL resource: ' . (string)$done['handle'] . '; cURL error: ' . curl_error($done['handle']) . ' (' . $done['result'] . ')');
+ } // Because curl_multi_info_read() might return more than one message about a request, we check to see if this request is already in our array of completed requests
+ elseif (!isset($to_process[(int)$done['handle']])) {
+ $to_process[(int)$done['handle']] = $done;
+ }
+ }
+
+ // Actually deal with the request
+ foreach ($to_process as $pkey => $done) {
+ $response = $http->process_response($done['handle'], curl_multi_getcontent($done['handle']));
+ $key = array_search($done['handle'], $handle_list, true);
+ $handles_post[$key] = $response;
+
+ if (count($handles) > 0) {
+ curl_multi_add_handle($multi_handle, array_shift($handles));
+ }
+
+ curl_multi_remove_handle($multi_handle, $done['handle']);
+ curl_close($done['handle']);
+ }
+ } while ($active || count($handles_post) < $added);
+
+ curl_multi_close($multi_handle);
+
+ ksort($handles_post, SORT_NUMERIC);
+ return $handles_post;
+ }
+
+
+ /*%******************************************************************************************%*/
+ // RESPONSE METHODS
+
+ /**
+ * Get the HTTP response headers from the request.
+ *
+ * @param string $header (Optional) A specific header value to return. Defaults to all headers.
+ * @return string|array All or selected header values.
+ */
+ public function get_response_header($header = null)
+ {
+ if ($header) {
+ return $this->response_headers[strtolower($header)];
+ }
+ return $this->response_headers;
+ }
+
+ /**
+ * Get the HTTP response body from the request.
+ *
+ * @return string The response body.
+ */
+ public function get_response_body()
+ {
+ return $this->response_body;
+ }
+
+ /**
+ * Get the HTTP response code from the request.
+ *
+ * @return string The HTTP response code.
+ */
+ public function get_response_code()
+ {
+ return $this->response_code;
+ }
+}
diff --git a/framework/library/alioss/src/OSS/Http/RequestCore_Exception.php b/framework/library/alioss/src/OSS/Http/RequestCore_Exception.php
new file mode 100644
index 0000000..cb4e83c
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Http/RequestCore_Exception.php
@@ -0,0 +1,8 @@
+).
+ * @param string $body (Required) XML-formatted response from AWS.
+ * @param integer $status (Optional) HTTP response status code from the request.
+ * @return Mixed Contains an `header` property (HTTP headers as an associative array), a or `body` property, and an `status` code.
+ */
+ public function __construct($header, $body, $status = null)
+ {
+ $this->header = $header;
+ $this->body = $body;
+ $this->status = $status;
+
+ return $this;
+ }
+
+ /**
+ * Did we receive the status code we expected?
+ *
+ * @param integer|array $codes (Optional) The status code(s) to expect. Pass an for a single acceptable value, or an of integers for multiple acceptable values.
+ * @return boolean Whether we received the expected status code or not.
+ */
+ public function isOK($codes = array(200, 201, 204, 206))
+ {
+ if (is_array($codes)) {
+ return in_array($this->status, $codes);
+ }
+
+ return $this->status === $codes;
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/BucketInfo.php b/framework/library/alioss/src/OSS/Model/BucketInfo.php
new file mode 100644
index 0000000..9b89674
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/BucketInfo.php
@@ -0,0 +1,78 @@
+location = $location;
+ $this->name = $name;
+ $this->createDate = $createDate;
+ }
+
+ /**
+ * 得到bucket所在的region
+ *
+ * @return string
+ */
+ public function getLocation()
+ {
+ return $this->location;
+ }
+
+ /**
+ * 得到bucket的名称
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * 得到bucket的创建时间
+ *
+ * @return string
+ */
+ public function getCreateDate()
+ {
+ return $this->createDate;
+ }
+
+ /**
+ * bucket所在的region
+ *
+ * @var string
+ */
+ private $location;
+ /**
+ * bucket的名称
+ *
+ * @var string
+ */
+ private $name;
+
+ /**
+ * bucket的创建事件
+ *
+ * @var string
+ */
+ private $createDate;
+
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/BucketListInfo.php b/framework/library/alioss/src/OSS/Model/BucketListInfo.php
new file mode 100644
index 0000000..910717f
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/BucketListInfo.php
@@ -0,0 +1,39 @@
+bucketList = $bucketList;
+ }
+
+ /**
+ * 得到BucketInfo列表
+ *
+ * @return BucketInfo[]
+ */
+ public function getBucketList()
+ {
+ return $this->bucketList;
+ }
+
+ /**
+ * BucketInfo信息列表
+ *
+ * @var array
+ */
+ private $bucketList = array();
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/CnameConfig.php b/framework/library/alioss/src/OSS/Model/CnameConfig.php
new file mode 100644
index 0000000..f3597d2
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/CnameConfig.php
@@ -0,0 +1,99 @@
+cnameList = array();
+ }
+
+ /**
+ * @return array
+ * @example
+ * array(2) {
+ * [0]=>
+ * array(3) {
+ * ["Domain"]=>
+ * string(11) "www.foo.com"
+ * ["Status"]=>
+ * string(7) "enabled"
+ * ["LastModified"]=>
+ * string(8) "20150101"
+ * }
+ * [1]=>
+ * array(3) {
+ * ["Domain"]=>
+ * string(7) "bar.com"
+ * ["Status"]=>
+ * string(8) "disabled"
+ * ["LastModified"]=>
+ * string(8) "20160101"
+ * }
+ * }
+ */
+ public function getCnames()
+ {
+ return $this->cnameList;
+ }
+
+
+ public function addCname($cname)
+ {
+ if (count($this->cnameList) >= self::OSS_MAX_RULES) {
+ throw new OssException(
+ "num of cname in the config exceeds self::OSS_MAX_RULES: " . strval(self::OSS_MAX_RULES));
+ }
+ $this->cnameList[] = array('Domain' => $cname);
+ }
+
+ public function parseFromXml($strXml)
+ {
+ $xml = simplexml_load_string($strXml);
+ if (!isset($xml->Cname)) return;
+ foreach ($xml->Cname as $entry) {
+ $cname = array();
+ foreach ($entry as $key => $value) {
+ $cname[strval($key)] = strval($value);
+ }
+ $this->cnameList[] = $cname;
+ }
+ }
+
+ public function serializeToXml()
+ {
+ $strXml = <<
+
+
+EOF;
+ $xml = new \SimpleXMLElement($strXml);
+ foreach ($this->cnameList as $cname) {
+ $node = $xml->addChild('Cname');
+ foreach ($cname as $key => $value) {
+ $node->addChild($key, $value);
+ }
+ }
+ return $xml->asXML();
+ }
+
+ public function __toString()
+ {
+ return $this->serializeToXml();
+ }
+
+ const OSS_MAX_RULES = 10;
+
+ private $cnameList = array();
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/CorsConfig.php b/framework/library/alioss/src/OSS/Model/CorsConfig.php
new file mode 100644
index 0000000..c44c10a
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/CorsConfig.php
@@ -0,0 +1,113 @@
+rules = array();
+ }
+
+ /**
+ * 得到CorsRule列表
+ *
+ * @return CorsRule[]
+ */
+ public function getRules()
+ {
+ return $this->rules;
+ }
+
+
+ /**
+ * 添加一条CorsRule
+ *
+ * @param CorsRule $rule
+ * @throws OssException
+ */
+ public function addRule($rule)
+ {
+ if (count($this->rules) >= self::OSS_MAX_RULES) {
+ throw new OssException("num of rules in the config exceeds self::OSS_MAX_RULES: " . strval(self::OSS_MAX_RULES));
+ }
+ $this->rules[] = $rule;
+ }
+
+ /**
+ * 从xml数据中解析出CorsConfig
+ *
+ * @param string $strXml
+ * @throws OssException
+ * @return null
+ */
+ public function parseFromXml($strXml)
+ {
+ $xml = simplexml_load_string($strXml);
+ if (!isset($xml->CORSRule)) return;
+ foreach ($xml->CORSRule as $rule) {
+ $corsRule = new CorsRule();
+ foreach ($rule as $key => $value) {
+ if ($key === self::OSS_CORS_ALLOWED_HEADER) {
+ $corsRule->addAllowedHeader(strval($value));
+ } elseif ($key === self::OSS_CORS_ALLOWED_METHOD) {
+ $corsRule->addAllowedMethod(strval($value));
+ } elseif ($key === self::OSS_CORS_ALLOWED_ORIGIN) {
+ $corsRule->addAllowedOrigin(strval($value));
+ } elseif ($key === self::OSS_CORS_EXPOSE_HEADER) {
+ $corsRule->addExposeHeader(strval($value));
+ } elseif ($key === self::OSS_CORS_MAX_AGE_SECONDS) {
+ $corsRule->setMaxAgeSeconds(strval($value));
+ }
+ }
+ $this->addRule($corsRule);
+ }
+ return;
+ }
+
+ /**
+ * 生成xml字符串
+ *
+ * @return string
+ */
+ public function serializeToXml()
+ {
+ $xml = new \SimpleXMLElement(' ');
+ foreach ($this->rules as $rule) {
+ $xmlRule = $xml->addChild('CORSRule');
+ $rule->appendToXml($xmlRule);
+ }
+ return $xml->asXML();
+ }
+
+ public function __toString()
+ {
+ return $this->serializeToXml();
+ }
+
+ const OSS_CORS_ALLOWED_ORIGIN = 'AllowedOrigin';
+ const OSS_CORS_ALLOWED_METHOD = 'AllowedMethod';
+ const OSS_CORS_ALLOWED_HEADER = 'AllowedHeader';
+ const OSS_CORS_EXPOSE_HEADER = 'ExposeHeader';
+ const OSS_CORS_MAX_AGE_SECONDS = 'MaxAgeSeconds';
+ const OSS_MAX_RULES = 10;
+
+ /**
+ * orsRule列表
+ *
+ * @var CorsRule[]
+ */
+ private $rules = array();
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/CorsRule.php b/framework/library/alioss/src/OSS/Model/CorsRule.php
new file mode 100644
index 0000000..2cbe1c1
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/CorsRule.php
@@ -0,0 +1,150 @@
+allowedOrigins[] = $allowedOrigin;
+ }
+ }
+
+ /**
+ * Rule中增加一条allowedMethod
+ *
+ * @param string $allowedMethod
+ */
+ public function addAllowedMethod($allowedMethod)
+ {
+ if (!empty($allowedMethod)) {
+ $this->allowedMethods[] = $allowedMethod;
+ }
+ }
+
+ /**
+ * Rule中增加一条allowedHeader
+ *
+ * @param string $allowedHeader
+ */
+ public function addAllowedHeader($allowedHeader)
+ {
+ if (!empty($allowedHeader)) {
+ $this->allowedHeaders[] = $allowedHeader;
+ }
+ }
+
+ /**
+ * Rule中增加一条exposeHeader
+ *
+ * @param string $exposeHeader
+ */
+ public function addExposeHeader($exposeHeader)
+ {
+ if (!empty($exposeHeader)) {
+ $this->exposeHeaders[] = $exposeHeader;
+ }
+ }
+
+ /**
+ * @return int
+ */
+ public function getMaxAgeSeconds()
+ {
+ return $this->maxAgeSeconds;
+ }
+
+ /**
+ * @param int $maxAgeSeconds
+ */
+ public function setMaxAgeSeconds($maxAgeSeconds)
+ {
+ $this->maxAgeSeconds = $maxAgeSeconds;
+ }
+
+ /**
+ * 得到AllowedHeaders列表
+ *
+ * @return string[]
+ */
+ public function getAllowedHeaders()
+ {
+ return $this->allowedHeaders;
+ }
+
+ /**
+ * 得到AllowedOrigins列表
+ *
+ * @return string[]
+ */
+ public function getAllowedOrigins()
+ {
+ return $this->allowedOrigins;
+ }
+
+ /**
+ * 得到AllowedMethods列表
+ *
+ * @return string[]
+ */
+ public function getAllowedMethods()
+ {
+ return $this->allowedMethods;
+ }
+
+ /**
+ * 得到ExposeHeaders列表
+ *
+ * @return string[]
+ */
+ public function getExposeHeaders()
+ {
+ return $this->exposeHeaders;
+ }
+
+ /**
+ * 根据提供的xmlRule, 把this按照一定的规则插入到$xmlRule中
+ *
+ * @param \SimpleXMLElement $xmlRule
+ * @throws OssException
+ */
+ public function appendToXml(&$xmlRule)
+ {
+ if (!isset($this->maxAgeSeconds)) {
+ throw new OssException("maxAgeSeconds is not set in the Rule");
+ }
+ foreach ($this->allowedOrigins as $allowedOrigin) {
+ $xmlRule->addChild(CorsConfig::OSS_CORS_ALLOWED_ORIGIN, $allowedOrigin);
+ }
+ foreach ($this->allowedMethods as $allowedMethod) {
+ $xmlRule->addChild(CorsConfig::OSS_CORS_ALLOWED_METHOD, $allowedMethod);
+ }
+ foreach ($this->allowedHeaders as $allowedHeader) {
+ $xmlRule->addChild(CorsConfig::OSS_CORS_ALLOWED_HEADER, $allowedHeader);
+ }
+ foreach ($this->exposeHeaders as $exposeHeader) {
+ $xmlRule->addChild(CorsConfig::OSS_CORS_EXPOSE_HEADER, $exposeHeader);
+ }
+ $xmlRule->addChild(CorsConfig::OSS_CORS_MAX_AGE_SECONDS, strval($this->maxAgeSeconds));
+ }
+
+ private $allowedHeaders = array();
+ private $allowedOrigins = array();
+ private $allowedMethods = array();
+ private $exposeHeaders = array();
+ private $maxAgeSeconds = null;
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/LifecycleAction.php b/framework/library/alioss/src/OSS/Model/LifecycleAction.php
new file mode 100644
index 0000000..5abd825
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/LifecycleAction.php
@@ -0,0 +1,88 @@
+action = $action;
+ $this->timeSpec = $timeSpec;
+ $this->timeValue = $timeValue;
+ }
+
+ /**
+ * @return LifecycleAction
+ */
+ public function getAction()
+ {
+ return $this->action;
+ }
+
+ /**
+ * @param string $action
+ */
+ public function setAction($action)
+ {
+ $this->action = $action;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTimeSpec()
+ {
+ return $this->timeSpec;
+ }
+
+ /**
+ * @param string $timeSpec
+ */
+ public function setTimeSpec($timeSpec)
+ {
+ $this->timeSpec = $timeSpec;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTimeValue()
+ {
+ return $this->timeValue;
+ }
+
+ /**
+ * @param string $timeValue
+ */
+ public function setTimeValue($timeValue)
+ {
+ $this->timeValue = $timeValue;
+ }
+
+ /**
+ * appendToXml 把actions插入到xml中
+ *
+ * @param \SimpleXMLElement $xmlRule
+ */
+ public function appendToXml(&$xmlRule)
+ {
+ $xmlAction = $xmlRule->addChild($this->action);
+ $xmlAction->addChild($this->timeSpec, $this->timeValue);
+ }
+
+ private $action;
+ private $timeSpec;
+ private $timeValue;
+
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/LifecycleConfig.php b/framework/library/alioss/src/OSS/Model/LifecycleConfig.php
new file mode 100644
index 0000000..fc4f575
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/LifecycleConfig.php
@@ -0,0 +1,107 @@
+rules = array();
+ $xml = simplexml_load_string($strXml);
+ if (!isset($xml->Rule)) return;
+ $this->rules = array();
+ foreach ($xml->Rule as $rule) {
+ $id = strval($rule->ID);
+ $prefix = strval($rule->Prefix);
+ $status = strval($rule->Status);
+ $actions = array();
+ foreach ($rule as $key => $value) {
+ if ($key === 'ID' || $key === 'Prefix' || $key === 'Status') continue;
+ $action = $key;
+ $timeSpec = null;
+ $timeValue = null;
+ foreach ($value as $timeSpecKey => $timeValueValue) {
+ $timeSpec = $timeSpecKey;
+ $timeValue = strval($timeValueValue);
+ }
+ $actions[] = new LifecycleAction($action, $timeSpec, $timeValue);
+ }
+ $this->rules[] = new LifecycleRule($id, $prefix, $status, $actions);
+ }
+ return;
+ }
+
+
+ /**
+ * 生成xml字符串
+ *
+ * @return string
+ */
+ public function serializeToXml()
+ {
+
+ $xml = new \SimpleXMLElement(' ');
+ foreach ($this->rules as $rule) {
+ $xmlRule = $xml->addChild('Rule');
+ $rule->appendToXml($xmlRule);
+ }
+ return $xml->asXML();
+ }
+
+ /**
+ *
+ * 添加LifecycleRule
+ *
+ * @param LifecycleRule $lifecycleRule
+ * @throws OssException
+ */
+ public function addRule($lifecycleRule)
+ {
+ if (!isset($lifecycleRule)) {
+ throw new OssException("lifecycleRule is null");
+ }
+ $this->rules[] = $lifecycleRule;
+ }
+
+ /**
+ * 将配置转换成字符串,便于用户查看
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->serializeToXml();
+ }
+
+ /**
+ * 得到所有的生命周期规则
+ *
+ * @return LifecycleRule[]
+ */
+ public function getRules()
+ {
+ return $this->rules;
+ }
+
+ /**
+ * @var LifecycleRule[]
+ */
+ private $rules;
+}
+
+
diff --git a/framework/library/alioss/src/OSS/Model/LifecycleRule.php b/framework/library/alioss/src/OSS/Model/LifecycleRule.php
new file mode 100644
index 0000000..ec615b9
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/LifecycleRule.php
@@ -0,0 +1,126 @@
+id;
+ }
+
+ /**
+ * @param string $id 规则ID
+ */
+ public function setId($id)
+ {
+ $this->id = $id;
+ }
+
+ /**
+ * 得到文件前缀
+ *
+ * @return string
+ */
+ public function getPrefix()
+ {
+ return $this->prefix;
+ }
+
+ /**
+ * 设置文件前缀
+ *
+ * @param string $prefix 文件前缀
+ */
+ public function setPrefix($prefix)
+ {
+ $this->prefix = $prefix;
+ }
+
+ /**
+ * Lifecycle规则的状态
+ *
+ * @return string
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ /**
+ * 设置Lifecycle规则状态
+ *
+ * @param string $status
+ */
+ public function setStatus($status)
+ {
+ $this->status = $status;
+ }
+
+ /**
+ *
+ * @return LifecycleAction[]
+ */
+ public function getActions()
+ {
+ return $this->actions;
+ }
+
+ /**
+ * @param LifecycleAction[] $actions
+ */
+ public function setActions($actions)
+ {
+ $this->actions = $actions;
+ }
+
+
+ /**
+ * LifecycleRule constructor.
+ *
+ * @param string $id 规则ID
+ * @param string $prefix 文件前缀
+ * @param string $status 规则状态,可选[self::LIFECYCLE_STATUS_ENABLED, self::LIFECYCLE_STATUS_DISABLED]
+ * @param LifecycleAction[] $actions
+ */
+ public function __construct($id, $prefix, $status, $actions)
+ {
+ $this->id = $id;
+ $this->prefix = $prefix;
+ $this->status = $status;
+ $this->actions = $actions;
+ }
+
+ /**
+ * @param \SimpleXMLElement $xmlRule
+ */
+ public function appendToXml(&$xmlRule)
+ {
+ $xmlRule->addChild('ID', $this->id);
+ $xmlRule->addChild('Prefix', $this->prefix);
+ $xmlRule->addChild('Status', $this->status);
+ foreach ($this->actions as $action) {
+ $action->appendToXml($xmlRule);
+ }
+ }
+
+ private $id;
+ private $prefix;
+ private $status;
+ private $actions = array();
+
+ const LIFECYCLE_STATUS_ENABLED = 'Enabled';
+ const LIFECYCLE_STATUS_DISABLED = 'Disabled';
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/ListMultipartUploadInfo.php b/framework/library/alioss/src/OSS/Model/ListMultipartUploadInfo.php
new file mode 100644
index 0000000..105d005
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/ListMultipartUploadInfo.php
@@ -0,0 +1,134 @@
+bucket = $bucket;
+ $this->keyMarker = $keyMarker;
+ $this->uploadIdMarker = $uploadIdMarker;
+ $this->nextKeyMarker = $nextKeyMarker;
+ $this->nextUploadIdMarker = $nextUploadIdMarker;
+ $this->delimiter = $delimiter;
+ $this->prefix = $prefix;
+ $this->maxUploads = $maxUploads;
+ $this->isTruncated = $isTruncated;
+ $this->uploads = $uploads;
+ }
+
+ /**
+ * 得到bucket名称
+ *
+ * @return string
+ */
+ public function getBucket()
+ {
+ return $this->bucket;
+ }
+
+ /**
+ * @return string
+ */
+ public function getKeyMarker()
+ {
+ return $this->keyMarker;
+ }
+
+ /**
+ *
+ * @return string
+ */
+ public function getUploadIdMarker()
+ {
+ return $this->uploadIdMarker;
+ }
+
+ /**
+ * @return string
+ */
+ public function getNextKeyMarker()
+ {
+ return $this->nextKeyMarker;
+ }
+
+ /**
+ * @return string
+ */
+ public function getNextUploadIdMarker()
+ {
+ return $this->nextUploadIdMarker;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDelimiter()
+ {
+ return $this->delimiter;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPrefix()
+ {
+ return $this->prefix;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMaxUploads()
+ {
+ return $this->maxUploads;
+ }
+
+ /**
+ * @return string
+ */
+ public function getIsTruncated()
+ {
+ return $this->isTruncated;
+ }
+
+ /**
+ * @return UploadInfo[]
+ */
+ public function getUploads()
+ {
+ return $this->uploads;
+ }
+
+ private $bucket = "";
+ private $keyMarker = "";
+ private $uploadIdMarker = "";
+ private $nextKeyMarker = "";
+ private $nextUploadIdMarker = "";
+ private $delimiter = "";
+ private $prefix = "";
+ private $maxUploads = 0;
+ private $isTruncated = "false";
+ private $uploads = array();
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/ListPartsInfo.php b/framework/library/alioss/src/OSS/Model/ListPartsInfo.php
new file mode 100644
index 0000000..f1d10ee
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/ListPartsInfo.php
@@ -0,0 +1,97 @@
+bucket = $bucket;
+ $this->key = $key;
+ $this->uploadId = $uploadId;
+ $this->nextPartNumberMarker = $nextPartNumberMarker;
+ $this->maxParts = $maxParts;
+ $this->isTruncated = $isTruncated;
+ $this->listPart = $listPart;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBucket()
+ {
+ return $this->bucket;
+ }
+
+ /**
+ * @return string
+ */
+ public function getKey()
+ {
+ return $this->key;
+ }
+
+ /**
+ * @return string
+ */
+ public function getUploadId()
+ {
+ return $this->uploadId;
+ }
+
+ /**
+ * @return int
+ */
+ public function getNextPartNumberMarker()
+ {
+ return $this->nextPartNumberMarker;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMaxParts()
+ {
+ return $this->maxParts;
+ }
+
+ /**
+ * @return string
+ */
+ public function getIsTruncated()
+ {
+ return $this->isTruncated;
+ }
+
+ /**
+ * @return array
+ */
+ public function getListPart()
+ {
+ return $this->listPart;
+ }
+
+ private $bucket = "";
+ private $key = "";
+ private $uploadId = "";
+ private $nextPartNumberMarker = 0;
+ private $maxParts = 0;
+ private $isTruncated = "";
+ private $listPart = array();
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/LoggingConfig.php b/framework/library/alioss/src/OSS/Model/LoggingConfig.php
new file mode 100644
index 0000000..978421a
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/LoggingConfig.php
@@ -0,0 +1,86 @@
+targetBucket = $targetBucket;
+ $this->targetPrefix = $targetPrefix;
+ }
+
+ /**
+ * @param $strXml
+ * @return null
+ */
+ public function parseFromXml($strXml)
+ {
+ $xml = simplexml_load_string($strXml);
+ if (!isset($xml->LoggingEnabled)) return;
+ foreach ($xml->LoggingEnabled as $status) {
+ foreach ($status as $key => $value) {
+ if ($key === 'TargetBucket') {
+ $this->targetBucket = strval($value);
+ } elseif ($key === 'TargetPrefix') {
+ $this->targetPrefix = strval($value);
+ }
+ }
+ break;
+ }
+ }
+
+ /**
+ * 序列化成xml字符串
+ *
+ */
+ public function serializeToXml()
+ {
+ $xml = new \SimpleXMLElement(' ');
+ if (isset($this->targetBucket) && isset($this->targetPrefix)) {
+ $loggingEnabled = $xml->addChild('LoggingEnabled');
+ $loggingEnabled->addChild('TargetBucket', $this->targetBucket);
+ $loggingEnabled->addChild('TargetPrefix', $this->targetPrefix);
+ }
+ return $xml->asXML();
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->serializeToXml();
+ }
+
+ /**
+ * @return string
+ */
+ public function getTargetBucket()
+ {
+ return $this->targetBucket;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTargetPrefix()
+ {
+ return $this->targetPrefix;
+ }
+
+ private $targetBucket = "";
+ private $targetPrefix = "";
+
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/ObjectInfo.php b/framework/library/alioss/src/OSS/Model/ObjectInfo.php
new file mode 100644
index 0000000..2ae6c99
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/ObjectInfo.php
@@ -0,0 +1,93 @@
+key = $key;
+ $this->lastModified = $lastModified;
+ $this->eTag = $eTag;
+ $this->type = $type;
+ $this->size = $size;
+ $this->storageClass = $storageClass;
+ }
+
+ /**
+ * @return string
+ */
+ public function getKey()
+ {
+ return $this->key;
+ }
+
+ /**
+ * @return string
+ */
+ public function getLastModified()
+ {
+ return $this->lastModified;
+ }
+
+ /**
+ * @return string
+ */
+ public function getETag()
+ {
+ return $this->eTag;
+ }
+
+ /**
+ * @return string
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * @return int
+ */
+ public function getSize()
+ {
+ return $this->size;
+ }
+
+ /**
+ * @return string
+ */
+ public function getStorageClass()
+ {
+ return $this->storageClass;
+ }
+
+ private $key = "";
+ private $lastModified = "";
+ private $eTag = "";
+ private $type = "";
+ private $size = 0;
+ private $storageClass = "";
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/ObjectListInfo.php b/framework/library/alioss/src/OSS/Model/ObjectListInfo.php
new file mode 100644
index 0000000..dbe7c7a
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/ObjectListInfo.php
@@ -0,0 +1,126 @@
+bucketName = $bucketName;
+ $this->prefix = $prefix;
+ $this->marker = $marker;
+ $this->nextMarker = $nextMarker;
+ $this->maxKeys = $maxKeys;
+ $this->delimiter = $delimiter;
+ $this->isTruncated = $isTruncated;
+ $this->objectList = $objectList;
+ $this->prefixList = $prefixList;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBucketName()
+ {
+ return $this->bucketName;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPrefix()
+ {
+ return $this->prefix;
+ }
+
+ /**
+ * @return string
+ */
+ public function getMarker()
+ {
+ return $this->marker;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMaxKeys()
+ {
+ return $this->maxKeys;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDelimiter()
+ {
+ return $this->delimiter;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getIsTruncated()
+ {
+ return $this->isTruncated;
+ }
+
+ /**
+ * 返回ListObjects接口返回数据中的ObjectInfo列表
+ *
+ * @return ObjectInfo[]
+ */
+ public function getObjectList()
+ {
+ return $this->objectList;
+ }
+
+ /**
+ * 返回ListObjects接口返回数据中的PrefixInfo列表
+ *
+ * @return PrefixInfo[]
+ */
+ public function getPrefixList()
+ {
+ return $this->prefixList;
+ }
+
+ /**
+ * @return string
+ */
+ public function getNextMarker()
+ {
+ return $this->nextMarker;
+ }
+
+ private $bucketName = "";
+ private $prefix = "";
+ private $marker = "";
+ private $nextMarker = "";
+ private $maxKeys = 0;
+ private $delimiter = "";
+ private $isTruncated = null;
+ private $objectList = array();
+ private $prefixList = array();
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/PartInfo.php b/framework/library/alioss/src/OSS/Model/PartInfo.php
new file mode 100644
index 0000000..439a84d
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/PartInfo.php
@@ -0,0 +1,63 @@
+partNumber = $partNumber;
+ $this->lastModified = $lastModified;
+ $this->eTag = $eTag;
+ $this->size = $size;
+ }
+
+ /**
+ * @return int
+ */
+ public function getPartNumber()
+ {
+ return $this->partNumber;
+ }
+
+ /**
+ * @return string
+ */
+ public function getLastModified()
+ {
+ return $this->lastModified;
+ }
+
+ /**
+ * @return string
+ */
+ public function getETag()
+ {
+ return $this->eTag;
+ }
+
+ /**
+ * @return int
+ */
+ public function getSize()
+ {
+ return $this->size;
+ }
+
+ private $partNumber = 0;
+ private $lastModified = "";
+ private $eTag = "";
+ private $size = 0;
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/PrefixInfo.php b/framework/library/alioss/src/OSS/Model/PrefixInfo.php
new file mode 100644
index 0000000..e61eac4
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/PrefixInfo.php
@@ -0,0 +1,36 @@
+prefix = $prefix;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPrefix()
+ {
+ return $this->prefix;
+ }
+
+ private $prefix;
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/RefererConfig.php b/framework/library/alioss/src/OSS/Model/RefererConfig.php
new file mode 100644
index 0000000..1d7d975
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/RefererConfig.php
@@ -0,0 +1,93 @@
+AllowEmptyReferer)) return;
+ if (!isset($xml->RefererList)) return;
+ $this->allowEmptyReferer =
+ (strval($xml->AllowEmptyReferer) === 'TRUE' || strval($xml->AllowEmptyReferer) === 'true') ? true : false;
+
+ foreach ($xml->RefererList->Referer as $key => $refer) {
+ $this->refererList[] = strval($refer);
+ }
+ }
+
+
+ /**
+ * 把RefererConfig序列化成xml
+ *
+ * @return string
+ */
+ public function serializeToXml()
+ {
+ $xml = new \SimpleXMLElement(' ');
+ if ($this->allowEmptyReferer) {
+ $xml->addChild('AllowEmptyReferer', 'true');
+ } else {
+ $xml->addChild('AllowEmptyReferer', 'false');
+ }
+ $refererList = $xml->addChild('RefererList');
+ foreach ($this->refererList as $referer) {
+ $refererList->addChild('Referer', $referer);
+ }
+ return $xml->asXML();
+ }
+
+ /**
+ * @return string
+ */
+ function __toString()
+ {
+ return $this->serializeToXml();
+ }
+
+ /**
+ * @param boolean $allowEmptyReferer
+ */
+ public function setAllowEmptyReferer($allowEmptyReferer)
+ {
+ $this->allowEmptyReferer = $allowEmptyReferer;
+ }
+
+ /**
+ * @param string $referer
+ */
+ public function addReferer($referer)
+ {
+ $this->refererList[] = $referer;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isAllowEmptyReferer()
+ {
+ return $this->allowEmptyReferer;
+ }
+
+ /**
+ * @return array
+ */
+ public function getRefererList()
+ {
+ return $this->refererList;
+ }
+
+ private $allowEmptyReferer = true;
+ private $refererList = array();
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/UploadInfo.php b/framework/library/alioss/src/OSS/Model/UploadInfo.php
new file mode 100644
index 0000000..8eaa363
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/UploadInfo.php
@@ -0,0 +1,55 @@
+key = $key;
+ $this->uploadId = $uploadId;
+ $this->initiated = $initiated;
+ }
+
+ /**
+ * @return string
+ */
+ public function getKey()
+ {
+ return $this->key;
+ }
+
+ /**
+ * @return string
+ */
+ public function getUploadId()
+ {
+ return $this->uploadId;
+ }
+
+ /**
+ * @return string
+ */
+ public function getInitiated()
+ {
+ return $this->initiated;
+ }
+
+ private $key = "";
+ private $uploadId = "";
+ private $initiated = "";
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/WebsiteConfig.php b/framework/library/alioss/src/OSS/Model/WebsiteConfig.php
new file mode 100644
index 0000000..8ea08a0
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/WebsiteConfig.php
@@ -0,0 +1,76 @@
+indexDocument = $indexDocument;
+ $this->errorDocument = $errorDocument;
+ }
+
+ /**
+ * @param string $strXml
+ * @return null
+ */
+ public function parseFromXml($strXml)
+ {
+ $xml = simplexml_load_string($strXml);
+ if (isset($xml->IndexDocument) && isset($xml->IndexDocument->Suffix)) {
+ $this->indexDocument = strval($xml->IndexDocument->Suffix);
+ }
+ if (isset($xml->ErrorDocument) && isset($xml->ErrorDocument->Key)) {
+ $this->errorDocument = strval($xml->ErrorDocument->Key);
+ }
+ }
+
+ /**
+ * 把WebsiteConfig序列化成xml
+ *
+ * @return string
+ * @throws OssException
+ */
+ public function serializeToXml()
+ {
+ $xml = new \SimpleXMLElement(' ');
+ $index_document_part = $xml->addChild('IndexDocument');
+ $error_document_part = $xml->addChild('ErrorDocument');
+ $index_document_part->addChild('Suffix', $this->indexDocument);
+ $error_document_part->addChild('Key', $this->errorDocument);
+ return $xml->asXML();
+ }
+
+ /**
+ * @return string
+ */
+ public function getIndexDocument()
+ {
+ return $this->indexDocument;
+ }
+
+ /**
+ * @return string
+ */
+ public function getErrorDocument()
+ {
+ return $this->errorDocument;
+ }
+
+ private $indexDocument = "";
+ private $errorDocument = "";
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Model/XmlConfig.php b/framework/library/alioss/src/OSS/Model/XmlConfig.php
new file mode 100644
index 0000000..d353a22
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Model/XmlConfig.php
@@ -0,0 +1,27 @@
+hostname = $this->checkEndpoint($endpoint, $isCName);
+ $this->accessKeyId = $accessKeyId;
+ $this->accessKeySecret = $accessKeySecret;
+ $this->securityToken = $securityToken;
+ self::checkEnv();
+ }
+
+ /**
+ * 列举用户所有的Bucket[GetService], Endpoint类型为cname不能进行此操作
+ *
+ * @param array $options
+ * @throws OssException
+ * @return BucketListInfo
+ */
+ public function listBuckets($options = NULL)
+ {
+ if ($this->hostType === self::OSS_HOST_TYPE_CNAME) {
+ throw new OssException("operation is not permitted with CName host");
+ }
+ $this->precheckOptions($options);
+ $options[self::OSS_BUCKET] = '';
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $response = $this->auth($options);
+ $result = new ListBucketsResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 创建bucket,默认创建的bucket的ACL是OssClient::OSS_ACL_TYPE_PRIVATE
+ *
+ * @param string $bucket
+ * @param string $acl
+ * @param array $options
+ * @return null
+ */
+ public function createBucket($bucket, $acl = self::OSS_ACL_TYPE_PRIVATE, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl);
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 删除bucket
+ * 如果Bucket不为空(Bucket中有Object,或者有分块上传的碎片),则Bucket无法删除,
+ * 必须删除Bucket中的所有Object以及碎片后,Bucket才能成功删除。
+ *
+ * @param string $bucket
+ * @param array $options
+ * @return null
+ */
+ public function deleteBucket($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;
+ $options[self::OSS_OBJECT] = '/';
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 判断bucket是否存在
+ *
+ * @param string $bucket
+ * @return bool
+ * @throws OssException
+ */
+ public function doesBucketExist($bucket)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'acl';
+ $response = $this->auth($options);
+ $result = new ExistResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取bucket的ACL配置情况
+ *
+ * @param string $bucket
+ * @param array $options
+ * @throws OssException
+ * @return string
+ */
+ public function getBucketAcl($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'acl';
+ $response = $this->auth($options);
+ $result = new AclResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 设置bucket的ACL配置情况
+ *
+ * @param string $bucket bucket名称
+ * @param string $acl 读写权限,可选值 ['private', 'public-read', 'public-read-write']
+ * @param array $options 可以为空
+ * @throws OssException
+ * @return null
+ */
+ public function putBucketAcl($bucket, $acl, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl);
+ $options[self::OSS_SUB_RESOURCE] = 'acl';
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取object的ACL属性
+ *
+ * @param string $bucket
+ * @param string $object
+ * @throws OssException
+ * @return string
+ */
+ public function getObjectAcl($bucket, $object)
+ {
+ $options = array();
+ $this->precheckCommon($bucket, $object, $options, true);
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_SUB_RESOURCE] = 'acl';
+ $response = $this->auth($options);
+ $result = new AclResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 设置object的ACL属性
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param string $acl 读写权限,可选值 ['default', 'private', 'public-read', 'public-read-write']
+ * @throws OssException
+ * @return null
+ */
+ public function putObjectAcl($bucket, $object, $acl)
+ {
+ $this->precheckCommon($bucket, $object, $options, true);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_ACL => $acl);
+ $options[self::OSS_SUB_RESOURCE] = 'acl';
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取Bucket的访问日志配置情况
+ *
+ * @param string $bucket bucket名称
+ * @param array $options 可以为空
+ * @throws OssException
+ * @return LoggingConfig
+ */
+ public function getBucketLogging($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'logging';
+ $response = $this->auth($options);
+ $result = new GetLoggingResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 开启Bucket访问日志记录功能,只有Bucket的所有者才能更改
+ *
+ * @param string $bucket bucket名称
+ * @param string $targetBucket 日志文件存放的bucket
+ * @param string $targetPrefix 日志的文件前缀
+ * @param array $options 可以为空
+ * @throws OssException
+ * @return null
+ */
+ public function putBucketLogging($bucket, $targetBucket, $targetPrefix, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $this->precheckBucket($targetBucket, 'targetbucket is not allowed empty');
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'logging';
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+
+ $loggingConfig = new LoggingConfig($targetBucket, $targetPrefix);
+ $options[self::OSS_CONTENT] = $loggingConfig->serializeToXml();
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 关闭bucket访问日志记录功能
+ *
+ * @param string $bucket bucket名称
+ * @param array $options 可以为空
+ * @throws OssException
+ * @return null
+ */
+ public function deleteBucketLogging($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'logging';
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 将bucket设置成静态网站托管模式
+ *
+ * @param string $bucket bucket名称
+ * @param WebsiteConfig $websiteConfig
+ * @param array $options 可以为空
+ * @throws OssException
+ * @return null
+ */
+ public function putBucketWebsite($bucket, $websiteConfig, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'website';
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+ $options[self::OSS_CONTENT] = $websiteConfig->serializeToXml();
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取bucket的静态网站托管状态
+ *
+ * @param string $bucket bucket名称
+ * @param array $options
+ * @throws OssException
+ * @return WebsiteConfig
+ */
+ public function getBucketWebsite($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'website';
+ $response = $this->auth($options);
+ $result = new GetWebsiteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 关闭bucket的静态网站托管模式
+ *
+ * @param string $bucket bucket名称
+ * @param array $options
+ * @throws OssException
+ * @return null
+ */
+ public function deleteBucketWebsite($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'website';
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 在指定的bucket上设定一个跨域资源共享(CORS)的规则,如果原规则存在则覆盖原规则
+ *
+ * @param string $bucket bucket名称
+ * @param CorsConfig $corsConfig 跨域资源共享配置,具体规则参见SDK文档
+ * @param array $options array
+ * @throws OssException
+ * @return null
+ */
+ public function putBucketCors($bucket, $corsConfig, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'cors';
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+ $options[self::OSS_CONTENT] = $corsConfig->serializeToXml();
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取Bucket的CORS配置情况
+ *
+ * @param string $bucket bucket名称
+ * @param array $options 可以为空
+ * @throws OssException
+ * @return CorsConfig
+ */
+ public function getBucketCors($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'cors';
+ $response = $this->auth($options);
+ $result = new GetCorsResult($response, __FUNCTION__);
+ return $result->getData();
+ }
+
+ /**
+ * 关闭指定Bucket对应的CORS功能并清空所有规则
+ *
+ * @param string $bucket bucket名称
+ * @param array $options
+ * @throws OssException
+ * @return null
+ */
+ public function deleteBucketCors($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'cors';
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 为指定Bucket增加CNAME绑定
+ *
+ * @param string $bucket bucket名称
+ * @param string $cname
+ * @param array $options
+ * @throws OssException
+ * @return null
+ */
+ public function addBucketCname($bucket, $cname, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'cname';
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+ $cnameConfig = new CnameConfig();
+ $cnameConfig->addCname($cname);
+ $options[self::OSS_CONTENT] = $cnameConfig->serializeToXml();
+ $options[self::OSS_CNAME_COMP] = 'add';
+
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取指定Bucket已绑定的CNAME列表
+ *
+ * @param string $bucket bucket名称
+ * @param array $options
+ * @throws OssException
+ * @return CnameConfig
+ */
+ public function getBucketCname($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'cname';
+ $response = $this->auth($options);
+ $result = new GetCnameResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 解除指定Bucket的CNAME绑定
+ *
+ * @param string $bucket bucket名称
+ * @param CnameConfig $cnameConfig
+ * @param array $options
+ * @throws OssException
+ * @return null
+ */
+ public function deleteBucketCname($bucket, $cname, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'cname';
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+ $cnameConfig = new CnameConfig();
+ $cnameConfig->addCname($cname);
+ $options[self::OSS_CONTENT] = $cnameConfig->serializeToXml();
+ $options[self::OSS_CNAME_COMP] = 'delete';
+
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 检验跨域资源请求, 发送跨域请求之前会发送一个preflight请求(OPTIONS)并带上特定的来源域,
+ * HTTP方法和header信息等给OSS以决定是否发送真正的请求。 OSS可以通过putBucketCors接口
+ * 来开启Bucket的CORS支持,开启CORS功能之后,OSS在收到浏览器preflight请求时会根据设定的
+ * 规则评估是否允许本次请求
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param string $origin 请求来源域
+ * @param string $request_method 表明实际请求中会使用的HTTP方法
+ * @param string $request_headers 表明实际请求中会使用的除了简单头部之外的headers
+ * @param array $options
+ * @return array
+ * @throws OssException
+ * @link http://help.aliyun.com/document_detail/oss/api-reference/cors/OptionObject.html
+ */
+ public function optionsObject($bucket, $object, $origin, $request_method, $request_headers, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_OPTIONS;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_HEADERS] = array(
+ self::OSS_OPTIONS_ORIGIN => $origin,
+ self::OSS_OPTIONS_REQUEST_HEADERS => $request_headers,
+ self::OSS_OPTIONS_REQUEST_METHOD => $request_method
+ );
+ $response = $this->auth($options);
+ $result = new HeaderResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 设置Bucket的Lifecycle配置
+ *
+ * @param string $bucket bucket名称
+ * @param LifecycleConfig $lifecycleConfig Lifecycle配置类
+ * @param array $options
+ * @throws OssException
+ * @return null
+ */
+ public function putBucketLifecycle($bucket, $lifecycleConfig, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'lifecycle';
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+ $options[self::OSS_CONTENT] = $lifecycleConfig->serializeToXml();
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取Bucket的Lifecycle配置情况
+ *
+ * @param string $bucket bucket名称
+ * @param array $options
+ * @throws OssException
+ * @return LifecycleConfig
+ */
+ public function getBucketLifecycle($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'lifecycle';
+ $response = $this->auth($options);
+ $result = new GetLifecycleResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 删除指定Bucket的生命周期配置
+ *
+ * @param string $bucket bucket名称
+ * @param array $options
+ * @throws OssException
+ * @return null
+ */
+ public function deleteBucketLifecycle($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'lifecycle';
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 设置一个bucket的referer访问白名单和是否允许referer字段为空的请求访问
+ * Bucket Referer防盗链具体见OSS防盗链
+ *
+ * @param string $bucket bucket名称
+ * @param RefererConfig $refererConfig
+ * @param array $options
+ * @return ResponseCore
+ * @throws null
+ */
+ public function putBucketReferer($bucket, $refererConfig, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'referer';
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+ $options[self::OSS_CONTENT] = $refererConfig->serializeToXml();
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取Bucket的Referer配置情况
+ * Bucket Referer防盗链具体见OSS防盗链
+ *
+ * @param string $bucket bucket名称
+ * @param array $options
+ * @throws OssException
+ * @return RefererConfig
+ */
+ public function getBucketReferer($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'referer';
+ $response = $this->auth($options);
+ $result = new GetRefererResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取bucket下的object列表
+ *
+ * @param string $bucket
+ * @param array $options
+ * 其中options中的参数如下
+ * $options = array(
+ * 'max-keys' => max-keys用于限定此次返回object的最大数,如果不设定,默认为100,max-keys取值不能大于1000。
+ * 'prefix' => 限定返回的object key必须以prefix作为前缀。注意使用prefix查询时,返回的key中仍会包含prefix。
+ * 'delimiter' => 是一个用于对Object名字进行分组的字符。所有名字包含指定的前缀且第一次出现delimiter字符之间的object作为一组元素
+ * 'marker' => 用户设定结果从marker之后按字母排序的第一个开始返回。
+ *)
+ * 其中 prefix,marker用来实现分页显示效果,参数的长度必须小于256字节。
+ * @throws OssException
+ * @return ObjectListInfo
+ */
+ public function listObjects($bucket, $options = NULL)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_HEADERS] = array(
+ self::OSS_DELIMITER => isset($options[self::OSS_DELIMITER]) ? $options[self::OSS_DELIMITER] : '/',
+ self::OSS_PREFIX => isset($options[self::OSS_PREFIX]) ? $options[self::OSS_PREFIX] : '',
+ self::OSS_MAX_KEYS => isset($options[self::OSS_MAX_KEYS]) ? $options[self::OSS_MAX_KEYS] : self::OSS_MAX_KEYS_VALUE,
+ self::OSS_MARKER => isset($options[self::OSS_MARKER]) ? $options[self::OSS_MARKER] : '',
+ );
+ $query = isset($options[self::OSS_QUERY_STRING]) ? $options[self::OSS_QUERY_STRING] : array();
+ $options[self::OSS_QUERY_STRING] = array_merge(
+ $query,
+ array(self::OSS_ENCODING_TYPE => self::OSS_ENCODING_TYPE_URL)
+ );
+
+ $response = $this->auth($options);
+ $result = new ListObjectsResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 创建虚拟目录 (本函数会在object名称后增加'/', 所以创建目录的object名称不需要'/'结尾,否则,目录名称会变成'//')
+ *
+ * 暂不开放此接口
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param array $options
+ * @return null
+ */
+ public function createObjectDir($bucket, $object, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = $object . '/';
+ $options[self::OSS_CONTENT_LENGTH] = array(self::OSS_CONTENT_LENGTH => 0);
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 上传内存中的内容
+ *
+ * @param string $bucket bucket名称
+ * @param string $object objcet名称
+ * @param string $content 上传的内容
+ * @param array $options
+ * @return null
+ */
+ public function putObject($bucket, $object, $content, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+
+ OssUtil::validateContent($content);
+ $options[self::OSS_CONTENT] = $content;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = $object;
+
+ if (!isset($options[self::OSS_LENGTH])) {
+ $options[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]);
+ } else {
+ $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH];
+ }
+
+ if (!isset($options[self::OSS_CONTENT_TYPE])) {
+ $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object);
+ }
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 上传本地文件
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param string $file 本地文件路径
+ * @param array $options
+ * @return null
+ * @throws OssException
+ */
+ public function uploadFile($bucket, $object, $file, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ OssUtil::throwOssExceptionWithMessageIfEmpty($file, "file path is invalid");
+ $file = OssUtil::encodePath($file);
+ if (!file_exists($file)) {
+ throw new OssException($file . " file does not exist");
+ }
+ $options[self::OSS_FILE_UPLOAD] = $file;
+ $file_size = filesize($options[self::OSS_FILE_UPLOAD]);
+ $is_check_md5 = $this->isCheckMD5($options);
+ if ($is_check_md5) {
+ $content_md5 = base64_encode(md5_file($options[self::OSS_FILE_UPLOAD], true));
+ $options[self::OSS_CONTENT_MD5] = $content_md5;
+ }
+ if (!isset($options[self::OSS_CONTENT_TYPE])) {
+ $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $file);
+ }
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_CONTENT_LENGTH] = $file_size;
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 追加上传内存中的内容
+ *
+ * @param string $bucket bucket名称
+ * @param string $object objcet名称
+ * @param string $content 本次追加上传的内容
+ * @param array $options
+ * @return int next append position
+ * @throws OssException
+ */
+ public function appendObject($bucket, $object, $content, $position, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+
+ OssUtil::validateContent($content);
+ $options[self::OSS_CONTENT] = $content;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_SUB_RESOURCE] = 'append';
+ $options[self::OSS_POSITION] = strval($position);
+
+ if (!isset($options[self::OSS_LENGTH])) {
+ $options[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]);
+ } else {
+ $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH];
+ }
+
+ if (!isset($options[self::OSS_CONTENT_TYPE])) {
+ $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object);
+ }
+ $response = $this->auth($options);
+ $result = new AppendResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 追加上传本地文件
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param string $file 追加上传的本地文件路径
+ * @param array $options
+ * @return int next append position
+ * @throws OssException
+ */
+ public function appendFile($bucket, $object, $file, $position, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+
+ OssUtil::throwOssExceptionWithMessageIfEmpty($file, "file path is invalid");
+ $file = OssUtil::encodePath($file);
+ if (!file_exists($file)) {
+ throw new OssException($file . " file does not exist");
+ }
+ $options[self::OSS_FILE_UPLOAD] = $file;
+ $file_size = filesize($options[self::OSS_FILE_UPLOAD]);
+ $is_check_md5 = $this->isCheckMD5($options);
+ if ($is_check_md5) {
+ $content_md5 = base64_encode(md5_file($options[self::OSS_FILE_UPLOAD], true));
+ $options[self::OSS_CONTENT_MD5] = $content_md5;
+ }
+ if (!isset($options[self::OSS_CONTENT_TYPE])) {
+ $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $file);
+ }
+
+ $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_CONTENT_LENGTH] = $file_size;
+ $options[self::OSS_SUB_RESOURCE] = 'append';
+ $options[self::OSS_POSITION] = strval($position);
+
+ $response = $this->auth($options);
+ $result = new AppendResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 拷贝一个在OSS上已经存在的object成另外一个object
+ *
+ * @param string $fromBucket 源bucket名称
+ * @param string $fromObject 源object名称
+ * @param string $toBucket 目标bucket名称
+ * @param string $toObject 目标object名称
+ * @param array $options
+ * @return null
+ * @throws OssException
+ */
+ public function copyObject($fromBucket, $fromObject, $toBucket, $toObject, $options = NULL)
+ {
+ $this->precheckCommon($fromBucket, $fromObject, $options);
+ $this->precheckCommon($toBucket, $toObject, $options);
+ $options[self::OSS_BUCKET] = $toBucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_OBJECT] = $toObject;
+ if (isset($options[self::OSS_HEADERS])) {
+ $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = '/' . $fromBucket . '/' . $fromObject;
+ } else {
+ $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_COPY_SOURCE => '/' . $fromBucket . '/' . $fromObject);
+ }
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取Object的Meta信息
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param string $options 具体参考SDK文档
+ * @return array
+ */
+ public function getObjectMeta($bucket, $object, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_HEAD;
+ $options[self::OSS_OBJECT] = $object;
+ $response = $this->auth($options);
+ $result = new HeaderResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 删除某个Object
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param array $options
+ * @return null
+ */
+ public function deleteObject($bucket, $object, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;
+ $options[self::OSS_OBJECT] = $object;
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 删除同一个Bucket中的多个Object
+ *
+ * @param string $bucket bucket名称
+ * @param array $objects object列表
+ * @param array $options
+ * @return ResponseCore
+ * @throws null
+ */
+ public function deleteObjects($bucket, $objects, $options = null)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ if (!is_array($objects) || !$objects) {
+ throw new OssException('objects must be array');
+ }
+ $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'delete';
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+ $quiet = 'false';
+ if (isset($options['quiet'])) {
+ if (is_bool($options['quiet'])) { //Boolean
+ $quiet = $options['quiet'] ? 'true' : 'false';
+ } elseif (is_string($options['quiet'])) { // string
+ $quiet = ($options['quiet'] === 'true') ? 'true' : 'false';
+ }
+ }
+ $xmlBody = OssUtil::createDeleteObjectsXmlBody($objects, $quiet);
+ $options[self::OSS_CONTENT] = $xmlBody;
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获得Object内容
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param array $options 该参数中必须设置ALIOSS::OSS_FILE_DOWNLOAD,ALIOSS::OSS_RANGE可选,可以根据实际情况设置;如果不设置,默认会下载全部内容
+ * @return string
+ */
+ public function getObject($bucket, $object, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_OBJECT] = $object;
+ if (isset($options[self::OSS_LAST_MODIFIED])) {
+ $options[self::OSS_HEADERS][self::OSS_IF_MODIFIED_SINCE] = $options[self::OSS_LAST_MODIFIED];
+ unset($options[self::OSS_LAST_MODIFIED]);
+ }
+ if (isset($options[self::OSS_ETAG])) {
+ $options[self::OSS_HEADERS][self::OSS_IF_NONE_MATCH] = $options[self::OSS_ETAG];
+ unset($options[self::OSS_ETAG]);
+ }
+ if (isset($options[self::OSS_RANGE])) {
+ $range = $options[self::OSS_RANGE];
+ $options[self::OSS_HEADERS][self::OSS_RANGE] = "bytes=$range";
+ unset($options[self::OSS_RANGE]);
+ }
+ $response = $this->auth($options);
+ $result = new BodyResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 检测Object是否存在
+ * 通过获取Object的Meta信息来判断Object是否存在, 用户需要自行解析ResponseCore判断object是否存在
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param array $options
+ * @return bool
+ */
+ public function doesObjectExist($bucket, $object, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_METHOD] = self::OSS_HTTP_HEAD;
+ $options[self::OSS_OBJECT] = $object;
+ $response = $this->auth($options);
+ $result = new ExistResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取分片大小,根据用户提供的part_size,重新计算一个更合理的partsize
+ *
+ * @param int $partSize
+ * @return int
+ */
+ private function computePartSize($partSize)
+ {
+ $partSize = (integer)$partSize;
+ if ($partSize <= self::OSS_MIN_PART_SIZE) {
+ $partSize = self::OSS_MIN_PART_SIZE;
+ } elseif ($partSize > self::OSS_MAX_PART_SIZE) {
+ $partSize = self::OSS_MAX_PART_SIZE;
+ }
+ return $partSize;
+ }
+
+ /**
+ * 计算文件可以分成多少个part,以及每个part的长度以及起始位置
+ * 方法必须在 中调用
+ *
+ * @param integer $file_size 文件大小
+ * @param integer $partSize part大小,默认5M
+ * @return array An array 包含 key-value 键值对. Key 为 `seekTo` 和 `length`.
+ */
+ public function generateMultiuploadParts($file_size, $partSize = 5242880)
+ {
+ $i = 0;
+ $size_count = $file_size;
+ $values = array();
+ $partSize = $this->computePartSize($partSize);
+ while ($size_count > 0) {
+ $size_count -= $partSize;
+ $values[] = array(
+ self::OSS_SEEK_TO => ($partSize * $i),
+ self::OSS_LENGTH => (($size_count > 0) ? $partSize : ($size_count + $partSize)),
+ );
+ $i++;
+ }
+ return $values;
+ }
+
+ /**
+ * 初始化multi-part upload
+ *
+ * @param string $bucket Bucket名称
+ * @param string $object Object名称
+ * @param array $options Key-Value数组
+ * @throws OssException
+ * @return string 返回uploadid
+ */
+ public function initiateMultipartUpload($bucket, $object, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_SUB_RESOURCE] = 'uploads';
+ $options[self::OSS_CONTENT] = '';
+
+ if (!isset($options[self::OSS_CONTENT_TYPE])) {
+ $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object);
+ }
+ if (!isset($options[self::OSS_HEADERS])) {
+ $options[self::OSS_HEADERS] = array();
+ }
+ $response = $this->auth($options);
+ $result = new InitiateMultipartUploadResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 分片上传的块上传接口
+ *
+ * @param string $bucket Bucket名称
+ * @param string $object Object名称
+ * @param string $uploadId
+ * @param array $options Key-Value数组
+ * @return string eTag
+ * @throws OssException
+ */
+ public function uploadPart($bucket, $object, $uploadId, $options = null)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $this->precheckParam($options, self::OSS_FILE_UPLOAD, __FUNCTION__);
+ $this->precheckParam($options, self::OSS_PART_NUM, __FUNCTION__);
+
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_UPLOAD_ID] = $uploadId;
+
+ if (isset($options[self::OSS_LENGTH])) {
+ $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH];
+ }
+ $response = $this->auth($options);
+ $result = new UploadPartResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 获取已成功上传的part
+ *
+ * @param string $bucket Bucket名称
+ * @param string $object Object名称
+ * @param string $uploadId uploadId
+ * @param array $options Key-Value数组
+ * @return ListPartsInfo
+ * @throws OssException
+ */
+ public function listParts($bucket, $object, $uploadId, $options = null)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_UPLOAD_ID] = $uploadId;
+ $options[self::OSS_QUERY_STRING] = array();
+ foreach (array('max-parts', 'part-number-marker') as $param) {
+ if (isset($options[$param])) {
+ $options[self::OSS_QUERY_STRING][$param] = $options[$param];
+ unset($options[$param]);
+ }
+ }
+ $response = $this->auth($options);
+ $result = new ListPartsResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 中止进行一半的分片上传操作
+ *
+ * @param string $bucket Bucket名称
+ * @param string $object Object名称
+ * @param string $uploadId uploadId
+ * @param array $options Key-Value数组
+ * @return null
+ * @throws OssException
+ */
+ public function abortMultipartUpload($bucket, $object, $uploadId, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_UPLOAD_ID] = $uploadId;
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 在将所有数据Part都上传完成后,调用此接口完成本次分块上传
+ *
+ * @param string $bucket Bucket名称
+ * @param string $object Object名称
+ * @param string $uploadId uploadId
+ * @param array $listParts array( array("PartNumber"=> int, "ETag"=>string))
+ * @param array $options Key-Value数组
+ * @throws OssException
+ * @return null
+ */
+ public function completeMultipartUpload($bucket, $object, $uploadId, $listParts, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_UPLOAD_ID] = $uploadId;
+ $options[self::OSS_CONTENT_TYPE] = 'application/xml';
+ if (!is_array($listParts)) {
+ throw new OssException("listParts must be array type");
+ }
+ $options[self::OSS_CONTENT] = OssUtil::createCompleteMultipartUploadXmlBody($listParts);
+ $response = $this->auth($options);
+ $result = new PutSetDeleteResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 罗列出所有执行中的Multipart Upload事件,即已经被初始化的Multipart Upload但是未被
+ * Complete或者Abort的Multipart Upload事件
+ *
+ * @param string $bucket bucket
+ * @param array $options 关联数组
+ * @throws OssException
+ * @return ListMultipartUploadInfo
+ */
+ public function listMultipartUploads($bucket, $options = null)
+ {
+ $this->precheckCommon($bucket, NULL, $options, false);
+ $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = '/';
+ $options[self::OSS_SUB_RESOURCE] = 'uploads';
+
+ foreach (array('delimiter', 'key-marker', 'max-uploads', 'prefix', 'upload-id-marker') as $param) {
+ if (isset($options[$param])) {
+ $options[self::OSS_QUERY_STRING][$param] = $options[$param];
+ unset($options[$param]);
+ }
+ }
+ $query = isset($options[self::OSS_QUERY_STRING]) ? $options[self::OSS_QUERY_STRING] : array();
+ $options[self::OSS_QUERY_STRING] = array_merge(
+ $query,
+ array(self::OSS_ENCODING_TYPE => self::OSS_ENCODING_TYPE_URL)
+ );
+
+ $response = $this->auth($options);
+ $result = new ListMultipartUploadResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * 从一个已存在的Object中拷贝数据来上传一个Part
+ *
+ * @param string $fromBucket 源bucket名称
+ * @param string $fromObject 源object名称
+ * @param string $toBucket 目标bucket名称
+ * @param string $toObject 目标object名称
+ * @param int $partNumber 分块上传的块id
+ * @param string $uploadId 初始化multipart upload返回的uploadid
+ * @param array $options Key-Value数组
+ * @return null
+ * @throws OssException
+ */
+ public function uploadPartCopy($fromBucket, $fromObject, $toBucket, $toObject, $partNumber, $uploadId, $options = NULL)
+ {
+ $this->precheckCommon($fromBucket, $fromObject, $options);
+ $this->precheckCommon($toBucket, $toObject, $options);
+
+ //如果没有设置$options['isFullCopy'],则需要强制判断copy的起止位置
+ $start_range = "0";
+ if (isset($options['start'])) {
+ $start_range = $options['start'];
+ }
+ $end_range = "";
+ if (isset($options['end'])) {
+ $end_range = $options['end'];
+ }
+ $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
+ $options[self::OSS_BUCKET] = $toBucket;
+ $options[self::OSS_OBJECT] = $toObject;
+ $options[self::OSS_PART_NUM] = $partNumber;
+ $options[self::OSS_UPLOAD_ID] = $uploadId;
+
+ if (!isset($options[self::OSS_HEADERS])) {
+ $options[self::OSS_HEADERS] = array();
+ }
+
+ $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = '/' . $fromBucket . '/' . $fromObject;
+ $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE_RANGE] = "bytes=" . $start_range . "-" . $end_range;
+ $response = $this->auth($options);
+ $result = new UploadPartResult($response);
+ return $result->getData();
+ }
+
+ /**
+ * multipart上传统一封装,从初始化到完成multipart,以及出错后中止动作
+ *
+ * @param string $bucket bucket名称
+ * @param string $object object名称
+ * @param string $file 需要上传的本地文件的路径
+ * @param array $options Key-Value数组
+ * @return null
+ * @throws OssException
+ */
+ public function multiuploadFile($bucket, $object, $file, $options = null)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ if (isset($options[self::OSS_LENGTH])) {
+ $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH];
+ unset($options[self::OSS_LENGTH]);
+ }
+ if (empty($file)) {
+ throw new OssException("parameter invalid, file is empty");
+ }
+ $uploadFile = OssUtil::encodePath($file);
+ if (!isset($options[self::OSS_CONTENT_TYPE])) {
+ $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $uploadFile);
+ }
+
+ $upload_position = isset($options[self::OSS_SEEK_TO]) ? (integer)$options[self::OSS_SEEK_TO] : 0;
+
+ if (isset($options[self::OSS_CONTENT_LENGTH])) {
+ $upload_file_size = (integer)$options[self::OSS_CONTENT_LENGTH];
+ } else {
+ $upload_file_size = filesize($uploadFile);
+ if ($upload_file_size !== false) {
+ $upload_file_size -= $upload_position;
+ }
+ }
+
+ if ($upload_position === false || !isset($upload_file_size) || $upload_file_size === false || $upload_file_size < 0) {
+ throw new OssException('The size of `fileUpload` cannot be determined in ' . __FUNCTION__ . '().');
+ }
+ // 处理partSize
+ if (isset($options[self::OSS_PART_SIZE])) {
+ $options[self::OSS_PART_SIZE] = $this->computePartSize($options[self::OSS_PART_SIZE]);
+ } else {
+ $options[self::OSS_PART_SIZE] = self::OSS_MID_PART_SIZE;
+ }
+
+ $is_check_md5 = $this->isCheckMD5($options);
+ // 如果上传的文件小于partSize,则直接使用普通方式上传
+ if ($upload_file_size < $options[self::OSS_PART_SIZE] && !isset($options[self::OSS_UPLOAD_ID])) {
+ return $this->uploadFile($bucket, $object, $uploadFile, $options);
+ }
+
+ // 初始化multipart
+ if (isset($options[self::OSS_UPLOAD_ID])) {
+ $uploadId = $options[self::OSS_UPLOAD_ID];
+ } else {
+ // 初始化
+ $uploadId = $this->initiateMultipartUpload($bucket, $object, $options);
+ }
+
+ // 获取的分片
+ $pieces = $this->generateMultiuploadParts($upload_file_size, (integer)$options[self::OSS_PART_SIZE]);
+ $response_upload_part = array();
+ foreach ($pieces as $i => $piece) {
+ $from_pos = $upload_position + (integer)$piece[self::OSS_SEEK_TO];
+ $to_pos = (integer)$piece[self::OSS_LENGTH] + $from_pos - 1;
+ $up_options = array(
+ self::OSS_FILE_UPLOAD => $uploadFile,
+ self::OSS_PART_NUM => ($i + 1),
+ self::OSS_SEEK_TO => $from_pos,
+ self::OSS_LENGTH => $to_pos - $from_pos + 1,
+ self::OSS_CHECK_MD5 => $is_check_md5,
+ );
+ if ($is_check_md5) {
+ $content_md5 = OssUtil::getMd5SumForFile($uploadFile, $from_pos, $to_pos);
+ $up_options[self::OSS_CONTENT_MD5] = $content_md5;
+ }
+ $response_upload_part[] = $this->uploadPart($bucket, $object, $uploadId, $up_options);
+ }
+
+ $uploadParts = array();
+ foreach ($response_upload_part as $i => $etag) {
+ $uploadParts[] = array(
+ 'PartNumber' => ($i + 1),
+ 'ETag' => $etag,
+ );
+ }
+ return $this->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts);
+ }
+
+ /**
+ * 上传本地目录内的文件或者目录到指定bucket的指定prefix的object中
+ *
+ * @param string $bucket bucket名称
+ * @param string $prefix 需要上传到的object的key前缀,可以理解成bucket中的子目录,结尾不能是'/',接口中会补充'/'
+ * @param string $localDirectory 需要上传的本地目录
+ * @param string $exclude 需要排除的目录
+ * @param bool $recursive 是否递归的上传localDirectory下的子目录内容
+ * @param bool $checkMd5
+ * @return array 返回两个列表 array("succeededList" => array("object"), "failedList" => array("object"=>"errorMessage"))
+ * @throws OssException
+ */
+ public function uploadDir($bucket, $prefix, $localDirectory, $exclude = '.|..|.svn|.git', $recursive = false, $checkMd5 = true)
+ {
+ $retArray = array("succeededList" => array(), "failedList" => array());
+ if (empty($bucket)) throw new OssException("parameter error, bucket is empty");
+ if (!is_string($prefix)) throw new OssException("parameter error, prefix is not string");
+ if (empty($localDirectory)) throw new OssException("parameter error, localDirectory is empty");
+ $directory = $localDirectory;
+ $directory = OssUtil::encodePath($directory);
+ //判断是否目录
+ if (!is_dir($directory)) {
+ throw new OssException('parameter error: ' . $directory . ' is not a directory, please check it');
+ }
+ //read directory
+ $file_list_array = OssUtil::readDir($directory, $exclude, $recursive);
+ if (!$file_list_array) {
+ throw new OssException($directory . ' is empty...');
+ }
+ foreach ($file_list_array as $k => $item) {
+ if (is_dir($item['path'])) {
+ continue;
+ }
+ $options = array(
+ self::OSS_PART_SIZE => self::OSS_MIN_PART_SIZE,
+ self::OSS_CHECK_MD5 => $checkMd5,
+ );
+ $realObject = (!empty($prefix) ? $prefix . '/' : '') . $item['file'];
+
+ try {
+ $this->multiuploadFile($bucket, $realObject, $item['path'], $options);
+ $retArray["succeededList"][] = $realObject;
+ } catch (OssException $e) {
+ $retArray["failedList"][$realObject] = $e->getMessage();
+ }
+ }
+ return $retArray;
+ }
+
+ /**
+ * 支持生成get和put签名, 用户可以生成一个具有一定有效期的
+ * 签名过的url
+ *
+ * @param string $bucket
+ * @param string $object
+ * @param int $timeout
+ * @param string $method
+ * @param array $options Key-Value数组
+ * @return string
+ * @throws OssException
+ */
+ public function signUrl($bucket, $object, $timeout = 60, $method = self::OSS_HTTP_GET, $options = NULL)
+ {
+ $this->precheckCommon($bucket, $object, $options);
+ //method
+ if (self::OSS_HTTP_GET !== $method && self::OSS_HTTP_PUT !== $method) {
+ throw new OssException("method is invalid");
+ }
+ $options[self::OSS_BUCKET] = $bucket;
+ $options[self::OSS_OBJECT] = $object;
+ $options[self::OSS_METHOD] = $method;
+ if (!isset($options[self::OSS_CONTENT_TYPE])) {
+ $options[self::OSS_CONTENT_TYPE] = '';
+ }
+ $timeout = time() + $timeout;
+ $options[self::OSS_PREAUTH] = $timeout;
+ $options[self::OSS_DATE] = $timeout;
+ $this->setSignStsInUrl(true);
+ return $this->auth($options);
+ }
+
+ /**
+ * 检测options参数
+ *
+ * @param array $options
+ * @throws OssException
+ */
+ private function precheckOptions(&$options)
+ {
+ OssUtil::validateOptions($options);
+ if (!$options) {
+ $options = array();
+ }
+ }
+
+ /**
+ * 校验bucket参数
+ *
+ * @param string $bucket
+ * @param string $errMsg
+ * @throws OssException
+ */
+ private function precheckBucket($bucket, $errMsg = 'bucket is not allowed empty')
+ {
+ OssUtil::throwOssExceptionWithMessageIfEmpty($bucket, $errMsg);
+ }
+
+ /**
+ * 校验object参数
+ *
+ * @param string $object
+ * @throws OssException
+ */
+ private function precheckObject($object)
+ {
+ OssUtil::throwOssExceptionWithMessageIfEmpty($object, "object name is empty");
+ }
+
+ /**
+ * 校验bucket,options参数
+ *
+ * @param string $bucket
+ * @param string $object
+ * @param array $options
+ * @param bool $isCheckObject
+ */
+ private function precheckCommon($bucket, $object, &$options, $isCheckObject = true)
+ {
+ if ($isCheckObject) {
+ $this->precheckObject($object);
+ }
+ $this->precheckOptions($options);
+ $this->precheckBucket($bucket);
+ }
+
+ /**
+ * 参数校验
+ *
+ * @param array $options
+ * @param string $param
+ * @param string $funcName
+ * @throws OssException
+ */
+ private function precheckParam($options, $param, $funcName)
+ {
+ if (!isset($options[$param])) {
+ throw new OssException('The `' . $param . '` options is required in ' . $funcName . '().');
+ }
+ }
+
+ /**
+ * 检测md5
+ *
+ * @param array $options
+ * @return bool|null
+ */
+ private function isCheckMD5($options)
+ {
+ return $this->getValue($options, self::OSS_CHECK_MD5, false, true, true);
+ }
+
+ /**
+ * 获取value
+ *
+ * @param array $options
+ * @param string $key
+ * @param string $default
+ * @param bool $isCheckEmpty
+ * @param bool $isCheckBool
+ * @return bool|null
+ */
+ private function getValue($options, $key, $default = NULL, $isCheckEmpty = false, $isCheckBool = false)
+ {
+ $value = $default;
+ if (isset($options[$key])) {
+ if ($isCheckEmpty) {
+ if (!empty($options[$key])) {
+ $value = $options[$key];
+ }
+ } else {
+ $value = $options[$key];
+ }
+ unset($options[$key]);
+ }
+ if ($isCheckBool) {
+ if ($value !== true && $value !== false) {
+ $value = false;
+ }
+ }
+ return $value;
+ }
+
+ /**
+ * 获取mimetype类型
+ *
+ * @param string $object
+ * @return string
+ */
+ private function getMimeType($object, $file = null)
+ {
+ if (!is_null($file)) {
+ $type = MimeTypes::getMimetype($file);
+ if (!is_null($type)) {
+ return $type;
+ }
+ }
+
+ $type = MimeTypes::getMimetype($object);
+ if (!is_null($type)) {
+ return $type;
+ }
+
+ return self::DEFAULT_CONTENT_TYPE;
+ }
+
+ /**
+ * 验证并且执行请求,按照OSS Api协议,执行操作
+ *
+ * @param array $options
+ * @return ResponseCore
+ * @throws OssException
+ * @throws RequestCore_Exception
+ */
+ private function auth($options)
+ {
+ OssUtil::validateOptions($options);
+ //验证bucket,list_bucket时不需要验证
+ $this->authPrecheckBucket($options);
+ //验证object
+ $this->authPrecheckObject($options);
+ //Object名称的编码必须是utf8
+ $this->authPrecheckObjectEncoding($options);
+ //验证ACL
+ $this->authPrecheckAcl($options);
+ // 获得当次请求使用的协议头,是https还是http
+ $scheme = $this->useSSL ? 'https://' : 'http://';
+ // 获得当次请求使用的hostname,如果是公共域名或者专有域名,bucket拼在前面构成三级域名
+ $hostname = $this->generateHostname($options);
+ $string_to_sign = '';
+ $headers = $this->generateHeaders($options, $hostname);
+ $signable_query_string_params = $this->generateSignableQueryStringParam($options);
+ $signable_query_string = OssUtil::toQueryString($signable_query_string_params);
+ $resource_uri = $this->generateResourceUri($options);
+ //生成请求URL
+ $conjunction = '?';
+ $non_signable_resource = '';
+ if (isset($options[self::OSS_SUB_RESOURCE])) {
+ $conjunction = '&';
+ }
+ if ($signable_query_string !== '') {
+ $signable_query_string = $conjunction . $signable_query_string;
+ $conjunction = '&';
+ }
+ $query_string = $this->generateQueryString($options);
+ if ($query_string !== '') {
+ $non_signable_resource .= $conjunction . $query_string;
+ $conjunction = '&';
+ }
+ $this->requestUrl = $scheme . $hostname . $resource_uri . $signable_query_string . $non_signable_resource;
+
+ //创建请求
+ $request = new RequestCore($this->requestUrl);
+ $request->set_useragent($this->generateUserAgent());
+ // Streaming uploads
+ if (isset($options[self::OSS_FILE_UPLOAD])) {
+ if (is_resource($options[self::OSS_FILE_UPLOAD])) {
+ $length = null;
+
+ if (isset($options[self::OSS_CONTENT_LENGTH])) {
+ $length = $options[self::OSS_CONTENT_LENGTH];
+ } elseif (isset($options[self::OSS_SEEK_TO])) {
+ $stats = fstat($options[self::OSS_FILE_UPLOAD]);
+ if ($stats && $stats[self::OSS_SIZE] >= 0) {
+ $length = $stats[self::OSS_SIZE] - (integer)$options[self::OSS_SEEK_TO];
+ }
+ }
+ $request->set_read_stream($options[self::OSS_FILE_UPLOAD], $length);
+ } else {
+ $request->set_read_file($options[self::OSS_FILE_UPLOAD]);
+ $length = $request->read_stream_size;
+ if (isset($options[self::OSS_CONTENT_LENGTH])) {
+ $length = $options[self::OSS_CONTENT_LENGTH];
+ } elseif (isset($options[self::OSS_SEEK_TO]) && isset($length)) {
+ $length -= (integer)$options[self::OSS_SEEK_TO];
+ }
+ $request->set_read_stream_size($length);
+ }
+ }
+ if (isset($options[self::OSS_SEEK_TO])) {
+ $request->set_seek_position((integer)$options[self::OSS_SEEK_TO]);
+ }
+ if (isset($options[self::OSS_FILE_DOWNLOAD])) {
+ if (is_resource($options[self::OSS_FILE_DOWNLOAD])) {
+ $request->set_write_stream($options[self::OSS_FILE_DOWNLOAD]);
+ } else {
+ $request->set_write_file($options[self::OSS_FILE_DOWNLOAD]);
+ }
+ }
+
+ if (isset($options[self::OSS_METHOD])) {
+ $request->set_method($options[self::OSS_METHOD]);
+ $string_to_sign .= $options[self::OSS_METHOD] . "\n";
+ }
+
+ if (isset($options[self::OSS_CONTENT])) {
+ $request->set_body($options[self::OSS_CONTENT]);
+ if ($headers[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded') {
+ $headers[self::OSS_CONTENT_TYPE] = 'application/octet-stream';
+ }
+
+ $headers[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]);
+ $headers[self::OSS_CONTENT_MD5] = base64_encode(md5($options[self::OSS_CONTENT], true));
+ }
+
+ uksort($headers, 'strnatcasecmp');
+ foreach ($headers as $header_key => $header_value) {
+ $header_value = str_replace(array("\r", "\n"), '', $header_value);
+ if ($header_value !== '') {
+ $request->add_header($header_key, $header_value);
+ }
+ if (
+ strtolower($header_key) === 'content-md5' ||
+ strtolower($header_key) === 'content-type' ||
+ strtolower($header_key) === 'date' ||
+ (isset($options['self::OSS_PREAUTH']) && (integer)$options['self::OSS_PREAUTH'] > 0)
+ ) {
+ $string_to_sign .= $header_value . "\n";
+ } elseif (substr(strtolower($header_key), 0, 6) === self::OSS_DEFAULT_PREFIX) {
+ $string_to_sign .= strtolower($header_key) . ':' . $header_value . "\n";
+ }
+ }
+ // 生成 signable_resource
+ $signable_resource = $this->generateSignableResource($options);
+ $string_to_sign .= rawurldecode($signable_resource) . urldecode($signable_query_string);
+ $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true));
+ $request->add_header('Authorization', 'OSS ' . $this->accessKeyId . ':' . $signature);
+
+ if (isset($options[self::OSS_PREAUTH]) && (integer)$options[self::OSS_PREAUTH] > 0) {
+ $signed_url = $this->requestUrl . $conjunction . self::OSS_URL_ACCESS_KEY_ID . '=' . rawurlencode($this->accessKeyId) . '&' . self::OSS_URL_EXPIRES . '=' . $options[self::OSS_PREAUTH] . '&' . self::OSS_URL_SIGNATURE . '=' . rawurlencode($signature);
+ return $signed_url;
+ } elseif (isset($options[self::OSS_PREAUTH])) {
+ return $this->requestUrl;
+ }
+
+ if ($this->timeout !== 0) {
+ $request->timeout = $this->timeout;
+ }
+ if ($this->connectTimeout !== 0) {
+ $request->connect_timeout = $this->connectTimeout;
+ }
+
+ try {
+ $request->send_request();
+ } catch (RequestCore_Exception $e) {
+ throw(new OssException('RequestCoreException: ' . $e->getMessage()));
+ }
+ $response_header = $request->get_response_header();
+ $response_header['oss-request-url'] = $this->requestUrl;
+ $response_header['oss-redirects'] = $this->redirects;
+ $response_header['oss-stringtosign'] = $string_to_sign;
+ $response_header['oss-requestheaders'] = $request->request_headers;
+
+ $data = new ResponseCore($response_header, $request->get_response_body(), $request->get_response_code());
+ //retry if OSS Internal Error
+ if ((integer)$request->get_response_code() === 500) {
+ if ($this->redirects <= $this->maxRetries) {
+ //设置休眠
+ $delay = (integer)(pow(4, $this->redirects) * 100000);
+ usleep($delay);
+ $this->redirects++;
+ $data = $this->auth($options);
+ }
+ }
+
+ $this->redirects = 0;
+ return $data;
+ }
+
+ /**
+ * 设置最大尝试次数
+ *
+ * @param int $maxRetries
+ * @return void
+ */
+ public function setMaxTries($maxRetries = 3)
+ {
+ $this->maxRetries = $maxRetries;
+ }
+
+ /**
+ * 获取最大尝试次数
+ *
+ * @return int
+ */
+ public function getMaxRetries()
+ {
+ return $this->maxRetries;
+ }
+
+ /**
+ * 打开sts enable标志,使用户构造函数中传入的$sts生效
+ *
+ * @param boolean $enable
+ */
+ public function setSignStsInUrl($enable)
+ {
+ $this->enableStsInUrl = $enable;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isUseSSL()
+ {
+ return $this->useSSL;
+ }
+
+ /**
+ * @param boolean $useSSL
+ */
+ public function setUseSSL($useSSL)
+ {
+ $this->useSSL = $useSSL;
+ }
+
+ /**
+ * 检查bucket名称格式是否正确,如果非法抛出异常
+ *
+ * @param $options
+ * @throws OssException
+ */
+ private function authPrecheckBucket($options)
+ {
+ if (!(('/' == $options[self::OSS_OBJECT]) && ('' == $options[self::OSS_BUCKET]) && ('GET' == $options[self::OSS_METHOD])) && !OssUtil::validateBucket($options[self::OSS_BUCKET])) {
+ throw new OssException('"' . $options[self::OSS_BUCKET] . '"' . 'bucket name is invalid');
+ }
+ }
+
+ /**
+ *
+ * 检查object名称格式是否正确,如果非法抛出异常
+ *
+ * @param $options
+ * @throws OssException
+ */
+ private function authPrecheckObject($options)
+ {
+ if (isset($options[self::OSS_OBJECT]) && $options[self::OSS_OBJECT] === '/') {
+ return;
+ }
+
+ if (isset($options[self::OSS_OBJECT]) && !OssUtil::validateObject($options[self::OSS_OBJECT])) {
+ throw new OssException('"' . $options[self::OSS_OBJECT] . '"' . ' object name is invalid');
+ }
+ }
+
+ /**
+ * 检查object的编码,如果是gbk或者gb2312则尝试将其转化为utf8编码
+ *
+ * @param mixed $options 参数
+ */
+ private function authPrecheckObjectEncoding(&$options)
+ {
+ $tmp_object = $options[self::OSS_OBJECT];
+ try {
+ if (OssUtil::isGb2312($options[self::OSS_OBJECT])) {
+ $options[self::OSS_OBJECT] = iconv('GB2312', "UTF-8//IGNORE", $options[self::OSS_OBJECT]);
+ } elseif (OssUtil::checkChar($options[self::OSS_OBJECT], true)) {
+ $options[self::OSS_OBJECT] = iconv('GBK', "UTF-8//IGNORE", $options[self::OSS_OBJECT]);
+ }
+ } catch (\Exception $e) {
+ try {
+ $tmp_object = iconv(mb_detect_encoding($tmp_object), "UTF-8", $tmp_object);
+ } catch (\Exception $e) {
+ }
+ }
+ $options[self::OSS_OBJECT] = $tmp_object;
+ }
+
+ /**
+ * 检查ACL是否是预定义中三种之一,如果不是抛出异常
+ *
+ * @param $options
+ * @throws OssException
+ */
+ private function authPrecheckAcl($options)
+ {
+ if (isset($options[self::OSS_HEADERS][self::OSS_ACL]) && !empty($options[self::OSS_HEADERS][self::OSS_ACL])) {
+ if (!in_array(strtolower($options[self::OSS_HEADERS][self::OSS_ACL]), self::$OSS_ACL_TYPES)) {
+ throw new OssException($options[self::OSS_HEADERS][self::OSS_ACL] . ':' . 'acl is invalid(private,public-read,public-read-write)');
+ }
+ }
+ }
+
+ /**
+ * 获得档次请求使用的域名
+ * bucket在前的三级域名,或者二级域名,如果是cname或者ip的话,则是二级域名
+ *
+ * @param $options
+ * @return string 剥掉协议头的域名
+ */
+ private function generateHostname($options)
+ {
+ if ($this->hostType === self::OSS_HOST_TYPE_IP) {
+ $hostname = $this->hostname;
+ } elseif ($this->hostType === self::OSS_HOST_TYPE_CNAME) {
+ $hostname = $this->hostname;
+ } else {
+ // 专有域或者官网endpoint
+ $hostname = ($options[self::OSS_BUCKET] == '') ? $this->hostname : ($options[self::OSS_BUCKET] . '.') . $this->hostname;
+ }
+ return $hostname;
+ }
+
+ /**
+ * 获得当次请求的资源定位字段
+ *
+ * @param $options
+ * @return string 资源定位字段
+ */
+ private function generateResourceUri($options)
+ {
+ $resource_uri = "";
+
+ // resource_uri + bucket
+ if (isset($options[self::OSS_BUCKET]) && '' !== $options[self::OSS_BUCKET]) {
+ if ($this->hostType === self::OSS_HOST_TYPE_IP) {
+ $resource_uri = '/' . $options[self::OSS_BUCKET];
+ }
+ }
+
+ // resource_uri + object
+ if (isset($options[self::OSS_OBJECT]) && '/' !== $options[self::OSS_OBJECT]) {
+ $resource_uri .= '/' . str_replace(array('%2F', '%25'), array('/', '%'), rawurlencode($options[self::OSS_OBJECT]));
+ }
+
+ // resource_uri + sub_resource
+ $conjunction = '?';
+ if (isset($options[self::OSS_SUB_RESOURCE])) {
+ $resource_uri .= $conjunction . $options[self::OSS_SUB_RESOURCE];
+ }
+ return $resource_uri;
+ }
+
+ /**
+ * 生成signalbe_query_string_param, array类型
+ *
+ * @param array $options
+ * @return array
+ */
+ private function generateSignableQueryStringParam($options)
+ {
+ $signableQueryStringParams = array();
+ $signableList = array(
+ self::OSS_PART_NUM,
+ 'response-content-type',
+ 'response-content-language',
+ 'response-cache-control',
+ 'response-content-encoding',
+ 'response-expires',
+ 'response-content-disposition',
+ self::OSS_UPLOAD_ID,
+ self::OSS_CNAME_COMP,
+ self::OSS_POSITION
+ );
+
+ foreach ($signableList as $item) {
+ if (isset($options[$item])) {
+ $signableQueryStringParams[$item] = $options[$item];
+ }
+ }
+
+ if ($this->enableStsInUrl && (!is_null($this->securityToken))) {
+ $signableQueryStringParams["security-token"] = $this->securityToken;
+ }
+
+ return $signableQueryStringParams;
+ }
+
+ /**
+ * 生成用于签名resource段
+ *
+ * @param mixed $options
+ * @return string
+ */
+ private function generateSignableResource($options)
+ {
+ $signableResource = "";
+ $signableResource .= '/';
+ if (isset($options[self::OSS_BUCKET]) && '' !== $options[self::OSS_BUCKET]) {
+ $signableResource .= $options[self::OSS_BUCKET];
+ // 如果操作没有Object操作的话,这里最后是否有斜线有个trick,ip的域名下,不需要加'/', 否则需要加'/'
+ if ($options[self::OSS_OBJECT] == '/') {
+ if ($this->hostType !== self::OSS_HOST_TYPE_IP) {
+ $signableResource .= "/";
+ }
+ }
+ }
+ //signable_resource + object
+ if (isset($options[self::OSS_OBJECT]) && '/' !== $options[self::OSS_OBJECT]) {
+ $signableResource .= '/' . str_replace(array('%2F', '%25'), array('/', '%'), rawurlencode($options[self::OSS_OBJECT]));
+ }
+ if (isset($options[self::OSS_SUB_RESOURCE])) {
+ $signableResource .= '?' . $options[self::OSS_SUB_RESOURCE];
+ }
+ return $signableResource;
+ }
+
+ /**
+ * 生成query_string
+ *
+ * @param mixed $options
+ * @return string
+ */
+ private function generateQueryString($options)
+ {
+ //请求参数
+ $queryStringParams = array();
+ if (isset($options[self::OSS_QUERY_STRING])) {
+ $queryStringParams = array_merge($queryStringParams, $options[self::OSS_QUERY_STRING]);
+ }
+ return OssUtil::toQueryString($queryStringParams);
+ }
+
+ /**
+ * 初始化headers
+ *
+ * @param mixed $options
+ * @param string $hostname hostname
+ * @return array
+ */
+ private function generateHeaders($options, $hostname)
+ {
+ $headers = array(
+ self::OSS_CONTENT_MD5 => '',
+ self::OSS_CONTENT_TYPE => isset($options[self::OSS_CONTENT_TYPE]) ? $options[self::OSS_CONTENT_TYPE] : self::DEFAULT_CONTENT_TYPE,
+ self::OSS_DATE => isset($options[self::OSS_DATE]) ? $options[self::OSS_DATE] : gmdate('D, d M Y H:i:s \G\M\T'),
+ self::OSS_HOST => $hostname,
+ );
+ if (isset($options[self::OSS_CONTENT_MD5])) {
+ $headers[self::OSS_CONTENT_MD5] = $options[self::OSS_CONTENT_MD5];
+ }
+ //添加stsSecurityToken
+ if ((!is_null($this->securityToken)) && (!$this->enableStsInUrl)) {
+ $headers[self::OSS_SECURITY_TOKEN] = $this->securityToken;
+ }
+ //合并HTTP headers
+ if (isset($options[self::OSS_HEADERS])) {
+ $headers = array_merge($headers, $options[self::OSS_HEADERS]);
+ }
+ return $headers;
+ }
+
+ /**
+ * 生成请求用的UserAgent
+ *
+ * @return string
+ */
+ private function generateUserAgent()
+ {
+ return self::OSS_NAME . "/" . self::OSS_VERSION . " (" . php_uname('s') . "/" . php_uname('r') . "/" . php_uname('m') . ";" . PHP_VERSION . ")";
+ }
+
+ /**
+ * 检查endpoint的种类
+ * 如有有协议头,剥去协议头
+ * 并且根据参数 is_cname 和endpoint本身,判定域名类型,是ip,cname,还是专有域或者官网域名
+ *
+ * @param string $endpoint
+ * @param boolean $isCName
+ * @return string 剥掉协议头的域名
+ */
+ private function checkEndpoint($endpoint, $isCName)
+ {
+ $ret_endpoint = null;
+ if (strpos($endpoint, 'http://') === 0) {
+ $ret_endpoint = substr($endpoint, strlen('http://'));
+ } elseif (strpos($endpoint, 'https://') === 0) {
+ $ret_endpoint = substr($endpoint, strlen('https://'));
+ $this->useSSL = true;
+ } else {
+ $ret_endpoint = $endpoint;
+ }
+
+ if ($isCName) {
+ $this->hostType = self::OSS_HOST_TYPE_CNAME;
+ } elseif (OssUtil::isIPFormat($ret_endpoint)) {
+ $this->hostType = self::OSS_HOST_TYPE_IP;
+ } else {
+ $this->hostType = self::OSS_HOST_TYPE_NORMAL;
+ }
+ return $ret_endpoint;
+ }
+
+ /**
+ * 用来检查sdk所以来的扩展是否打开
+ *
+ * @throws OssException
+ */
+ public static function checkEnv()
+ {
+ if (function_exists('get_loaded_extensions')) {
+ //检测curl扩展
+ $enabled_extension = array("curl");
+ $extensions = get_loaded_extensions();
+ if ($extensions) {
+ foreach ($enabled_extension as $item) {
+ if (!in_array($item, $extensions)) {
+ throw new OssException("Extension {" . $item . "} is not installed or not enabled, please check your php env.");
+ }
+ }
+ } else {
+ throw new OssException("function get_loaded_extensions not found.");
+ }
+ } else {
+ throw new OssException('Function get_loaded_extensions has been disabled, please check php config.');
+ }
+ }
+
+ /**
+ * 设置http库的请求超时时间,单位秒
+ *
+ * @param int $timeout
+ */
+ public function setTimeout($timeout)
+ {
+ $this->timeout = $timeout;
+ }
+
+ /**
+ * 设置http库的连接超时时间,单位秒
+ *
+ * @param int $connectTimeout
+ */
+ public function setConnectTimeout($connectTimeout)
+ {
+ $this->connectTimeout = $connectTimeout;
+ }
+
+ // 生命周期相关常量
+ const OSS_LIFECYCLE_EXPIRATION = "Expiration";
+ const OSS_LIFECYCLE_TIMING_DAYS = "Days";
+ const OSS_LIFECYCLE_TIMING_DATE = "Date";
+ //OSS 内部常量
+ const OSS_BUCKET = 'bucket';
+ const OSS_OBJECT = 'object';
+ const OSS_HEADERS = OssUtil::OSS_HEADERS;
+ const OSS_METHOD = 'method';
+ const OSS_QUERY = 'query';
+ const OSS_BASENAME = 'basename';
+ const OSS_MAX_KEYS = 'max-keys';
+ const OSS_UPLOAD_ID = 'uploadId';
+ const OSS_PART_NUM = 'partNumber';
+ const OSS_CNAME_COMP = 'comp';
+ const OSS_POSITION = 'position';
+ const OSS_MAX_KEYS_VALUE = 100;
+ const OSS_MAX_OBJECT_GROUP_VALUE = OssUtil::OSS_MAX_OBJECT_GROUP_VALUE;
+ const OSS_MAX_PART_SIZE = OssUtil::OSS_MAX_PART_SIZE;
+ const OSS_MID_PART_SIZE = OssUtil::OSS_MID_PART_SIZE;
+ const OSS_MIN_PART_SIZE = OssUtil::OSS_MIN_PART_SIZE;
+ const OSS_FILE_SLICE_SIZE = 8192;
+ const OSS_PREFIX = 'prefix';
+ const OSS_DELIMITER = 'delimiter';
+ const OSS_MARKER = 'marker';
+ const OSS_CONTENT_MD5 = 'Content-Md5';
+ const OSS_SELF_CONTENT_MD5 = 'x-oss-meta-md5';
+ const OSS_CONTENT_TYPE = 'Content-Type';
+ const OSS_CONTENT_LENGTH = 'Content-Length';
+ const OSS_IF_MODIFIED_SINCE = 'If-Modified-Since';
+ const OSS_IF_UNMODIFIED_SINCE = 'If-Unmodified-Since';
+ const OSS_IF_MATCH = 'If-Match';
+ const OSS_IF_NONE_MATCH = 'If-None-Match';
+ const OSS_CACHE_CONTROL = 'Cache-Control';
+ const OSS_EXPIRES = 'Expires';
+ const OSS_PREAUTH = 'preauth';
+ const OSS_CONTENT_COING = 'Content-Coding';
+ const OSS_CONTENT_DISPOSTION = 'Content-Disposition';
+ const OSS_RANGE = 'range';
+ const OSS_ETAG = 'etag';
+ const OSS_LAST_MODIFIED = 'lastmodified';
+ const OS_CONTENT_RANGE = 'Content-Range';
+ const OSS_CONTENT = OssUtil::OSS_CONTENT;
+ const OSS_BODY = 'body';
+ const OSS_LENGTH = OssUtil::OSS_LENGTH;
+ const OSS_HOST = 'Host';
+ const OSS_DATE = 'Date';
+ const OSS_AUTHORIZATION = 'Authorization';
+ const OSS_FILE_DOWNLOAD = 'fileDownload';
+ const OSS_FILE_UPLOAD = 'fileUpload';
+ const OSS_PART_SIZE = 'partSize';
+ const OSS_SEEK_TO = 'seekTo';
+ const OSS_SIZE = 'size';
+ const OSS_QUERY_STRING = 'query_string';
+ const OSS_SUB_RESOURCE = 'sub_resource';
+ const OSS_DEFAULT_PREFIX = 'x-oss-';
+ const OSS_CHECK_MD5 = 'checkmd5';
+ const DEFAULT_CONTENT_TYPE = 'application/octet-stream';
+
+ //私有URL变量
+ const OSS_URL_ACCESS_KEY_ID = 'OSSAccessKeyId';
+ const OSS_URL_EXPIRES = 'Expires';
+ const OSS_URL_SIGNATURE = 'Signature';
+ //HTTP方法
+ const OSS_HTTP_GET = 'GET';
+ const OSS_HTTP_PUT = 'PUT';
+ const OSS_HTTP_HEAD = 'HEAD';
+ const OSS_HTTP_POST = 'POST';
+ const OSS_HTTP_DELETE = 'DELETE';
+ const OSS_HTTP_OPTIONS = 'OPTIONS';
+ //其他常量
+ const OSS_ACL = 'x-oss-acl';
+ const OSS_OBJECT_ACL = 'x-oss-object-acl';
+ const OSS_OBJECT_GROUP = 'x-oss-file-group';
+ const OSS_MULTI_PART = 'uploads';
+ const OSS_MULTI_DELETE = 'delete';
+ const OSS_OBJECT_COPY_SOURCE = 'x-oss-copy-source';
+ const OSS_OBJECT_COPY_SOURCE_RANGE = "x-oss-copy-source-range";
+ //支持STS SecurityToken
+ const OSS_SECURITY_TOKEN = "x-oss-security-token";
+ const OSS_ACL_TYPE_PRIVATE = 'private';
+ const OSS_ACL_TYPE_PUBLIC_READ = 'public-read';
+ const OSS_ACL_TYPE_PUBLIC_READ_WRITE = 'public-read-write';
+ const OSS_ENCODING_TYPE = "encoding-type";
+ const OSS_ENCODING_TYPE_URL = "url";
+
+ // 域名类型
+ const OSS_HOST_TYPE_NORMAL = "normal";//http://bucket.oss-cn-hangzhou.aliyuncs.com/object
+ const OSS_HOST_TYPE_IP = "ip"; //http://1.1.1.1/bucket/object
+ const OSS_HOST_TYPE_SPECIAL = 'special'; //http://bucket.guizhou.gov/object
+ const OSS_HOST_TYPE_CNAME = "cname"; //http://mydomain.com/object
+ //OSS ACL数组
+ static $OSS_ACL_TYPES = array(
+ self::OSS_ACL_TYPE_PRIVATE,
+ self::OSS_ACL_TYPE_PUBLIC_READ,
+ self::OSS_ACL_TYPE_PUBLIC_READ_WRITE
+ );
+ // OssClient版本信息
+ const OSS_NAME = "aliyun-sdk-php";
+ const OSS_VERSION = "2.0.7";
+ const OSS_BUILD = "20160617";
+ const OSS_AUTHOR = "";
+ const OSS_OPTIONS_ORIGIN = 'Origin';
+ const OSS_OPTIONS_REQUEST_METHOD = 'Access-Control-Request-Method';
+ const OSS_OPTIONS_REQUEST_HEADERS = 'Access-Control-Request-Headers';
+
+ //是否使用ssl
+ private $useSSL = false;
+ private $maxRetries = 3;
+ private $redirects = 0;
+
+ // 用户提供的域名类型,有四种 OSS_HOST_TYPE_NORMAL, OSS_HOST_TYPE_IP, OSS_HOST_TYPE_SPECIAL, OSS_HOST_TYPE_CNAME
+ private $hostType = self::OSS_HOST_TYPE_NORMAL;
+ private $requestUrl;
+ private $accessKeyId;
+ private $accessKeySecret;
+ private $hostname;
+ private $securityToken;
+ private $enableStsInUrl = false;
+ private $timeout = 0;
+ private $connectTimeout = 0;
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/AclResult.php b/framework/library/alioss/src/OSS/Result/AclResult.php
new file mode 100644
index 0000000..e12e3e9
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/AclResult.php
@@ -0,0 +1,33 @@
+rawResponse->body;
+ if (empty($content)) {
+ throw new OssException("body is null");
+ }
+ $xml = simplexml_load_string($content);
+ if (isset($xml->AccessControlList->Grant)) {
+ return strval($xml->AccessControlList->Grant);
+ } else {
+ throw new OssException("xml format exception");
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/AppendResult.php b/framework/library/alioss/src/OSS/Result/AppendResult.php
new file mode 100644
index 0000000..433c03e
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/AppendResult.php
@@ -0,0 +1,27 @@
+rawResponse->header;
+ if (isset($header["x-oss-next-append-position"])) {
+ return intval($header["x-oss-next-append-position"]);
+ }
+ throw new OssException("cannot get next-append-position");
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/BodyResult.php b/framework/library/alioss/src/OSS/Result/BodyResult.php
new file mode 100644
index 0000000..44ba15e
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/BodyResult.php
@@ -0,0 +1,19 @@
+rawResponse->body) ? "" : $this->rawResponse->body;
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/ExistResult.php b/framework/library/alioss/src/OSS/Result/ExistResult.php
new file mode 100644
index 0000000..f7aa287
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/ExistResult.php
@@ -0,0 +1,35 @@
+rawResponse->status) === 200 ? true : false;
+ }
+
+ /**
+ * 根据返回http状态码判断,[200-299]即认为是OK, 判断是否存在的接口,404也认为是一种
+ * 有效响应
+ *
+ * @return bool
+ */
+ protected function isResponseOk()
+ {
+ $status = $this->rawResponse->status;
+ if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) {
+ return true;
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/GetCnameResult.php b/framework/library/alioss/src/OSS/Result/GetCnameResult.php
new file mode 100644
index 0000000..1f42e23
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/GetCnameResult.php
@@ -0,0 +1,34 @@
+rawResponse->body;
+ $config = new CnameConfig();
+ $config->parseFromXml($content);
+ return $config;
+ }
+
+ /**
+ * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种
+ * 有效响应
+ *
+ * @return bool
+ */
+ protected function isResponseOk()
+ {
+ $status = $this->rawResponse->status;
+ if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) {
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/GetCorsResult.php b/framework/library/alioss/src/OSS/Result/GetCorsResult.php
new file mode 100644
index 0000000..a51afe2
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/GetCorsResult.php
@@ -0,0 +1,35 @@
+rawResponse->body;
+ $config = new CorsConfig();
+ $config->parseFromXml($content);
+ return $config;
+ }
+
+ /**
+ * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种
+ * 有效响应
+ *
+ * @return bool
+ */
+ protected function isResponseOk()
+ {
+ $status = $this->rawResponse->status;
+ if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) {
+ return true;
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/GetLifecycleResult.php b/framework/library/alioss/src/OSS/Result/GetLifecycleResult.php
new file mode 100644
index 0000000..6b440c3
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/GetLifecycleResult.php
@@ -0,0 +1,41 @@
+rawResponse->body;
+ $config = new LifecycleConfig();
+ $config->parseFromXml($content);
+ return $config;
+ }
+
+ /**
+ * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种
+ * 有效响应
+ *
+ * @return bool
+ */
+ protected function isResponseOk()
+ {
+ $status = $this->rawResponse->status;
+ if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) {
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/GetLoggingResult.php b/framework/library/alioss/src/OSS/Result/GetLoggingResult.php
new file mode 100644
index 0000000..72fc3ae
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/GetLoggingResult.php
@@ -0,0 +1,41 @@
+rawResponse->body;
+ $config = new LoggingConfig();
+ $config->parseFromXml($content);
+ return $config;
+ }
+
+ /**
+ * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种
+ * 有效响应
+ *
+ * @return bool
+ */
+ protected function isResponseOk()
+ {
+ $status = $this->rawResponse->status;
+ if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) {
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/GetRefererResult.php b/framework/library/alioss/src/OSS/Result/GetRefererResult.php
new file mode 100644
index 0000000..aee50d3
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/GetRefererResult.php
@@ -0,0 +1,41 @@
+rawResponse->body;
+ $config = new RefererConfig();
+ $config->parseFromXml($content);
+ return $config;
+ }
+
+ /**
+ * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种
+ * 有效响应
+ *
+ * @return bool
+ */
+ protected function isResponseOk()
+ {
+ $status = $this->rawResponse->status;
+ if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) {
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/GetWebsiteResult.php b/framework/library/alioss/src/OSS/Result/GetWebsiteResult.php
new file mode 100644
index 0000000..3099172
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/GetWebsiteResult.php
@@ -0,0 +1,40 @@
+rawResponse->body;
+ $config = new WebsiteConfig();
+ $config->parseFromXml($content);
+ return $config;
+ }
+
+ /**
+ * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种
+ * 有效响应
+ *
+ * @return bool
+ */
+ protected function isResponseOk()
+ {
+ $status = $this->rawResponse->status;
+ if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) {
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/HeaderResult.php b/framework/library/alioss/src/OSS/Result/HeaderResult.php
new file mode 100644
index 0000000..c9aae56
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/HeaderResult.php
@@ -0,0 +1,23 @@
+rawResponse->header) ? array() : $this->rawResponse->header;
+ }
+
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/InitiateMultipartUploadResult.php b/framework/library/alioss/src/OSS/Result/InitiateMultipartUploadResult.php
new file mode 100644
index 0000000..af985f2
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/InitiateMultipartUploadResult.php
@@ -0,0 +1,29 @@
+rawResponse->body;
+ $xml = simplexml_load_string($content);
+ if (isset($xml->UploadId)) {
+ return strval($xml->UploadId);
+ }
+ throw new OssException("cannot get UploadId");
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/ListBucketsResult.php b/framework/library/alioss/src/OSS/Result/ListBucketsResult.php
new file mode 100644
index 0000000..a58fb2d
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/ListBucketsResult.php
@@ -0,0 +1,33 @@
+rawResponse->body;
+ $xml = new \SimpleXMLElement($content);
+ if (isset($xml->Buckets) && isset($xml->Buckets->Bucket)) {
+ foreach ($xml->Buckets->Bucket as $bucket) {
+ $bucketInfo = new BucketInfo(strval($bucket->Location),
+ strval($bucket->Name),
+ strval($bucket->CreationDate));
+ $bucketList[] = $bucketInfo;
+ }
+ }
+ return new BucketListInfo($bucketList);
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/ListMultipartUploadResult.php b/framework/library/alioss/src/OSS/Result/ListMultipartUploadResult.php
new file mode 100644
index 0000000..bcb20bf
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/ListMultipartUploadResult.php
@@ -0,0 +1,55 @@
+rawResponse->body;
+ $xml = simplexml_load_string($content);
+
+ $encodingType = isset($xml->EncodingType) ? strval($xml->EncodingType) : "";
+ $bucket = isset($xml->Bucket) ? strval($xml->Bucket) : "";
+ $keyMarker = isset($xml->KeyMarker) ? strval($xml->KeyMarker) : "";
+ $keyMarker = OssUtil::decodeKey($keyMarker, $encodingType);
+ $uploadIdMarker = isset($xml->UploadIdMarker) ? strval($xml->UploadIdMarker) : "";
+ $nextKeyMarker = isset($xml->NextKeyMarker) ? strval($xml->NextKeyMarker) : "";
+ $nextKeyMarker = OssUtil::decodeKey($nextKeyMarker, $encodingType);
+ $nextUploadIdMarker = isset($xml->NextUploadIdMarker) ? strval($xml->NextUploadIdMarker) : "";
+ $delimiter = isset($xml->Delimiter) ? strval($xml->Delimiter) : "";
+ $delimiter = OssUtil::decodeKey($delimiter, $encodingType);
+ $prefix = isset($xml->Prefix) ? strval($xml->Prefix) : "";
+ $prefix = OssUtil::decodeKey($prefix, $encodingType);
+ $maxUploads = isset($xml->MaxUploads) ? intval($xml->MaxUploads) : 0;
+ $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : "";
+ $listUpload = array();
+
+ if (isset($xml->Upload)) {
+ foreach ($xml->Upload as $upload) {
+ $key = isset($upload->Key) ? strval($upload->Key) : "";
+ $key = OssUtil::decodeKey($key, $encodingType);
+ $uploadId = isset($upload->UploadId) ? strval($upload->UploadId) : "";
+ $initiated = isset($upload->Initiated) ? strval($upload->Initiated) : "";
+ $listUpload[] = new UploadInfo($key, $uploadId, $initiated);
+ }
+ }
+ return new ListMultipartUploadInfo($bucket, $keyMarker, $uploadIdMarker,
+ $nextKeyMarker, $nextUploadIdMarker,
+ $delimiter, $prefix, $maxUploads, $isTruncated, $listUpload);
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/ListObjectsResult.php b/framework/library/alioss/src/OSS/Result/ListObjectsResult.php
new file mode 100644
index 0000000..fcf493d
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/ListObjectsResult.php
@@ -0,0 +1,71 @@
+rawResponse->body);
+ $encodingType = isset($xml->EncodingType) ? strval($xml->EncodingType) : "";
+ $objectList = $this->parseObjectList($xml, $encodingType);
+ $prefixList = $this->parsePrefixList($xml, $encodingType);
+ $bucketName = isset($xml->Name) ? strval($xml->Name) : "";
+ $prefix = isset($xml->Prefix) ? strval($xml->Prefix) : "";
+ $prefix = OssUtil::decodeKey($prefix, $encodingType);
+ $marker = isset($xml->Marker) ? strval($xml->Marker) : "";
+ $marker = OssUtil::decodeKey($marker, $encodingType);
+ $maxKeys = isset($xml->MaxKeys) ? intval($xml->MaxKeys) : 0;
+ $delimiter = isset($xml->Delimiter) ? strval($xml->Delimiter) : "";
+ $delimiter = OssUtil::decodeKey($delimiter, $encodingType);
+ $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : "";
+ $nextMarker = isset($xml->NextMarker) ? strval($xml->NextMarker) : "";
+ $nextMarker = OssUtil::decodeKey($nextMarker, $encodingType);
+ return new ObjectListInfo($bucketName, $prefix, $marker, $nextMarker, $maxKeys, $delimiter, $isTruncated, $objectList, $prefixList);
+ }
+
+ private function parseObjectList($xml, $encodingType)
+ {
+ $retList = array();
+ if (isset($xml->Contents)) {
+ foreach ($xml->Contents as $content) {
+ $key = isset($content->Key) ? strval($content->Key) : "";
+ $key = OssUtil::decodeKey($key, $encodingType);
+ $lastModified = isset($content->LastModified) ? strval($content->LastModified) : "";
+ $eTag = isset($content->ETag) ? strval($content->ETag) : "";
+ $type = isset($content->Type) ? strval($content->Type) : "";
+ $size = isset($content->Size) ? intval($content->Size) : 0;
+ $storageClass = isset($content->StorageClass) ? strval($content->StorageClass) : "";
+ $retList[] = new ObjectInfo($key, $lastModified, $eTag, $type, $size, $storageClass);
+ }
+ }
+ return $retList;
+ }
+
+ private function parsePrefixList($xml, $encodingType)
+ {
+ $retList = array();
+ if (isset($xml->CommonPrefixes)) {
+ foreach ($xml->CommonPrefixes as $commonPrefix) {
+ $prefix = isset($commonPrefix->Prefix) ? strval($commonPrefix->Prefix) : "";
+ $prefix = OssUtil::decodeKey($prefix, $encodingType);
+ $retList[] = new PrefixInfo($prefix);
+ }
+ }
+ return $retList;
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/ListPartsResult.php b/framework/library/alioss/src/OSS/Result/ListPartsResult.php
new file mode 100644
index 0000000..fd8a1b8
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/ListPartsResult.php
@@ -0,0 +1,42 @@
+rawResponse->body;
+ $xml = simplexml_load_string($content);
+ $bucket = isset($xml->Bucket) ? strval($xml->Bucket) : "";
+ $key = isset($xml->Key) ? strval($xml->Key) : "";
+ $uploadId = isset($xml->UploadId) ? strval($xml->UploadId) : "";
+ $nextPartNumberMarker = isset($xml->NextPartNumberMarker) ? intval($xml->NextPartNumberMarker) : "";
+ $maxParts = isset($xml->MaxParts) ? intval($xml->MaxParts) : "";
+ $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : "";
+ $partList = array();
+ if (isset($xml->Part)) {
+ foreach ($xml->Part as $part) {
+ $partNumber = isset($part->PartNumber) ? intval($part->PartNumber) : "";
+ $lastModified = isset($part->LastModified) ? strval($part->LastModified) : "";
+ $eTag = isset($part->ETag) ? strval($part->ETag) : "";
+ $size = isset($part->Size) ? intval($part->Size) : "";
+ $partList[] = new PartInfo($partNumber, $lastModified, $eTag, $size);
+ }
+ }
+ return new ListPartsInfo($bucket, $key, $uploadId, $nextPartNumberMarker, $maxParts, $isTruncated, $partList);
+ }
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/PutSetDeleteResult.php b/framework/library/alioss/src/OSS/Result/PutSetDeleteResult.php
new file mode 100644
index 0000000..c629949
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/PutSetDeleteResult.php
@@ -0,0 +1,19 @@
+rawResponse = $response;
+ $this->parseResponse();
+ }
+
+ /**
+ * 获取requestId
+ *
+ * @return string
+ */
+ public function getRequestId()
+ {
+ if (isset($this->rawResponse) &&
+ isset($this->rawResponse->header) &&
+ isset($this->rawResponse->header['x-oss-request-id'])
+ ) {
+ return $this->rawResponse->header['x-oss-request-id'];
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * 得到返回数据,不同的请求返回数据格式不同
+ *
+ * $return mixed
+ */
+ public function getData()
+ {
+ return $this->parsedData;
+ }
+
+ /**
+ * 由子类实现,不同的请求返回数据有不同的解析逻辑,由子类实现
+ *
+ * @return mixed
+ */
+ abstract protected function parseDataFromResponse();
+
+ /**
+ * 操作是否成功
+ *
+ * @return mixed
+ */
+ public function isOK()
+ {
+ return $this->isOk;
+ }
+
+ /**
+ * @throws OssException
+ */
+ public function parseResponse()
+ {
+ $this->isOk = $this->isResponseOk();
+ if ($this->isOk) {
+ $this->parsedData = $this->parseDataFromResponse();
+ } else {
+ $httpStatus = strval($this->rawResponse->status);
+ $requestId = strval($this->getRequestId());
+ $code = $this->retrieveErrorCode($this->rawResponse->body);
+ $message = $this->retrieveErrorMessage($this->rawResponse->body);
+ $body = $this->rawResponse->body;
+
+ $details = array(
+ 'status' => $httpStatus,
+ 'request-id' => $requestId,
+ 'code' => $code,
+ 'message' => $message,
+ 'body' => $body
+ );
+ throw new OssException($details);
+ }
+ }
+
+ /**
+ * 尝试从body中获取错误Message
+ *
+ * @param $body
+ * @return string
+ */
+ private function retrieveErrorMessage($body)
+ {
+ if (empty($body) || false === strpos($body, 'Message)) {
+ return strval($xml->Message);
+ }
+ return '';
+ }
+
+ /**
+ * 尝试从body中获取错误Code
+ *
+ * @param $body
+ * @return string
+ */
+ private function retrieveErrorCode($body)
+ {
+ if (empty($body) || false === strpos($body, 'Code)) {
+ return strval($xml->Code);
+ }
+ return '';
+ }
+
+ /**
+ * 根据返回http状态码判断,[200-299]即认为是OK
+ *
+ * @return bool
+ */
+ protected function isResponseOk()
+ {
+ $status = $this->rawResponse->status;
+ if ((int)(intval($status) / 100) == 2) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 返回原始的返回数据
+ *
+ * @return ResponseCore
+ */
+ public function getRawResponse()
+ {
+ return $this->rawResponse;
+ }
+
+ /**
+ * 标示请求是否成功
+ */
+ protected $isOk = false;
+ /**
+ * 由子类解析过的数据
+ */
+ protected $parsedData = null;
+ /**
+ * 存放auth函数返回的原始Response
+ *
+ * @var ResponseCore
+ */
+ protected $rawResponse;
+}
\ No newline at end of file
diff --git a/framework/library/alioss/src/OSS/Result/UploadPartResult.php b/framework/library/alioss/src/OSS/Result/UploadPartResult.php
new file mode 100644
index 0000000..c6b66d4
--- /dev/null
+++ b/framework/library/alioss/src/OSS/Result/UploadPartResult.php
@@ -0,0 +1,28 @@
+rawResponse->header;
+ if (isset($header["etag"])) {
+ return $header["etag"];
+ }
+ throw new OssException("cannot get ETag");
+
+ }
+}
\ No newline at end of file
diff --git a/framework/model/account.mod.php b/framework/model/account.mod.php
new file mode 100644
index 0000000..d1937c6
--- /dev/null
+++ b/framework/model/account.mod.php
@@ -0,0 +1,1413 @@
+ array(
+ 'contain_type' => array(ACCOUNT_TYPE_OFFCIAL_NORMAL, ACCOUNT_TYPE_OFFCIAL_AUTH),
+ 'level' => array(ACCOUNT_SUBSCRIPTION => '订阅号', ACCOUNT_SERVICE => '服务号', ACCOUNT_SUBSCRIPTION_VERIFY => '认证订阅号', ACCOUNT_SERVICE_VERIFY => '认证服务号'),
+ 'icon' => 'wi wi-wx-circle',
+ 'createurl' => url('account/post-step'),
+ 'title' => '公众号',
+ ),
+ WXAPP_TYPE_SIGN => array(
+ 'contain_type' => array(ACCOUNT_TYPE_APP_NORMAL, ACCOUNT_TYPE_APP_AUTH),
+ 'level' => array(),
+ 'icon' => 'wi wi-wxapp',
+ 'createurl' => url('wxapp/post/design_method'),
+ 'title' => '微信小程序',
+ ),
+ WEBAPP_TYPE_SIGN => array(
+ 'contain_type' => array(ACCOUNT_TYPE_WEBAPP_NORMAL),
+ 'level' => array(),
+ 'icon' => 'wi wi-pc-circle',
+ 'createurl' => url('account/create', array('sign' => 'webapp')),
+ 'title' => 'PC',
+ ),
+ PHONEAPP_TYPE_SIGN => array(
+ 'contain_type' => array(ACCOUNT_TYPE_PHONEAPP_NORMAL),
+ 'level' => array(),
+ 'icon' => 'wi wi-app',
+ 'createurl' => url('account/create', array('sign' => 'phoneapp')),
+ 'title' => 'APP',
+ ),
+ ALIAPP_TYPE_SIGN => array(
+ 'contain_type' => array(ACCOUNT_TYPE_ALIAPP_NORMAL),
+ 'level' => array(),
+ 'icon' => 'wi wi-aliapp',
+ 'createurl' => url('account/create', array('sign' => 'aliapp')),
+ 'title' => '支付宝小程序',
+ ),
+ BAIDUAPP_TYPE_SIGN => array(
+ 'contain_type' => array(ACCOUNT_TYPE_BAIDUAPP_NORMAL),
+ 'level' => array(),
+ 'icon' => 'wi wi-baiduapp',
+ 'createurl' => url('account/create', array('sign' => 'baiduapp')),
+ 'title' => '百度小程序',
+ ),
+ TOUTIAOAPP_TYPE_SIGN => array(
+ 'contain_type' => array(ACCOUNT_TYPE_TOUTIAOAPP_NORMAL),
+ 'level' => array(),
+ 'icon' => 'wi wi-toutiaoapp',
+ 'createurl' => url('account/create', array('sign' => 'toutiaoapp')),
+ 'title' => '字节跳动小程序',
+ ),
+ );
+ if (!empty($type_sign)) {
+ return !empty($all_account_type_sign[$type_sign]) ? $all_account_type_sign[$type_sign] : array();
+ }
+ return $all_account_type_sign;
+}
+
+
+function uni_account_type($type = 0)
+{
+ $all_account_type = array(
+ ACCOUNT_TYPE_OFFCIAL_NORMAL => array(
+ 'title' => '公众号',
+ 'type_sign' => ACCOUNT_TYPE_SIGN,
+ 'table_name' => 'account_wechats',
+ 'module_support_name' => MODULE_SUPPORT_ACCOUNT_NAME,
+ 'module_support_value' => MODULE_SUPPORT_ACCOUNT,
+ 'store_type_module' => STORE_TYPE_MODULE,
+ 'store_type_number' => STORE_TYPE_ACCOUNT,
+ 'store_type_renew' => STORE_TYPE_ACCOUNT_RENEW,
+ ),
+ ACCOUNT_TYPE_OFFCIAL_AUTH => array(
+ 'title' => '公众号',
+ 'type_sign' => ACCOUNT_TYPE_SIGN,
+ 'table_name' => 'account_wechats',
+ 'module_support_name' => MODULE_SUPPORT_ACCOUNT_NAME,
+ 'module_support_value' => MODULE_SUPPORT_ACCOUNT,
+ 'store_type_module' => STORE_TYPE_MODULE,
+ 'store_type_number' => STORE_TYPE_ACCOUNT,
+ 'store_type_renew' => STORE_TYPE_ACCOUNT_RENEW,
+ ),
+ ACCOUNT_TYPE_APP_NORMAL => array(
+ 'title' => '微信小程序',
+ 'type_sign' => WXAPP_TYPE_SIGN,
+ 'table_name' => 'account_wxapp',
+ 'support_version' => 1,
+ 'version_tablename' => 'wxapp_versions',
+ 'module_support_name' => MODULE_SUPPORT_WXAPP_NAME,
+ 'module_support_value' => MODULE_SUPPORT_WXAPP,
+ 'store_type_module' => STORE_TYPE_WXAPP_MODULE,
+ 'store_type_number' => STORE_TYPE_WXAPP,
+ 'store_type_renew' => STORE_TYPE_WXAPP_RENEW,
+ ),
+ ACCOUNT_TYPE_APP_AUTH => array(
+ 'title' => '微信小程序',
+ 'type_sign' => WXAPP_TYPE_SIGN,
+ 'table_name' => 'account_wxapp',
+ 'support_version' => 1,
+ 'version_tablename' => 'wxapp_versions',
+ 'module_support_name' => MODULE_SUPPORT_WXAPP_NAME,
+ 'module_support_value' => MODULE_SUPPORT_WXAPP,
+ 'store_type_module' => STORE_TYPE_WXAPP_MODULE,
+ 'store_type_number' => STORE_TYPE_WXAPP,
+ 'store_type_renew' => STORE_TYPE_WXAPP_RENEW,
+ ),
+ ACCOUNT_TYPE_WEBAPP_NORMAL => array(
+ 'title' => 'PC',
+ 'type_sign' => WEBAPP_TYPE_SIGN,
+ 'table_name' => 'account_webapp',
+ 'module_support_name' => MODULE_SUPPORT_WEBAPP_NAME,
+ 'module_support_value' => MODULE_SUPPORT_WEBAPP,
+ 'store_type_module' => STORE_TYPE_WEBAPP_MODULE,
+ 'store_type_number' => STORE_TYPE_WEBAPP,
+ 'store_type_renew' => STORE_TYPE_WEBAPP_RENEW,
+ ),
+ ACCOUNT_TYPE_PHONEAPP_NORMAL => array(
+ 'title' => 'APP',
+ 'type_sign' => PHONEAPP_TYPE_SIGN,
+ 'table_name' => 'account_phoneapp',
+ 'support_version' => 1,
+ 'version_tablename' => 'wxapp_versions',
+ 'module_support_name' => MODULE_SUPPORT_PHONEAPP_NAME,
+ 'module_support_value' => MODULE_SUPPORT_PHONEAPP,
+ 'store_type_module' => STORE_TYPE_PHONEAPP_MODULE,
+ 'store_type_number' => STORE_TYPE_PHONEAPP,
+ 'store_type_renew' => STORE_TYPE_PHONEAPP_RENEW,
+ ),
+ ACCOUNT_TYPE_ALIAPP_NORMAL => array(
+ 'title' => '支付宝小程序',
+ 'type_sign' => ALIAPP_TYPE_SIGN,
+ 'table_name' => 'account_aliapp',
+ 'support_version' => 1,
+ 'version_tablename' => 'wxapp_versions',
+ 'module_support_name' => MODULE_SUPPORT_ALIAPP_NAME,
+ 'module_support_value' => MODULE_SUPPORT_ALIAPP,
+ 'store_type_module' => STORE_TYPE_ALIAPP_MODULE,
+ 'store_type_number' => STORE_TYPE_ALIAPP,
+ 'store_type_renew' => STORE_TYPE_ALIAPP_RENEW,
+ ),
+ ACCOUNT_TYPE_BAIDUAPP_NORMAL => array(
+ 'title' => '百度小程序',
+ 'type_sign' => BAIDUAPP_TYPE_SIGN,
+ 'table_name' => 'account_baiduapp',
+ 'support_version' => 1,
+ 'version_tablename' => 'wxapp_versions',
+ 'module_support_name' => MODULE_SUPPORT_BAIDUAPP_NAME,
+ 'module_support_value' => MODULE_SUPPORT_BAIDUAPP,
+ 'store_type_module' => STORE_TYPE_BAIDUAPP_MODULE,
+ 'store_type_number' => STORE_TYPE_BAIDUAPP,
+ 'store_type_renew' => STORE_TYPE_BAIDUAPP_RENEW,
+ ),
+ ACCOUNT_TYPE_TOUTIAOAPP_NORMAL => array(
+ 'title' => '字节跳动小程序',
+ 'type_sign' => TOUTIAOAPP_TYPE_SIGN,
+ 'table_name' => 'account_toutiaoapp',
+ 'support_version' => 1,
+ 'version_tablename' => 'wxapp_versions',
+ 'module_support_name' => MODULE_SUPPORT_TOUTIAOAPP_NAME,
+ 'module_support_value' => MODULE_SUPPORT_TOUTIAOAPP,
+ 'store_type_module' => STORE_TYPE_TOUTIAOAPP_MODULE,
+ 'store_type_number' => STORE_TYPE_TOUTIAOAPP,
+ 'store_type_renew' => STORE_TYPE_TOUTIAOAPP_RENEW,
+ ),
+ );
+ if (!empty($type)) {
+ return !empty($all_account_type[$type]) ? $all_account_type[$type] : array();
+ }
+ return $all_account_type;
+}
+
+
+function uni_need_account_info()
+{
+ global $controller, $action, $do, $_GPC;
+ if (defined('FRAME') && in_array(FRAME, array('account', 'wxapp')) && $_GPC['module_name'] != 'store' && !$_GPC['system_welcome'] && $_GPC['module_type'] != 'system_welcome') {
+ return true;
+ }
+ if ($controller == 'miniapp') {
+ if ($action == 'version' && $do == 'display') {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+function uni_account_can_create($type_sign)
+{
+ $result = 1;
+ return $result;
+ $type_sign_info = uni_account_type_sign($type_sign);
+ if (empty($type_sign_info)) {
+ return 0;
+ }
+ $all_accounts = table('account')->getall();
+ if (empty($all_accounts)) {
+ return $result;
+ }
+ $account_nums = array();
+ $account_total = 0;
+
+ $uni_account_type = uni_account_type();
+ foreach ($all_accounts as $account) {
+ if (!empty($uni_account_type[$account['type']])) {
+ $account_nums[$uni_account_type[$account['type']]['type_sign']] += 1;
+ }
+ }
+ if (empty($account_nums[$type_sign])) {
+ return $result;
+ }
+ foreach ($account_nums as $account_num) {
+ if ($account_num > 1) {
+ $account_total += ($account_num - 1);
+ }
+ }
+
+ $cloud_total = cloud_account_info();
+ if ($account_total >= $cloud_total) {
+ $result = 0;
+ }
+
+ return $result;
+}
+
+function uni_account_create_info()
+{
+ global $_W;
+ load()->model('permission');
+ $account_create_info = permission_user_account_num();
+ $account_all_type_sign = uni_account_type_sign();
+ foreach ($account_all_type_sign as $sign => &$sign_info) {
+ if ($_W['isadmin']) {
+ $sign_info['can_create'] = true;
+ } else {
+ $sign_limit = $sign . '_limit';
+ $founder_sign_limit = 'founder_' . $sign . '_limit';
+ if (!empty($account_create_info[$sign_limit]) && (!empty($account_create_info[$founder_sign_limit]) && $_W['user']['owner_uid'] || empty($_W['user']['owner_uid'])) || !empty($account_create_info['store_' . $sign . '_limit'])) {
+ $sign_info['can_create'] = true;
+ } else {
+ $sign_info['can_create'] = false;
+ }
+ }
+ }
+ return $account_all_type_sign;
+}
+
+
+function uni_account_extra_info($uniacid)
+{
+ $uniacid = max(0, intval($uniacid));
+ if (empty($uniacid)) {
+ return array();
+ }
+ $account = pdo_get('account', array('uniacid' => $uniacid));
+ if (empty($account) || empty($account['type'])) {
+ return array();
+ }
+ $account_extra = uni_account_type($account['type']);
+ return $account_extra;
+}
+
+
+function uni_user_accounts($uid = 0, $type = 'account')
+{
+ global $_W;
+ $uid = intval($uid) > 0 ? intval($uid) : $_W['uid'];
+ if (!in_array($type, array('account', 'wxapp', 'webapp', 'phoneapp', 'aliapp', 'baiduapp', 'toutiaoapp'))) {
+ $type = 'account';
+ }
+ $cachekey = cache_system_key('user_accounts', array('type' => $type, 'uid' => $uid));
+ $cache = cache_load($cachekey);
+ if (!empty($cache)) {
+ return $cache;
+ }
+ $type = in_array($type, array('account')) ? 'wechats' : $type;
+ $select_fields = 'w.acid, w.uniacid, w.name, a.type';
+ if (in_array($type, array('wechats', 'wxapp'))) {
+ $select_fields .= ', w.level, w.key, w.secret, w.token';
+ }
+ $where = '';
+ $params = array();
+ if (!user_is_founder($uid, true)) {
+ $select_fields .= ', u.role';
+ $where .= " LEFT JOIN " . tablename('uni_account_users') . " u ON u.uniacid = w.uniacid WHERE u.uid = :uid AND u.role IN(:role1, :role2, :role3, :role4) ";
+ $params[':uid'] = $uid;
+ $params[':role1'] = ACCOUNT_MANAGE_NAME_OPERATOR;
+ $params[':role2'] = ACCOUNT_MANAGE_NAME_MANAGER;
+ $params[':role3'] = ACCOUNT_MANAGE_NAME_OWNER;
+ $params[':role4'] = ACCOUNT_MANAGE_NAME_VICE_FOUNDER;
+ }
+ $where .= !empty($where) ? " AND a.isdeleted <> 1 AND u.role IS NOT NULL" : " WHERE a.isdeleted <> 1";
+
+ $sql = "SELECT " . $select_fields . " FROM " . tablename('account_' . $type) . " w LEFT JOIN " . tablename('account') . " a ON a.acid = w.acid AND a.uniacid = w.uniacid" . $where;
+ $result = pdo_fetchall($sql, $params, 'uniacid');
+ cache_write($cachekey, $result);
+ return $result;
+}
+
+
+function account_owner($uniacid = 0)
+{
+ global $_W;
+ load()->model('user');
+ $uniacid = intval($uniacid);
+ if (empty($uniacid)) {
+ return array();
+ }
+ $ownerid = pdo_getcolumn('uni_account_users', array('uniacid' => $uniacid, 'role' => 'owner'), 'uid');
+ if (empty($ownerid)) {
+ $ownerid = pdo_getcolumn('uni_account_users', array('uniacid' => $uniacid, 'role' => 'vice_founder'), 'uid');
+ if (empty($ownerid)) {
+ $founders = explode(',', $_W['config']['setting']['founder']);
+ $ownerid = $founders[0];
+ }
+ }
+ $owner = user_single($ownerid);
+ if (empty($owner)) {
+ return array();
+ }
+ return $owner;
+}
+
+function uni_fetch($uniacid = 0)
+{
+ global $_W;
+ $uniacid = empty($uniacid) ? $_W['uniacid'] : intval($uniacid);
+ $account_api = WeAccount::createByUniacid($uniacid);
+ if (is_error($account_api)) {
+ return $account_api;
+ }
+ $account_api->__toArray();
+ $account_api['accessurl'] = $account_api['manageurl'] = wurl('account/post', array('uniacid' => $uniacid, 'account_type' => $account_api['type']), true);
+ $account_api['roleurl'] = wurl('account/post-user/edit', array('uniacid' => $uniacid, 'account_type' => $account_api['type']), true);
+ return $account_api;
+}
+
+
+function uni_site_store_buy_goods($uniacid, $type = STORE_TYPE_MODULE)
+{
+ $cachekey = cache_system_key('site_store_buy', array('type' => $type, 'uniacid' => $uniacid));
+ $site_store_buy_goods = cache_load($cachekey);
+ if (!empty($site_store_buy_goods)) {
+ return $site_store_buy_goods;
+ }
+ $store_table = table('site_store_order');
+ if ($type != STORE_TYPE_API) {
+ $store_table->searchWithEndtime();
+ $site_store_buy_goods = $store_table->searchAccountBuyGoods($uniacid, $type);
+ $site_store_buy_goods = array_keys($site_store_buy_goods);
+ } else {
+ $site_store_buy_goods = $store_table->searchAccountBuyGoods($uniacid, $type);
+ $setting = uni_setting_load('statistics', $uniacid);
+ $use_number = isset($setting['statistics']['use']) ? intval($setting['statistics']['use']) : 0;
+ $site_store_buy_goods = $site_store_buy_goods - $use_number;
+ }
+ cache_write($cachekey, $site_store_buy_goods);
+ return $site_store_buy_goods;
+}
+
+
+function uni_modules_by_uniacid($uniacid)
+{
+ global $_W;
+ load()->model('user');
+ load()->model('module');
+ $account_info = table('account')->getByUniacid($uniacid);
+ $uni_account_type = uni_account_type($account_info['type']);
+ $owner_uid = pdo_getall('uni_account_users', array('uniacid' => $uniacid, 'role' => array('owner', 'vice_founder')), array('uid', 'role'), 'role');
+ $owner_uid = !empty($owner_uid['owner']) ? $owner_uid['owner']['uid'] : (!empty($owner_uid['vice_founder']) ? $owner_uid['vice_founder']['uid'] : 0);
+
+ $cachekey = cache_system_key('unimodules', array('uniacid' => $uniacid));
+ $modules = cache_load($cachekey);
+ if (empty($modules)) {
+ $enabled_modules = table('modules')->getNonRecycleModules();
+ if (!empty($owner_uid) && !user_is_founder($owner_uid, true)) {
+ $group_modules = table('account')->accountGroupModules($uniacid);
+
+ $user_modules = user_modules($owner_uid);
+ if (!empty($user_modules)) {
+ $group_modules = array_unique(array_merge($group_modules, array_keys($user_modules)));
+ $group_modules = array_intersect(array_keys($enabled_modules), $group_modules);
+ }
+ } else {
+ $group_modules = array_keys($enabled_modules);
+ }
+ cache_write($cachekey, $group_modules);
+ $modules = $group_modules;
+ }
+ $modules = array_merge($modules, module_system());
+
+ $module_list = array();
+ if (!empty($modules)) {
+ foreach ($modules as $name) {
+ if (empty($name)) {
+ continue;
+ }
+ $module_info = module_fetch($name);
+ if ($module_info[$uni_account_type['module_support_name']] != $uni_account_type['module_support_value']) {
+ continue;
+ }
+ if (empty($module_info)) {
+ $module_cloud_info = pdo_get('modules_cloud', array('name' => $name));
+ $store_goods_info = pdo_get('site_store_goods', array('module' => $name));
+ if (!empty($module_cloud_info) && $store_goods_info['is_wish'] == 1) {
+ $module_info = $module_cloud_info;
+ }
+ }
+ if (!empty($module_info['recycle_info'])) {
+ foreach (module_support_type() as $support => $value) {
+ if ($module_info['recycle_info'][$support] > 0 && $module_info[$support] == $value['support']) {
+ $module_info[$support] = $value['not_support'];
+ }
+ }
+ }
+ if ($module_info[MODULE_SUPPORT_ACCOUNT_NAME] != MODULE_SUPPORT_ACCOUNT &&
+ in_array($account_info['type'], array(ACCOUNT_TYPE_OFFCIAL_NORMAL, ACCOUNT_TYPE_OFFCIAL_AUTH))) {
+ continue;
+ }
+ if ($module_info[MODULE_SUPPORT_WEBAPP_NAME] != MODULE_SUPPORT_WEBAPP &&
+ in_array($account_info['type'], array(ACCOUNT_TYPE_WEBAPP_NORMAL))) {
+ continue;
+ }
+ if ($module_info[MODULE_SUPPORT_PHONEAPP_NAME] != MODULE_SUPPORT_PHONEAPP &&
+ in_array($account_info['type'], array(ACCOUNT_TYPE_PHONEAPP_NORMAL))) {
+ continue;
+ }
+ if ($module_info[MODULE_SUPPORT_ALIAPP_NAME] != MODULE_SUPPORT_ALIAPP &&
+ in_array($account_info['type'], array(ACCOUNT_TYPE_ALIAPP_NORMAL))) {
+ continue;
+ }
+ if ($module_info[MODULE_SUPPORT_BAIDUAPP_NAME] != MODULE_SUPPORT_BAIDUAPP &&
+ in_array($account_info['type'], array(ACCOUNT_TYPE_BAIDUAPP_NORMAL))) {
+ continue;
+ }
+ if ($module_info[MODULE_SUPPORT_TOUTIAOAPP_NAME] != MODULE_SUPPORT_TOUTIAOAPP &&
+ in_array($account_info['type'], array(ACCOUNT_TYPE_TOUTIAOAPP_NORMAL))) {
+ continue;
+ }
+ if ($module_info[MODULE_SUPPORT_WXAPP_NAME] != MODULE_SUPPORT_WXAPP &&
+ $module_info[MODULE_SUPPORT_ACCOUNT_NAME] != MODULE_SUPPORT_ACCOUNT &&
+ in_array($account_info['type'], array(ACCOUNT_TYPE_APP_NORMAL, ACCOUNT_TYPE_APP_AUTH))) {
+ continue;
+ }
+ if ($module_info[MODULE_SUPPORT_SYSTEMWELCOME_NAME] == MODULE_SUPPORT_SYSTEMWELCOME &&
+ $module_info[MODULE_SUPPORT_ACCOUNT_NAME] != MODULE_SUPPORT_ACCOUNT &&
+ $module_info[MODULE_SUPPORT_WEBAPP_NAME] != MODULE_SUPPORT_WEBAPP &&
+ $module_info[MODULE_SUPPORT_PHONEAPP_NAME] != MODULE_SUPPORT_PHONEAPP &&
+ $module_info[MODULE_SUPPORT_ALIAPP_NAME] != MODULE_SUPPORT_ALIAPP &&
+ $module_info[MODULE_SUPPORT_BAIDUAPP_NAME] != MODULE_SUPPORT_BAIDUAPP &&
+ $module_info[MODULE_SUPPORT_WXAPP_NAME] != MODULE_SUPPORT_WXAPP) {
+ continue;
+ }
+ if (!empty($module_info)) {
+ $module_list[$name] = $module_info;
+ }
+ }
+ }
+ $module_list['core'] = array('title' => '系统事件处理模块', 'name' => 'core', 'issystem' => 1, 'enabled' => 1, 'isdisplay' => 0);
+ return $module_list;
+}
+
+
+function uni_modules()
+{
+ global $_W;
+ return uni_modules_by_uniacid($_W['uniacid']);
+}
+
+function uni_modules_app_binding()
+{
+ global $_W;
+ $cachekey = cache_system_key('unimodules_binding', array('uniacid' => $_W['uniacid']));
+ $cache = cache_load($cachekey);
+ if (!empty($cache)) {
+ return $cache;
+ }
+ load()->model('module');
+ $result = array();
+ $modules = uni_modules();
+ if (!empty($modules)) {
+ foreach ($modules as $module) {
+ if ($module['type'] == 'system') {
+ continue;
+ }
+ $entries = module_app_entries($module['name'], array('home', 'profile', 'shortcut', 'function', 'cover'));
+ if (empty($entries)) {
+ continue;
+ }
+ if ($module['type'] == '') {
+ $module['type'] = 'other';
+ }
+ $result[$module['name']] = array(
+ 'name' => $module['name'],
+ 'type' => $module['type'],
+ 'title' => $module['title'],
+ 'entries' => array(
+ 'cover' => $entries['cover'],
+ 'home' => $entries['home'],
+ 'profile' => $entries['profile'],
+ 'shortcut' => $entries['shortcut'],
+ 'function' => $entries['function']
+ )
+ );
+ unset($module);
+ }
+ }
+ cache_write($cachekey, $result);
+ return $result;
+}
+
+
+function uni_groups($groupids = array(), $show_all = false)
+{
+ load()->model('module');
+ global $_W;
+ $cache_key_id = 0;
+ if (!empty($groupids)) {
+ foreach ($groupids as $groupid_key => $groupid_val) {
+ $groupid_val = intval($groupid_val);
+ $groupids[$groupid_key] = $groupid_val;
+ $cache_key_id .= $groupid_val;
+ }
+ }
+ $cachekey = cache_system_key('uni_groups', array('groupids' => $cache_key_id));
+ $list = cache_load($cachekey);
+ if (empty($list)) {
+ $condition = ' WHERE uniacid = 0 AND uid = 0';
+ if (!empty($groupids)) {
+ foreach ($groupids as $groupid_key => $groupid_val) {
+ $groupids[$groupid_key] = intval($groupid_val);
+ }
+ $groupids_string = implode(',', $groupids);
+ $condition .= ' AND id IN (' . $groupids_string . ')';
+ }
+ $list = pdo_fetchall("SELECT * FROM " . tablename('uni_group') . $condition . " ORDER BY id DESC", array(), 'id');
+ if (!empty($groupids)) {
+ if (in_array('-1', $groupids)) {
+ $list[-1] = array('id' => -1, 'name' => '所有服务', 'modules' => array('title' => '系统所有模块'), 'templates' => array('title' => '系统所有模板'));
+ }
+ if (in_array('0', $groupids)) {
+ $list[0] = array('id' => 0, 'name' => '基础服务', 'modules' => array('title' => '系统模块'), 'templates' => array('title' => '系统模板'));
+ }
+ }
+
+ if (!empty($list)) {
+ foreach ($list as $k => &$row) {
+ $modules = (array)iunserializer($row['modules']);
+ $row['modules_all'] = array();
+ if (!empty($modules)) {
+ foreach ($modules as $type => $modulenames) {
+ $type = $type == 'modules' ? 'account' : $type;
+ if (empty($modulenames) || !is_array($modulenames)) {
+ continue;
+ }
+ $row['modules_all'] = array_merge($row['modules_all'], $modulenames);
+ $row[$type] = empty($row[$type]) ? $modulenames : array_merge($row[$type], $modulenames);
+ }
+ $row['modules_all'] = array_unique($row['modules_all']);
+ }
+
+ if (!empty($row['templates'])) {
+ $row['templates'] = (array)iunserializer($row['templates']);
+ if (!empty($row['templates'])) {
+ $row['templates'] = table('modules')->getAllTemplateByIds($row['templates'], 'name');
+ }
+ }
+ }
+ }
+ cache_write($cachekey, $list);
+ }
+ $group_list = array();
+ if (empty($list)) {
+ return $group_list;
+ }
+ $modules_info = array();
+ foreach ($list as &$item) {
+ if (empty($item['modules_all'])) {
+ continue;
+ }
+
+ $modules_all = $item['modules_all'];
+ $item['modules_all'] = array();
+ if (!empty($item['account'])) {
+ $account_modules = $item['account'];
+ $item['account'] = array();
+ foreach ($account_modules as $name) {
+ if (empty($modules_info[$name]) || !is_array($modules_info[$name])) {
+ $modules_info[$name] = module_main_info($name);
+ }
+ if (empty($item['modules_all'][$name])) {
+ $item['modules_all'][$name] = $modules_info[$name];
+ }
+ if (in_array($name, $modules_all)) {
+ $item['modules_all'][$name]['group_support']['account_support'] = 2;
+ }
+ $item['account'][$name] = $modules_info[$name];
+ }
+ }
+ if (!empty($item['wxapp'])) {
+ $wxapp_modules = $item['wxapp'];
+ $item['wxapp'] = array();
+ foreach ($wxapp_modules as $name) {
+ if (empty($modules_info[$name]) || !is_array($modules_info[$name])) {
+ $modules_info[$name] = module_main_info($name);
+ }
+ if (empty($item['modules_all'][$name])) {
+ $item['modules_all'][$name] = $modules_info[$name];
+ }
+ if (in_array($name, $modules_all)) {
+ $item['modules_all'][$name]['group_support']['account_support'] = 2;
+ }
+ $item['wxapp'][$name] = $modules_info[$name];
+ }
+ }
+ if (!empty($item['webapp'])) {
+ $wxapp_modules = $item['webapp'];
+ $item['webapp'] = array();
+ foreach ($wxapp_modules as $name) {
+ if (empty($modules_info[$name]) || !is_array($modules_info[$name])) {
+ $modules_info[$name] = module_main_info($name);
+ }
+ if (empty($item['modules_all'][$name])) {
+ $item['modules_all'][$name] = $modules_info[$name];
+ }
+ if (in_array($name, $modules_all)) {
+ $item['modules_all'][$name]['group_support']['webapp_support'] = 2;
+ }
+ $item['webapp'][$name] = $modules_info[$name];
+ }
+ }
+ if (!empty($item['phoneapp'])) {
+ $phoneapp_modules = $item['phoneapp'];
+ $item['phoneapp'] = array();
+ foreach ($phoneapp_modules as $name) {
+ if (empty($modules_info[$name]) || !is_array($modules_info[$name])) {
+ $modules_info[$name] = module_main_info($name);
+ }
+ if (empty($item['modules_all'][$name])) {
+ $item['modules_all'][$name] = $modules_info[$name];
+ }
+ if (in_array($name, $modules_all)) {
+ $item['modules_all'][$name]['group_support']['phoneapp_support'] = 2;
+ }
+ $item['phoneapp'][$name] = $modules_info[$name];
+ }
+ }
+ if (!empty($item['aliapp'])) {
+ $aliapp_modules = $item['aliapp'];
+ $item['aliapp'] = array();
+ foreach ($aliapp_modules as $name) {
+ if (empty($modules_info[$name]) || !is_array($modules_info[$name])) {
+ $modules_info[$name] = module_main_info($name);
+ }
+ if (empty($item['modules_all'][$name])) {
+ $item['modules_all'][$name] = $modules_info[$name];
+ }
+ if (in_array($name, $modules_all)) {
+ $item['modules_all'][$name]['group_support']['aliapp_support'] = 2;
+ }
+ $item['aliapp'][$name] = $modules_info[$name];
+ }
+ }
+ if (!empty($item['baiduapp'])) {
+ $baiduapp_modules = $item['baiduapp'];
+ $item['baiduapp'] = array();
+ foreach ($baiduapp_modules as $name) {
+ if (empty($modules_info[$name]) || !is_array($modules_info[$name])) {
+ $modules_info[$name] = module_main_info($name);
+ }
+ if (empty($item['modules_all'][$name])) {
+ $item['modules_all'][$name] = $modules_info[$name];
+ }
+ if (in_array($name, $modules_all)) {
+ $item['modules_all'][$name]['group_support']['baiduapp_support'] = 2;
+ }
+ $item['baiduapp'][$name] = $modules_info[$name];
+ }
+ }
+ if (!empty($item['toutiaoapp'])) {
+ $toutiaoapp_modules = $item['toutiaoapp'];
+ $item['toutiaoapp'] = array();
+ foreach ($toutiaoapp_modules as $name) {
+ if (empty($modules_info[$name]) || !is_array($modules_info[$name])) {
+ $modules_info[$name] = module_main_info($name);
+ }
+ if (empty($item['modules_all'][$name])) {
+ $item['modules_all'][$name] = $modules_info[$name];
+ }
+ if (in_array($name, $modules_all)) {
+ $item['modules_all'][$name]['group_support']['toutiaoapp_support'] = 2;
+ }
+ $item['toutiaoapp'][$name] = $modules_info[$name];
+ }
+ }
+ }
+
+ if (!empty($groupids)) {
+ foreach ($groupids as $id) {
+ $group_list[$id] = $list[$id];
+ }
+ } else {
+ if (user_is_vice_founder() && empty($show_all)) {
+ $founder_own_table = table('users_founder_own_uni_groups');
+ $founder_own_uni_groups = $founder_own_table->getOwnUniGroupsByFounderUid($_W['uid']);
+ foreach ($list as $group_key => $group) {
+ if (!in_array($group_key, array_keys($founder_own_uni_groups))) {
+ unset($list[$group_key]);
+ continue;
+ }
+ }
+ }
+ $group_list = $list;
+ }
+
+ return $group_list;
+}
+
+
+function uni_templates()
+{
+ global $_W;
+ load()->model('user');
+ $owneruid = pdo_fetchcolumn("SELECT uid FROM " . tablename('uni_account_users') . " WHERE uniacid = :uniacid AND role = 'owner'", array(':uniacid' => $_W['uniacid']));
+ $owner = user_single(array('uid' => $owneruid));
+ if (empty($owner) || user_is_founder($owner['uid'])) {
+ $groupid = '-1';
+ } else {
+ $groupid = $owner['groupid'];
+ }
+ if ($groupid == '-1') {
+ $templates = table('modules')->getAllTemplates('mid');
+ return $templates;
+ }
+
+ $extend = pdo_getall('uni_account_group', array('uniacid' => $_W['uniacid']), array(), 'groupid');
+ $uni_extend = pdo_get('uni_account_extra_modules', array('uniacid' => $_W['uniacid']));
+ $owner_extend_groups = table('users_extra_group')->getUniGroupsByUid($owneruid);
+ $owner_extend_templates = table('users_extra_modules')->getExtraModulesByUid($owneruid);
+ $modules_table = table('modules');
+ $modules_table->searchTemplateWithName('default');
+ $template_default = $modules_table->getAllTemplates('mid');
+
+ if (empty($groupid) && empty($extend) && empty($uni_extend) && empty($owner_extend_groups) && empty($owner_extend_templates)) {
+ return $template_default;
+ }
+
+ $group = pdo_fetch("SELECT id, name, package FROM " . tablename('users_group') . " WHERE id = :id", array(':id' => $groupid));
+ $packageids = iunserializer($group['package']);
+ if (!is_array($packageids)) {
+ $packageids = array();
+ }
+ if (!empty($extend)) {
+ foreach ($extend as $extend_packageid => $row) {
+ $packageids[] = $extend_packageid;
+ }
+ }
+
+ if (!empty($owner_extend_groups)) {
+ foreach ($owner_extend_groups as $id => $row) {
+ $packageids[] = $id;
+ }
+ }
+ if (in_array('-1', $packageids)) {
+ return table('modules')->getAllTemplates('mid');
+ }
+
+ $template_modules = array();
+ if (!empty($packageids)) {
+ $wechatgroup = table('uni_group')->where(array('id' => $packageids))->getall();
+ if (!empty($wechatgroup)) {
+ foreach ($wechatgroup as $row) {
+ $account_modules = iunserializer($row['modules']);
+ if (!is_array($account_modules['modules']) || empty($account_modules['modules'])) {
+ continue;
+ }
+ foreach ($account_modules['modules'] as $module_name) {
+ $template_modules[] = $module_name;
+ }
+ }
+ }
+ }
+ if (!empty($uni_extend)) {
+ $uni_extend_modules = iunserializer($uni_extend['modules']);
+ if (is_array($uni_extend_modules['modules']) && !empty($uni_extend_modules['modules'])) {
+ foreach ($uni_extend_modules['modules'] as $module_name) {
+ $template_modules[] = $module_name;
+ }
+ }
+ }
+ $template_modules = array_unique($template_modules);
+ $template_modules[] = 'default';
+ if (is_array($owner_extend_templates)) {
+ $template_modules = array_merge($template_modules, array_column($owner_extend_templates, 'module_name'));
+ }
+ $result = table('modules')->getTemplateByNames($template_modules, 'mid');
+ return $result;
+}
+
+
+function uni_setting_save($name, $value)
+{
+ global $_W;
+ $uniacid = !empty($_W['uniacid']) ? $_W['uniacid'] : $_W['account']['uniacid'];
+ if (empty($name)) {
+ return false;
+ }
+ if (is_array($value)) {
+ $value = serialize($value);
+ }
+ $unisetting = pdo_get('uni_settings', array('uniacid' => $uniacid), array('uniacid'));
+ if (!empty($unisetting)) {
+ pdo_update('uni_settings', array($name => $value), array('uniacid' => $uniacid));
+ } else {
+ pdo_insert('uni_settings', array($name => $value, 'uniacid' => $uniacid));
+ }
+ cache_delete(cache_system_key('uniaccount', array('uniacid' => $uniacid)));
+ return true;
+}
+
+
+function uni_setting_load($name = '', $uniacid = 0)
+{
+ global $_W;
+ $uniacid = empty($uniacid) ? $_W['uniacid'] : $uniacid;
+ $cachekey = cache_system_key('unisetting', array('uniacid' => $uniacid));
+ $unisetting = cache_load($cachekey);
+ if (empty($unisetting) || ($name == 'remote' && empty($unisetting['remote']))) {
+ $unisetting = pdo_get('uni_settings', array('uniacid' => $uniacid));
+ if (!empty($unisetting)) {
+ $serialize = array('site_info', 'stat', 'oauth', 'passport', 'notify',
+ 'creditnames', 'default_message', 'creditbehaviors', 'payment',
+ 'recharge', 'tplnotice', 'mcplugin', 'statistics', 'bind_domain', 'remote');
+ foreach ($unisetting as $key => &$row) {
+ if (in_array($key, $serialize) && !empty($row)) {
+ $row = (array)iunserializer($row);
+ }
+ }
+ } else {
+ $unisetting = array();
+ }
+ cache_write($cachekey, $unisetting);
+ }
+ if (empty($unisetting)) {
+ return array();
+ }
+ if (empty($name)) {
+ return $unisetting;
+ }
+ if (!is_array($name)) {
+ $name = array($name);
+ }
+ return array_elements($name, $unisetting);
+}
+
+function uni_account_user_role_insert($uniacid, $uid, $role)
+{
+ $vice_account = array(
+ 'uniacid' => intval($uniacid),
+ 'uid' => intval($uid),
+ 'role' => trim($role)
+ );
+ $account_user = pdo_get('uni_account_users', $vice_account, array('id'));
+ if (!empty($account_user)) {
+ return false;
+ }
+ return pdo_insert('uni_account_users', $vice_account);
+}
+
+
+function uni_owner_account_nums($uid, $role)
+{
+ $account_all_type = uni_account_type();
+ $account_all_type_sign = array_keys(uni_account_type_sign());
+
+ foreach ($account_all_type_sign as $type_info) {
+ $key_name = $type_info . '_num';
+ $num[$key_name] = 0;
+ }
+
+ $uniacocunts = table('account')->searchAccountList();
+
+ if (!empty($uniacocunts)) {
+ $uni_account_users_table = table('uni_account_users');
+ $uni_account_users_table->searchWithRole($role);
+ $all_account = $uni_account_users_table->getCommonUserOwnAccountUniacids($uid);
+
+ foreach ($all_account as $account) {
+ foreach ($account_all_type as $type_key => $type_info) {
+ if ($type_key == $account['type']) {
+ $key_name = $type_info['type_sign'] . '_num';
+ $num[$key_name] += 1;
+ continue;
+ }
+ }
+ }
+ }
+
+ return $num;
+}
+
+function uni_update_week_stat()
+{
+ global $_W;
+ $cachekey = cache_system_key('stat_todaylock', array('uniacid' => $_W['uniacid']));
+ $cache = cache_load($cachekey);
+ if (!empty($cache) && $cache['expire'] > TIMESTAMP) {
+ return true;
+ }
+ $seven_days = array(
+ date('Ymd', strtotime('-1 days')),
+ date('Ymd', strtotime('-2 days')),
+ date('Ymd', strtotime('-3 days')),
+ date('Ymd', strtotime('-4 days')),
+ date('Ymd', strtotime('-5 days')),
+ date('Ymd', strtotime('-6 days')),
+ date('Ymd', strtotime('-7 days')),
+ );
+
+ $week_stat_fans = pdo_getall('stat_fans', array('date' => $seven_days, 'uniacid' => $_W['uniacid']), '', 'date');
+ $stat_update_yes = false;
+ foreach ($seven_days as $sevens) {
+ if (empty($week_stat_fans[$sevens]) || $week_stat_fans[$sevens]['cumulate'] <= 0) {
+ $stat_update_yes = true;
+ break;
+ }
+ }
+ if (empty($stat_update_yes)) {
+ return true;
+ }
+ $account = uni_fetch($_W['uniacid']);
+ if (is_error($account)) {
+ return $account;
+ }
+ if ($account['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || $account['level'] == ACCOUNT_SERVICE_VERIFY) {
+ $account_obj = WeAccount::createByUniacid();
+ $weixin_stat = $account_obj->getFansStat();
+ if (empty($weixin_stat) || is_error($weixin_stat)) {
+ return error(-1, '调用微信接口错误');
+ }
+ }
+ foreach ($seven_days as $sevens) {
+ if ($account['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || $account['level'] == ACCOUNT_SERVICE_VERIFY) {
+ $update_stat = array(
+ 'uniacid' => $_W['uniacid'],
+ 'new' => $weixin_stat[$sevens]['new'],
+ 'cancel' => $weixin_stat[$sevens]['cancel'],
+ 'cumulate' => $weixin_stat[$sevens]['cumulate'],
+ 'date' => $sevens,
+ );
+ } else {
+ $update_stat = array(
+ 'cumulate' => pdo_fetchcolumn("SELECT COUNT(*) FROM " . tablename('mc_mapping_fans') . " WHERE uniacid = :uniacid AND follow = :follow AND followtime < :endtime", array(':uniacid' => $_W['uniacid'], ':endtime' => strtotime($sevens) + 86400, ':follow' => 1)),
+ 'date' => $sevens,
+ 'new' => $week_stat_fans[$sevens]['new'],
+ 'cancel' => $week_stat_fans[$sevens]['cancel'],
+ 'uniacid' => $_W['uniacid'],
+ );
+ }
+ if (empty($week_stat_fans[$sevens])) {
+ pdo_insert('stat_fans', $update_stat);
+ } elseif (empty($week_stat_fans[$sevens]['cumulate']) || $week_stat_fans[$sevens]['cumulate'] < 0) {
+ pdo_update('stat_fans', $update_stat, array('id' => $week_stat_fans[$sevens]['id']));
+ }
+ }
+ cache_write($cachekey, array('expire' => TIMESTAMP + 7200));
+ return true;
+}
+
+
+function account_create($uniacid, $account)
+{
+ global $_W;
+ $account_all_type = uni_account_type();
+ $type = $account['type'];
+ $type_sign = $account_all_type[$type]['type_sign'];
+ unset($account['type']);
+
+ $accountdata = array('uniacid' => $uniacid, 'type' => $type, 'hash' => random(8));
+ //$user_create_account_info = permission_user_account_num();
+
+ if (!$_W['isadmin'] && $_W['user']['endtime'] > USER_ENDTIME_GROUP_UNLIMIT_TYPE) {
+ $accountdata['endtime'] = $_W['user']['endtime'];
+ }
+
+// if (empty($_W['isfounder']) && empty($user_create_account_info["usergroup_{$type_sign}_limit"])) {
+// $accountdata['endtime'] = strtotime('+1 month', time());
+// pdo_insert('site_store_create_account', array('endtime' => strtotime('+1 month', time()), 'uid' => $_W['uid'], 'uniacid' => $uniacid, 'type' => $type));
+// }
+
+
+ pdo_insert('account', $accountdata);
+ $acid = pdo_insertid();
+
+ $account['acid'] = $acid;
+ $account['uniacid'] = $uniacid;
+ if (in_array($type_sign, array(ACCOUNT_TYPE_SIGN))) {
+ $account['token'] = random(32);
+ $account['encodingaeskey'] = random(43);
+ }
+ pdo_insert($account_all_type[$type]['table_name'], $account);
+ return $acid;
+}
+
+
+function account_fetch($acid)
+{
+ $account_info = pdo_get('account', array('acid' => $acid));
+ if (empty($account_info)) {
+ return error(-1, '公众号不存在');
+ }
+ return uni_fetch($account_info['uniacid']);
+}
+
+
+function uni_setmeal($uniacid = 0)
+{
+ global $_W;
+ if (!$uniacid) {
+ $uniacid = $_W['uniacid'];
+ }
+ $owneruid = pdo_fetchcolumn("SELECT uid FROM " . tablename('uni_account_users') . " WHERE uniacid = :uniacid AND role = 'owner'", array(':uniacid' => $uniacid));
+ if (empty($owneruid)) {
+ $user = array(
+ 'uid' => -1,
+ 'username' => '创始人',
+ 'timelimit' => '未设置',
+ 'groupid' => '-1',
+ 'groupname' => '所有服务'
+ );
+ return $user;
+ }
+ load()->model('user');
+ $owner = user_single(array('uid' => $owneruid));
+ $user = array(
+ 'uid' => $owner['uid'],
+ 'username' => $owner['username'],
+ 'groupid' => $owner['groupid'],
+ 'groupname' => ''
+ );
+ if (empty($owner['endtime'])) {
+ $user['timelimit'] = date('Y-m-d', $owner['starttime']) . ' ~ 无限制';
+ } else {
+ if ($owner['endtime'] <= TIMESTAMP) {
+ $user['timelimit'] = '已到期';
+ } else {
+ $year = 0;
+ $month = 0;
+ $day = 0;
+ $endtime = $owner['endtime'];
+ $time = strtotime('+1 year');
+ if ($endtime > $time) {
+ $year = $year + 1;
+ $time = strtotime("+1 year", $time);
+ }
+ $time = strtotime("-1 year", $time);
+ $time = strtotime("+1 month", $time);
+ if ($endtime > $time) {
+ $month = $month + 1;
+ $time = strtotime("+1 month", $time);
+ }
+ $time = strtotime("-1 month", $time);
+ $time = strtotime("+1 day", $time);
+ if ($endtime > $time) {
+ $day = $day + 1;
+ $time = strtotime("+1 day", $time);
+ }
+ if (empty($year)) {
+ $timelimit = empty($month) ? $day . '天' : date('Y-m-d', $owner['starttime']) . '~' . date('Y-m-d', $owner['endtime']);
+ } else {
+ $timelimit = date('Y-m-d', $owner['starttime']) . '~' . date('Y-m-d', $owner['endtime']);
+ }
+ $user['timelimit'] = $timelimit;
+ }
+ }
+ return $user;
+}
+
+
+function account_delete($acid)
+{
+ global $_W;
+ load()->func('file');
+ load()->model('module');
+ load()->model('job');
+ $jobid = 0;
+ $account = pdo_get('uni_account', array('default_acid' => $acid));
+ if ($account) {
+ $uniacid = $account['uniacid'];
+ $state = permission_account_user_role($_W['uid'], $uniacid);
+ if (!in_array($state, array(ACCOUNT_MANAGE_NAME_OWNER, ACCOUNT_MANAGE_NAME_FOUNDER, ACCOUNT_MANAGE_NAME_VICE_FOUNDER))) {
+ itoast('没有该公众号操作权限!', url('account/recycle'), 'error');
+ }
+ if ($uniacid == $_W['uniacid']) {
+ isetcookie('__uniacid', '');
+ }
+ cache_delete(cache_system_key('uniaccount', array('uniacid' => $uniacid)));
+ $modules = array();
+ $rules = pdo_fetchall("SELECT id, module FROM " . tablename('rule') . " WHERE uniacid = '{$uniacid}'");
+ if (!empty($rules)) {
+ foreach ($rules as $index => $rule) {
+ $deleteid[] = intval($rule['id']);
+ }
+ pdo_delete('rule', "id IN ('" . implode("','", $deleteid) . "')");
+ }
+
+ $subaccount = pdo_fetchall("SELECT acid FROM " . tablename('account') . " WHERE uniacid = :uniacid", array(':uniacid' => $uniacid));
+ if (!empty($subaccount)) {
+ foreach ($subaccount as $childaccount) {
+ @unlink(IA_ROOT . '/attachment/qrcode_' . $childaccount['acid'] . '.jpg');
+ @unlink(IA_ROOT . '/attachment/headimg_' . $childaccount['acid'] . '.jpg');
+ file_remote_delete('qrcode_' . $childaccount['acid'] . '.jpg');
+ file_remote_delete('headimg_' . $childaccount['acid'] . '.jpg');
+ }
+ if (!empty($acid)) {
+ $jobid = job_create_delete_account($uniacid, $account['name'], $_W['uid']);
+ }
+ }
+
+ $tables = array(
+ 'account', 'account_wechats', 'account_wxapp', 'wxapp_versions', 'account_webapp', 'account_phoneapp',
+ 'core_paylog', 'cover_reply', 'mc_chats_record', 'mc_credits_recharge', 'mc_credits_record',
+ 'mc_fans_groups', 'mc_groups', 'mc_handsel', 'mc_mapping_fans', 'mc_mass_record', 'mc_member_address',
+ 'mc_member_fields', 'mc_members', 'menu_event', 'qrcode', 'qrcode_stat', 'rule', 'rule_keyword',
+ 'site_article', 'site_category', 'site_multi', 'site_nav', 'site_slide', 'site_styles', 'site_styles_vars',
+ 'stat_keyword', 'stat_rule', 'uni_account', 'uni_account_modules', 'uni_account_users', 'uni_settings',
+ 'uni_group', 'uni_account_extra_modules', 'uni_verifycode', 'users_permission', 'wechat_news',
+ 'users_lastuse', 'users_operate_history', 'users_operate_star'
+ );
+ if (!empty($tables)) {
+ foreach ($tables as $table) {
+ $tablename = str_replace($GLOBALS['_W']['config']['db']['tablepre'], '', $table);
+ pdo_delete($tablename, array('uniacid' => $uniacid));
+ }
+ }
+ } else {
+ $account = account_fetch($acid);
+ if (empty($account)) {
+ itoast('子公众号不存在或是已经被删除', '', '');
+ }
+ $uniacid = $account['uniacid'];
+ $state = permission_account_user_role($_W['uid'], $uniacid);
+ if ($state != ACCOUNT_MANAGE_NAME_FOUNDER && $state != ACCOUNT_MANAGE_NAME_OWNER) {
+ itoast('没有该公众号操作权限!', url('account/recycle'), 'error');
+ }
+ $uniaccount = uni_fetch($account['uniacid']);
+ if ($uniaccount['default_acid'] == $acid) {
+ itoast('默认子公众号不能删除', '', '');
+ }
+ pdo_delete('account', array('uniacid' => $uniacid));
+ pdo_delete('account_wechats', array('uniacid' => $uniacid));
+ cache_delete(cache_system_key('uniaccount', array('uniacid' => $uniacid)));
+ cache_delete(cache_system_key('account_auth_refreshtoken', array('uniacid' => $uniacid)));
+ $oauth = uni_setting($uniacid, array('oauth'));
+ if (!empty($oauth['oauth']['account']) && $oauth['oauth']['account'] == $acid) {
+ $acid = pdo_fetchcolumn('SELECT acid FROM ' . tablename('account_wechats') . " WHERE uniacid = :id AND level = 4 AND secret != '' AND `key` != ''", array(':id' => $uniacid));
+ pdo_update('uni_settings', array('oauth' => iserializer(array('account' => $acid, 'host' => $oauth['oauth']['host']))), array('uniacid' => $uniacid));
+ }
+ @unlink(IA_ROOT . '/attachment/qrcode_' . $acid . '.jpg');
+ @unlink(IA_ROOT . '/attachment/headimg_' . $acid . '.jpg');
+ file_remote_delete('qrcode_' . $acid . '.jpg');
+ file_remote_delete('headimg_' . $acid . '.jpg');
+ }
+ return $jobid;
+}
+
+
+function account_wechatpay_proxy()
+{
+ global $_W;
+ $proxy_account = cache_load(cache_system_key('proxy_wechatpay_account'));
+ if (empty($proxy_account)) {
+ $proxy_account = cache_build_proxy_wechatpay_account();
+ }
+ unset($proxy_account['borrow'][$_W['uniacid']]);
+ unset($proxy_account['service'][$_W['uniacid']]);
+ return $proxy_account;
+}
+
+
+function uni_account_module_shortcut_enabled($modulename, $status = STATUS_ON)
+{
+ global $_W;
+ $module = module_fetch($modulename);
+ if (empty($module)) {
+ return error(1, '抱歉,你操作的模块不能被访问!');
+ }
+
+ $module_status = pdo_get('uni_account_modules', array('module' => $modulename, 'uniacid' => $_W['uniacid']), array('id', 'shortcut'));
+ if (empty($module_status)) {
+ $data = array(
+ 'uniacid' => $_W['uniacid'],
+ 'module' => $modulename,
+ 'enabled' => STATUS_ON,
+ 'shortcut' => $status ? STATUS_ON : STATUS_OFF,
+ 'settings' => '',
+ );
+ pdo_insert('uni_account_modules', $data);
+ } else {
+ $data = array(
+ 'shortcut' => $status ? STATUS_ON : STATUS_OFF,
+ );
+ pdo_update('uni_account_modules', $data, array('id' => $module_status['id']));
+ }
+ cache_build_module_info($modulename);
+ return true;
+}
+
+
+function uni_account_member_fields($uniacid)
+{
+ if (empty($uniacid)) {
+ return array();
+ }
+ $account_member_fields = pdo_getall('mc_member_fields', array('uniacid' => $uniacid), array(), 'fieldid');
+ $system_member_fields = pdo_getall('profile_fields', array(), array(), 'id');
+ $less_field_indexes = array_diff(array_keys($system_member_fields), array_keys($account_member_fields));
+ if (empty($less_field_indexes)) {
+ foreach ($account_member_fields as &$field) {
+ $field['field'] = $system_member_fields[$field['fieldid']]['field'];
+ }
+ unset($field);
+ return $account_member_fields;
+ }
+
+ $account_member_add_fields = array('uniacid' => $uniacid);
+ foreach ($less_field_indexes as $field_index) {
+ $account_member_add_fields['fieldid'] = $system_member_fields[$field_index]['id'];
+ $account_member_add_fields['title'] = $system_member_fields[$field_index]['title'];
+ $account_member_add_fields['available'] = $system_member_fields[$field_index]['available'];
+ $account_member_add_fields['displayorder'] = $system_member_fields[$field_index]['displayorder'];
+ pdo_insert('mc_member_fields', $account_member_add_fields);
+ $insert_id = pdo_insertid();
+ $account_member_fields[$insert_id]['id'] = $insert_id;
+ $account_member_fields[$insert_id]['field'] = $system_member_fields[$field_index]['field'];
+ $account_member_fields[$insert_id]['fid'] = $system_member_fields[$field_index]['id'];
+ $account_member_fields[$insert_id] = array_merge($account_member_fields[$insert_id], $account_member_add_fields);
+ }
+ return $account_member_fields;
+}
+
+
+function uni_account_global_oauth()
+{
+ load()->model('setting');
+ $oauth = setting_load('global_oauth');
+ $oauth = !empty($oauth['global_oauth']) ? $oauth['global_oauth'] : array();
+ if (!empty($oauth['oauth']['account'])) {
+ $account_exist = uni_fetch($oauth['oauth']['account']);
+ if (empty($account_exist) || is_error($account_exist)) {
+ $oauth['oauth']['account'] = 0;
+ }
+ }
+ return $oauth;
+}
+
+function uni_search_link_account($module_name, $type_sign, $uniacid = 0)
+{
+ global $_W;
+ load()->model('miniapp');
+ load()->model('phoneapp');
+ $module_name = trim($module_name);
+ if (empty($module_name) || empty($type_sign)) {
+ return array();
+ }
+ $all_account_type = uni_account_type();
+ $all_account_type_sign = uni_account_type_sign();
+ if (empty($all_account_type_sign[$type_sign])) {
+ return array();
+ }
+ $owned_account = uni_user_accounts($_W['uid'], $type_sign);
+
+ if (!empty($owned_account)) {
+ foreach ($owned_account as $key => $account) {
+ if (!empty($uniacid) && $account['uniacid'] == $uniacid) {
+ unset($owned_account[$key]);
+ continue;
+ }
+ $account['role'] = permission_account_user_role($_W['uid'], $account['uniacid']);
+ if (!in_array($account['role'], array(ACCOUNT_MANAGE_NAME_OWNER, ACCOUNT_MANAGE_NAME_VICE_FOUNDER, ACCOUNT_MANAGE_NAME_FOUNDER))) {
+ unset($owned_account[$key]);
+ continue;
+ }
+ $account_modules = uni_modules_by_uniacid($account['uniacid']);
+ if (empty($account_modules[$module_name])) {
+ unset($owned_account[$key]);
+ continue;
+ }
+ $type = $all_account_type_sign[$type_sign]['contain_type'][0];
+ $type_info = $all_account_type[$type];
+ if ($account_modules[$module_name][$type_info['module_support_name']] != $type_info['module_support_value']) {
+ unset($owned_account[$key]);
+ continue;
+ }
+ $account_support_version = array_filter($all_account_type, function ($item) {
+ return $item['support_version'];
+ });
+ $account_support_version = array_keys($account_support_version);
+ if (in_array($type, $account_support_version)) {
+ $last_version = miniapp_fetch($account['uniacid']);
+ if (empty($last_version['version']) || empty($last_version['version']['modules']) || !is_array($last_version['version']['modules'])) {
+ unset($owned_account[$key]);
+ continue;
+ }
+ $module_version = array();
+ foreach ($last_version['version']['modules'] as $item) {
+ if (!empty($item['name']) && $item['name'] == $module_name) {
+ $module_version = $item;
+ break;
+ }
+ }
+ if (empty($module_version) || !empty($module_version['account']) || !empty($module_version['uniacid'])) {
+ unset($owned_account[$key]);
+ continue;
+ }
+ }
+ }
+ }
+ return $owned_account;
+}
+
+
+function uni_account_oauth_host()
+{
+ global $_W;
+ $oauth_url = $_W['siteroot'];
+ $unisetting = uni_setting_load();
+ if (!empty($unisetting['bind_domain']) && !empty($unisetting['bind_domain']['domain'])) {
+ $oauth_url = $unisetting['bind_domain']['domain'] . '/';
+ } else {
+ if (!empty($unisetting['oauth']['host'])) {
+ $oauth_url = $unisetting['oauth']['host'] . '/';
+ } else {
+ $global_unisetting = uni_account_global_oauth();
+ $oauth_url = !empty($global_unisetting['oauth']['host']) ? $global_unisetting['oauth']['host'] . '/' : $oauth_url;
+ }
+ }
+ return $oauth_url;
+}
+
+
+function uni_user_see_more_info($user_type, $see_more = false)
+{
+ global $_W;
+ if (empty($user_type)) {
+ return false;
+ }
+ if ($user_type == ACCOUNT_MANAGE_NAME_VICE_FOUNDER && !empty($see_more) || $_W['role'] != $user_type) {
+ return true;
+ }
+
+ return false;
+}
+
+
+function uni_delete_rule($rid, $relate_table_name)
+{
+ global $_W;
+ $rid = intval($rid);
+ if (empty($rid)) {
+ return false;
+ }
+ $allowed_table_names = array('news_reply', 'cover_reply');
+ if (!in_array($relate_table_name, $allowed_table_names)) {
+ return false;
+ }
+ $rule_result = pdo_delete('rule', array('id' => $rid, 'uniacid' => $_W['uniacid']));
+ $rule_keyword_result = pdo_delete('rule_keyword', array('rid' => $rid, 'uniacid' => $_W['uniacid']));
+ if ($rule_result && $rule_keyword_result) {
+ $result = pdo_delete($relate_table_name, array('rid' => $rid));
+ }
+ return $result ? true : false;
+}
+
+function uni_get_account_by_appid($appid, $account_type, $except_uniacid = 0)
+{
+ $type_info = uni_account_type($account_type);
+
+ if (in_array($type_info['type_sign'], array(WEBAPP_TYPE_SIGN, PHONEAPP_TYPE_SIGN))) {
+ return array();
+ }
+ $sql = 'SELECT t.`key`, t.name, a.acid, a.uniacid FROM '
+ . tablename($type_info['table_name'])
+ . 't JOIN ' . tablename('account')
+ . ' a ON t.uniacid = a.uniacid WHERE a.isdeleted != 1';
+
+ if (in_array($type_info['type_sign'], array(BAIDUAPP_TYPE_SIGN, TOUTIAOAPP_TYPE_SIGN))) {
+ $sql .= ' AND t.`appid` = :appid';
+ } else {
+ $sql .= ' AND t.`key` = :appid';
+ }
+ if (!empty($except_uniacid)) {
+ $sql .= ' AND a.uniacid != ' . intval($except_uniacid);
+ }
+
+ $account = pdo_fetch($sql, array(':appid' => $appid));
+ if (!empty($account)) {
+ $account['type_title'] = $type_info['title'];
+
+ if ($type_info['type_sign'] == XZAPP_TYPE_SIGN) {
+ $account['key_title'] = 'ClientId';
+ } else {
+ $account['key_title'] = 'AppId';
+ }
+ }
+ return $account;
+}
\ No newline at end of file
diff --git a/framework/model/attachment.mod.php b/framework/model/attachment.mod.php
new file mode 100644
index 0000000..f4addc5
--- /dev/null
+++ b/framework/model/attachment.mod.php
@@ -0,0 +1,177 @@
+ '杭州数据中心',
+ 'oss-cn-qingdao' => '青岛数据中心',
+ 'oss-cn-beijing' => '北京数据中心',
+ 'oss-cn-hongkong' => '香港数据中心',
+ 'oss-cn-shenzhen' => '深圳数据中心',
+ 'oss-cn-shanghai' => '上海数据中心',
+ 'oss-us-west-1' => '美国硅谷数据中心',
+ );
+ return $bucket_datacenter;
+}
+
+function attachment_newalioss_auth($key, $secret, $bucket, $internal = false){
+ load()->library('oss');
+ $buckets = attachment_alioss_buctkets($key, $secret);
+ $host = $internal ? '-internal.aliyuncs.com' : '.aliyuncs.com';
+ $url = 'http://'.$buckets[$bucket]['location'] . $host;
+ $filename = 'MicroEngine.png';
+ try {
+ $ossClient = new \OSS\OssClient($key, $secret, $url);
+ $ossClient->uploadFile($bucket, $filename, ATTACHMENT_ROOT.'images/global/'.$filename);
+ } catch (\OSS\Core\OssException $e) {
+ return error(1, $e->getMessage());
+ }
+ return 1;
+}
+
+function attachment_alioss_buctkets($key, $secret) {
+ load()->library('oss');
+ $url = 'http://oss-cn-beijing.aliyuncs.com';
+ try {
+ $ossClient = new \OSS\OssClient($key, $secret, $url);
+ } catch(\OSS\Core\OssException $e) {
+ return error(1, $e->getMessage());
+ }
+ try{
+ $bucketlistinfo = $ossClient->listBuckets();
+ } catch(OSS\OSS_Exception $e) {
+ return error(1, $e->getMessage());
+ }
+ $bucketlistinfo = $bucketlistinfo->getBucketList();
+ $bucketlist = array();
+ foreach ($bucketlistinfo as &$bucket) {
+ $bucketlist[$bucket->getName()] = array('name' => $bucket->getName(), 'location' => $bucket->getLocation());
+ }
+ return $bucketlist;
+}
+
+function attachment_qiniu_auth($key, $secret,$bucket) {
+ load()->library('qiniu');
+ $auth = new Qiniu\Auth($key, $secret);
+ $token = $auth->uploadToken($bucket);
+ $config = new Qiniu\Config();
+ $uploadmgr = new Qiniu\Storage\UploadManager($config);
+ list($ret, $err) = $uploadmgr->putFile($token, 'MicroEngine.png', ATTACHMENT_ROOT.'images/global/MicroEngine.png');
+ if ($err !== null) {
+ $err = (array)$err;
+ $err = (array)array_pop($err);
+ $err = json_decode($err['body'], true);
+ return error(-1, $err);
+ } else {
+ return true;
+ }
+}
+function attachment_cos_auth($bucket,$appid, $key, $secret, $bucket_local = '') {
+ if (!is_numeric($appid)) {
+ return error(-1, '传入appid值不合法, 请重新输入');
+ }
+ if (!preg_match('/^[a-zA-Z0-9]{36}$/', $key)) {
+ return error(-1, '传入secretid值不合法,请重新传入');
+ }
+ if (!preg_match('/^[a-zA-Z0-9]{32}$/', $secret)) {
+ return error(-1, '传入secretkey值不合法,请重新传入');
+ }
+ load()->library('cosv5');
+ try {
+ $cosClient = new Qcloud\Cos\Client(
+ array(
+ 'region' => $bucket_local,
+ 'credentials'=> array(
+ 'secretId' => $key,
+ 'secretKey' => $secret)));
+ $cosClient->Upload($bucket . '-' . $appid, 'MicroEngine.png', fopen(ATTACHMENT_ROOT . 'images/global/MicroEngine.png', 'rb'));
+ } catch (\Exception $e) {
+ return error(-1, $e->getMessage());
+ }
+ return true;
+}
+
+
+function attachment_reset_uniacid($uniacid) {
+ global $_W;
+ if ($_W['role'] == ACCOUNT_MANAGE_NAME_FOUNDER) {
+ if (empty($uniacid)) {
+ $_W['uniacid'] = 0;
+ } elseif ($uniacid > 0) {
+ $_W['uniacid'] = $uniacid;
+ }
+ } else {
+
+ $account = table('account');
+ $accounts = $account->userOwnedAccount($_W['uid']);
+ if (is_array($accounts) && isset($accounts[$uniacid])) {
+ $_W['uniacid'] = $uniacid;
+ }
+ }
+ return true;
+}
+
+
+function attachment_replace_article_remote_url($old_url, $new_url) {
+ if (empty($old_url) || empty($new_url) || $old_url == $new_url) {
+ return false;
+ }
+ $content_exists = pdo_get('article_news', array('content LIKE' => "%{$old_url}%"));
+ if (!empty($content_exists)) {
+ $update_sql = "UPDATE " . tablename('article_news') . " SET `content`=REPLACE(content, :old_url, :new_url)";
+ return pdo_query($update_sql, array(':old_url' => $old_url, ':new_url' => $new_url));
+ }
+}
+
+
+function attachment_recursion_group($group_data = array(), $pid = 0) {
+ if (empty($group_data)) return array();
+ $return_data = array();
+ foreach ($group_data as $key => $group_data_value) {
+ if($group_data_value['pid'] == $pid){
+ $return_data[$group_data_value['id']] = $group_data_value;
+ $sub_group = attachment_recursion_group($group_data, $group_data_value['id']);
+ if (0 == $pid) {
+ $return_data[$group_data_value['id']]['sub_group'] = !empty($sub_group) ? $sub_group : array();
+ }
+ }
+ }
+ return $return_data;
+}
+
+
+function attachment_get_type($type_sign) {
+ $attach_type = array(
+ ATTACH_FTP => 'ftp',
+ ATTACH_OSS => 'alioss',
+ ATTACH_QINIU => 'qiniu',
+ ATTACH_COS => 'cos',
+ );
+ return !empty($attach_type[$type_sign]) ? $attach_type[$type_sign] : '';
+}
\ No newline at end of file
diff --git a/framework/model/cache.mod.php b/framework/model/cache.mod.php
new file mode 100644
index 0000000..4a616a2
--- /dev/null
+++ b/framework/model/cache.mod.php
@@ -0,0 +1,505 @@
+func('file');
+ rmdirs(IA_ROOT . '/data/tpl', true);
+}
+
+
+function cache_build_setting()
+{
+ $setting = table('core_settings')->getall('key');
+ if (is_array($setting)) {
+ foreach ($setting as $k => $v) {
+ $setting[$v['key']] = iunserializer($v['value']);
+ }
+ cache_write(cache_system_key('setting'), $setting);
+ }
+}
+
+
+function cache_build_account_modules($uniacid = 0, $uid = 0)
+{
+ load()->model('phoneapp');
+ load()->model('miniapp');
+ $uniacid = intval($uniacid);
+ if (empty($uniacid)) {
+ cache_clean(cache_system_key('unimodules'));
+ if (!empty($uid)) {
+ cache_delete(cache_system_key('user_modules', array('uid' => $uid)));
+ } else {
+ cache_clean(cache_system_key('user_modules'));
+ }
+ return true;
+ } else {
+ cache_clean(cache_system_key('unimodules', array('uniacid' => $uniacid)));
+ if (empty($uid)) {
+ $uid = table('uni_account_users')->getUidByUniacidAndRole($uniacid, 'owner');
+ }
+ cache_delete(cache_system_key('user_modules', array('uid' => $uid)));
+ }
+ $account_info = uni_fetch($uniacid);
+ if (is_error($account_info)) {
+ return false;
+ }
+
+ $uni_modules_new = uni_modules_by_uniacid($uniacid);
+ $module_system = module_system();
+ foreach ($uni_modules_new as $uni_module_new_key => $uni_module_new_val) {
+ if (in_array($uni_module_new_key, $module_system)) {
+ unset($uni_modules_new[$uni_module_new_key]);
+ } elseif ($account_info->typeSign == 'wxapp' && $uni_module_new_val[MODULE_SUPPORT_WXAPP_NAME] != MODULE_SUPPORT_WXAPP) {
+ unset($uni_modules_new[$uni_module_new_key]);
+ }
+ }
+ $uni_modules_new = array_keys($uni_modules_new);
+
+ if ($account_info->supportVersion) {
+ $version_modules = array();
+ if ($account_info['type'] == ACCOUNT_TYPE_PHONEAPP_NORMAL) {
+ $version_all = phoneapp_version_all($uniacid);
+ }
+ if (in_array($account_info['type'], array(ACCOUNT_TYPE_APP_NORMAL, ACCOUNT_TYPE_APP_AUTH))) {
+ $version_all = miniapp_version_all($uniacid);
+ }
+ if (!empty($version_all)) {
+ foreach ($version_all as $version_key => $version_val) {
+ if (empty($version_val['modules'])) {
+ continue;
+ }
+ foreach ($version_val['modules'] as $module_name => $module_info) {
+ $version_modules[] = $module_name;
+ }
+ }
+ }
+ foreach ($uni_modules_new as $uni_module_key => $uni_module_val) {
+ if (empty($uni_module_val)) {
+ continue;
+ }
+ if (empty($version_modules) || !in_array($uni_module_val, $version_modules)) {
+ pdo_delete('users_lastuse', array('uniacid' => $uniacid, 'modulename' => $uni_module_val));
+ }
+ }
+ }
+
+ $uni_account_modules = table('uni_modules')->getallByUniacid($uniacid);
+ $uni_account_modules = array_column($uni_account_modules, 'module_name');
+
+ $uni_modules_add = array_diff($uni_modules_new, $uni_account_modules);
+ $uni_modules_delete = array_diff($uni_account_modules, $uni_modules_new);
+
+ $users_lastuse_table = table('users_lastuse');
+ $users_lastuse_table->searchWithUniacid($uniacid);
+ $uni_modules_default_list = $users_lastuse_table->getall('modulename');
+ $uni_modules_default_delete = array_diff(array_keys($uni_modules_default_list), $uni_modules_new);
+ if (!empty($uni_modules_default_delete)) {
+ foreach ($uni_modules_default_delete as $module_default_delete_name) {
+ if (empty($module_default_delete_name)) {
+ continue;
+ }
+ pdo_delete('users_lastuse', array('uniacid' => $uniacid, 'modulename' => $module_default_delete_name));
+ }
+ }
+
+ if (!empty($uni_modules_add)) {
+ foreach ($uni_modules_add as $module_add_name) {
+ $account_modules_data = array('uniacid' => $uniacid, 'module_name' => $module_add_name);
+ pdo_insert('uni_modules', $account_modules_data);
+ }
+ }
+
+ if (!empty($uni_modules_delete)) {
+ foreach ($uni_modules_delete as $mdoule_delete_name) {
+ pdo_delete('uni_modules', array('uniacid' => $uniacid, 'module_name' => $mdoule_delete_name));
+ }
+ }
+
+ $modules_rank_table = table('modules_rank');
+ $modules_rank_list = $modules_rank_table->getModuleListByUidAndUniacid();
+ $modules_rank_list = array_keys($modules_rank_list);
+ $modules_rank_add = array_diff($uni_account_modules, $modules_rank_list);
+ $modules_rank_delete = array_diff($modules_rank_list, $uni_account_modules);
+ asort($modules_rank_add);
+ asort($modules_rank_delete);
+
+ if (!empty($modules_rank_add)) {
+ foreach ($modules_rank_add as $uni_account_module_key => $uni_account_module_name) {
+ $modules_rank_data = array('uid' => $uid, 'uniacid' => $uniacid, 'module_name' => $uni_account_module_name, 'rank' => $uni_account_module_key);
+ pdo_insert('modules_rank', $modules_rank_data);
+ }
+ }
+
+ if (!empty($modules_rank_delete)) {
+ foreach ($modules_rank_delete as $uni_account_module_name) {
+ $modules_rank_data = array('uid' => $uid, 'uniacid' => $uniacid, 'module_name' => $uni_account_module_name);
+ pdo_delete('modules_rank', $modules_rank_data);
+ }
+ }
+ return true;
+}
+
+
+function cache_build_account($uniacid = 0)
+{
+ $uniacid = intval($uniacid);
+ if (empty($uniacid)) {
+ $uniacid_arr = table('account')->getAll();
+ foreach ($uniacid_arr as $account) {
+ cache_delete(cache_system_key('uniaccount', array('uniacid' => $account['uniacid'])));
+ cache_delete(cache_system_key('defaultgroupid', array('uniacid' => $account['uniacid'])));
+ }
+ } else {
+ cache_delete(cache_system_key('uniaccount', array('uniacid' => $uniacid)));
+ cache_delete(cache_system_key('defaultgroupid', array('uniacid' => $uniacid)));
+ }
+ return true;
+}
+
+
+function cache_build_memberinfo($uid)
+{
+ $uid = intval($uid);
+ cache_delete(cache_system_key('memberinfo', array('uid' => $uid)));
+ return true;
+}
+
+
+function cache_build_users_struct()
+{
+ $base_fields = array(
+ 'uniacid' => '同一公众号id',
+ 'groupid' => '分组id',
+ 'credit1' => '积分',
+ 'credit2' => '余额',
+ 'credit3' => '预留积分类型3',
+ 'credit4' => '预留积分类型4',
+ 'credit5' => '预留积分类型5',
+ 'credit6' => '预留积分类型6',
+ 'createtime' => '加入时间',
+ 'mobile' => '手机号码',
+ 'email' => '电子邮箱',
+ 'realname' => '真实姓名',
+ 'nickname' => '昵称',
+ 'avatar' => '头像',
+ 'qq' => 'QQ号',
+ 'gender' => '性别',
+ 'birth' => '生日',
+ 'constellation' => '星座',
+ 'zodiac' => '生肖',
+ 'telephone' => '固定电话',
+ 'idcard' => '证件号码',
+ 'studentid' => '学号',
+ 'grade' => '班级',
+ 'address' => '地址',
+ 'zipcode' => '邮编',
+ 'nationality' => '国籍',
+ 'reside' => '居住地',
+ 'graduateschool' => '毕业学校',
+ 'company' => '公司',
+ 'education' => '学历',
+ 'occupation' => '职业',
+ 'position' => '职位',
+ 'revenue' => '年收入',
+ 'affectivestatus' => '情感状态',
+ 'lookingfor' => ' 交友目的',
+ 'bloodtype' => '血型',
+ 'height' => '身高',
+ 'weight' => '体重',
+ 'alipay' => '支付宝帐号',
+ 'msn' => 'MSN',
+ 'taobao' => '阿里旺旺',
+ 'site' => '主页',
+ 'bio' => '自我介绍',
+ 'interest' => '兴趣爱好',
+ 'password' => '密码',
+ 'pay_password' => '支付密码',
+ );
+ cache_write(cache_system_key('userbasefields'), $base_fields);
+ $fields = table('core_profile_fields')->getall('field');
+ if (!empty($fields)) {
+ foreach ($fields as &$field) {
+ $field = $field['title'];
+ }
+ $fields['uniacid'] = '同一公众号id';
+ $fields['groupid'] = '分组id';
+ $fields['credit1'] = '积分';
+ $fields['credit2'] = '余额';
+ $fields['credit3'] = '预留积分类型3';
+ $fields['credit4'] = '预留积分类型4';
+ $fields['credit5'] = '预留积分类型5';
+ $fields['credit6'] = '预留积分类型6';
+ $fields['createtime'] = '加入时间';
+ $fields['password'] = '用户密码';
+ $fields['pay_password'] = '支付密码';
+ cache_write(cache_system_key('usersfields'), $fields);
+ } else {
+ cache_write(cache_system_key('usersfields'), $base_fields);
+ }
+}
+
+function cache_build_frame_menu()
+{
+ global $_W;
+ load()->model('system');
+ $system_menu = system_menu();
+ if (!empty($system_menu) && is_array($system_menu)) {
+ $system_menu = iarray_sort($system_menu, 'displayorder', 'asc');
+ cache_delete(cache_system_key('system_frame', array('uniacid' => $_W['uniacid'])));
+ cache_write(cache_system_key('system_frame', array('uniacid' => $_W['uniacid'])), $system_menu);
+ return $system_menu;
+ }
+}
+
+function cache_build_module_subscribe_type()
+{
+ global $_W;
+ $modules = table('modules')->getByHasSubscribes();
+ if (empty($modules)) {
+ return array();
+ }
+ $subscribe = array();
+ foreach ($modules as $module) {
+ $module['subscribes'] = iunserializer($module['subscribes']);
+ if (!empty($module['subscribes'])) {
+ foreach ($module['subscribes'] as $event) {
+ if ($event == 'text') {
+ continue;
+ }
+ $subscribe[$event][] = $module['name'];
+ }
+ }
+ }
+
+ $module_ban = $_W['setting']['module_receive_ban'];
+ foreach ($subscribe as $event => $module_group) {
+ if (!empty($module_group)) {
+ foreach ($module_group as $index => $module) {
+ if (!empty($module_ban[$module])) {
+ unset($subscribe[$event][$index]);
+ }
+ }
+ }
+ }
+ cache_write(cache_system_key('module_receive_enable'), $subscribe);
+ return $subscribe;
+}
+
+
+function cache_build_cloud_ad()
+{
+ global $_W;
+ $uniacid_arr = table('account')->getAll();
+ foreach ($uniacid_arr as $account) {
+ cache_delete(cache_system_key('stat_todaylock', array('uniacid' => $account['uniacid'])));
+ cache_delete(cache_system_key('cloud_ad_uniaccount', array('uniacid' => $account['uniacid'])));
+ cache_delete(cache_system_key('cloud_ad_app_list', array('uniacid' => $account['uniacid'])));
+ }
+ cache_delete(cache_system_key('cloud_flow_master'));
+ cache_delete(cache_system_key('cloud_ad_uniaccount_list'));
+ cache_delete(cache_system_key('cloud_ad_tags'));
+ cache_delete(cache_system_key('cloud_ad_type_list'));
+ cache_delete(cache_system_key('cloud_ad_app_support_list'));
+ cache_delete(cache_system_key('cloud_ad_site_finance'));
+}
+
+
+function cache_build_uninstalled_module()
+{
+ $modulelist = table('modules')->getall('name');
+
+ $module_root = IA_ROOT . '/addons/';
+ $module_path_list = glob($module_root . '/*');
+ if (empty($module_path_list)) {
+ return true;
+ }
+ $module_support_type = module_support_type();
+
+ foreach ($module_path_list as $path) {
+ $modulename = pathinfo($path, PATHINFO_BASENAME);
+ $module_recycle_info = table('modules_recycle')->searchWithNameType($modulename, MODULE_RECYCLE_UNINSTALL_IGNORE)->get();
+
+ if (!empty($modulelist[$modulename])) {
+ $module_cloud_upgrade = table('modules_cloud')->getByName($modulename);
+ if (!empty($module_cloud_upgrade)) {
+ $has_new_support = false;
+ $installed_support = array();
+ foreach (module_support_type() as $support => $value) {
+ if (!empty($module_recycle_info) && $module_recycle_info[$support] == 1) {
+ $installed_support[$support] = $value['not_support'];
+ }
+ if ($module_cloud_upgrade[$support] == $value['support'] && $modulelist[$modulename][$support] != $value['support']) {
+ if ($has_new_support == false) {
+ $has_new_support = true;
+ }
+ } else {
+ $installed_support[$support] = $value['not_support'];
+ }
+ }
+ if (empty($has_new_support)) {
+ table('modules_cloud')->deleteByName($modulename);
+ } else {
+ $installed_support['install_status'] = MODULE_CLOUD_UNINSTALL;
+ table('modules_cloud')->fill($installed_support)->where('id', $module_cloud_upgrade['id'])->save();
+ }
+ }
+ }
+
+ if (!is_dir($path) || !file_exists($path . '/manifest.xml')) {
+ continue;
+ }
+ $manifest = ext_module_manifest($modulename);
+ $module_upgrade_data = array(
+ 'name' => $modulename,
+ 'has_new_version' => 0,
+ 'has_new_branch' => 0,
+ 'install_status' => MODULE_LOCAL_UNINSTALL,
+ 'logo' => $manifest['application']['logo'],
+ 'version' => $manifest['application']['version'],
+ 'title' => $manifest['application']['name'],
+ 'title_initial' => get_first_pinyin($manifest['application']['name']),
+ );
+
+ if (!empty($manifest['platform']['supports'])) {
+ foreach (array('app', 'wxapp', 'webapp', 'android', 'ios', 'system_welcome', 'aliapp', 'baiduapp', 'toutiaoapp') as $support) {
+ if (in_array($support, $manifest['platform']['supports'])) {
+ if ($support == 'app') {
+ $support = 'account';
+ }
+ if ($support == 'system_welcome') {
+ $support = 'welcome';
+ }
+ if ($support == 'android' || $support == 'ios') {
+ $support = 'phoneapp';
+ }
+ $module_upgrade_data["{$support}_support"] = MODULE_SUPPORT_ACCOUNT;
+ }
+ }
+ }
+
+ if (!empty($modulelist[$modulename])) {
+ $new_support = module_check_notinstalled_support($modulelist[$modulename], $manifest['platform']['supports']);
+ if (!empty($new_support)) {
+ $module_upgrade_data = array_merge($module_upgrade_data, $new_support);
+ } else {
+ table('modules_cloud')->deleteByName($modulename);
+ continue;
+ }
+ }
+
+ if (!empty($module_recycle_info)) {
+ foreach ($module_support_type as $support => $value) {
+ if ($module_recycle_info[$support] == 1) {
+ $module_upgrade_data[$support] = $value['not_support'];
+ }
+ }
+ }
+ $module_cloud_upgrade = table('modules_cloud')->getByName($modulename);
+ if (empty($module_cloud_upgrade)) {
+ table('modules_cloud')->fill($module_upgrade_data)->save();
+ } else {
+ table('modules_cloud')->fill($module_upgrade_data)->where('name', $modulename)->save();
+ }
+ }
+ return true;
+}
+
+
+function cache_build_proxy_wechatpay_account()
+{
+ global $_W;
+ load()->model('account');
+ $account_table = table('account');
+ if ($_W['isadmin']) {
+ $uniaccounts = pdo_getall('account', array('type IN ' => array(ACCOUNT_TYPE_OFFCIAL_NORMAL, ACCOUNT_TYPE_OFFCIAL_AUTH)));
+ } else {
+ $uniaccounts = $account_table->userOwnedAccount($_W['uid']);
+ }
+ $service = array();
+ $borrow = array();
+ if (!empty($uniaccounts)) {
+ foreach ($uniaccounts as $uniaccount) {
+ if (!in_array($uniaccount['type'], array(ACCOUNT_TYPE_OFFCIAL_NORMAL, ACCOUNT_TYPE_OFFCIAL_AUTH))) {
+ continue;
+ }
+ $account = uni_fetch($uniaccount['uniacid']);
+ $payment = (array)$account['setting']['payment'];
+ if (!empty($account['key']) && !empty($account['secret']) && in_array($account['level'], array(4)) &&
+ is_array($payment) && !empty($payment) && intval($payment['wechat']['switch']) == 1) {
+ if ((!is_bool($payment['wechat']['switch']) && $payment['wechat']['switch'] != 4) || (is_bool($payment['wechat']['switch']) && !empty($payment['wechat']['switch']))) {
+ $borrow[$account['uniacid']] = $account['name'];
+ }
+ }
+ if (!empty($payment['wechat_facilitator']['switch'])) {
+ $service[$account['uniacid']] = $account['name'];
+ }
+ }
+ }
+ $cache = array(
+ 'service' => $service,
+ 'borrow' => $borrow
+ );
+ cache_write(cache_system_key('proxy_wechatpay_account'), $cache);
+ return $cache;
+}
+
+
+function cache_build_module_info($module_name)
+{
+ global $_W;
+ table('modules_cloud')->deleteByName($module_name);
+ cache_delete(cache_system_key('module_info', array('module_name' => $module_name)));
+}
+
+
+function cache_build_uni_group()
+{
+ $uni_group_cache_key = cache_system_key('uni_groups', array());
+ $cache_keys = cache_search($uni_group_cache_key);
+ if (!empty($cache_keys)) {
+ foreach ($cache_keys as $cache_key => $cache_value) {
+ cache_delete($cache_key);
+ }
+ }
+}
+
+
+function cache_random($length = 4, $direct_write = false)
+{
+ $cachekey = cache_system_key('random');
+ $cache = cache_load($cachekey);
+ if ($cache && !$direct_write) {
+ return $cache;
+ }
+ $result = random($length);
+ cache_write($cachekey, $result, CACHE_EXPIRE_MIDDLE);
+ return $result;
+}
+
+function cache_updatecache()
+{
+ $account_ticket_cache = cache_read(cache_system_key('account_ticket'));
+ pdo_delete('core_cache');
+ cache_clean();
+ cache_write(cache_system_key('account_ticket'), $account_ticket_cache);
+
+ setting_save(array(), 'cloudip');
+ cache_build_template();
+ cache_build_users_struct();
+ cache_build_setting();
+ cache_build_module_subscribe_type();
+ rmdirs(IA_ROOT . '/data/patch/upgrade/');
+ rmdirs(IA_ROOT . '/data/tpl/web/');
+ rmdirs(IA_ROOT . '/data/tpl/app/');
+ $path = IA_ROOT . '/data/';
+ if ($dir = opendir($path)) {
+ while (false !== ($file = readdir($dir))) {
+ if (is_file($path . '/' . $file) && (strpos($file, 'application.build') === 0) || strpos($file, 'module.info') === 0) {
+ @unlink($path . '/' . $file);
+ }
+ }
+ }
+ pdo_delete('modules_cloud');
+ return true;
+}
diff --git a/framework/model/extension.mod.php b/framework/model/extension.mod.php
new file mode 100644
index 0000000..c36c0e3
--- /dev/null
+++ b/framework/model/extension.mod.php
@@ -0,0 +1,698 @@
+ $manifest['application']['identifie'],
+ 'title' => $manifest['application']['name'],
+ 'version' => $manifest['application']['version'],
+ 'type' => $manifest['application']['type'],
+ 'ability' => $manifest['application']['ability'],
+ 'description' => $manifest['application']['description'],
+ 'author' => $manifest['application']['author'],
+ 'url' => $manifest['application']['url'],
+ 'settings' => intval($manifest['application']['setting']),
+ 'subscribes' => iserializer(is_array($manifest['platform']['subscribes']) ? $manifest['platform']['subscribes'] : array()),
+ 'handles' => iserializer(is_array($manifest['platform']['handles']) ? $manifest['platform']['handles'] : array()),
+ 'isrulefields' => intval($manifest['platform']['isrulefields']),
+ 'iscard' => intval($manifest['platform']['iscard']),
+ 'oauth_type' => $manifest['platform']['oauth_type'],
+ 'page' => $manifest['bindings']['page'],
+ 'cover' => $manifest['bindings']['cover'],
+ 'rule' => $manifest['bindings']['rule'],
+ 'menu' => $manifest['bindings']['menu'],
+ 'home' => $manifest['bindings']['home'],
+ 'profile' => $manifest['bindings']['profile'],
+ 'system_welcome' => $manifest['bindings']['system_welcome'],
+ 'webapp' => $manifest['bindings']['webapp'],
+ 'phoneapp' => $manifest['bindings']['phoneapp'],
+ MODULE_SUPPORT_ACCOUNT_NAME => $app_support,
+ 'wxapp_support' => $wxapp_support,
+ 'webapp_support' => $webapp_support,
+ 'phoneapp_support' => $phoneapp_support,
+ 'aliapp_support' => $aliapp_support,
+ 'baiduapp_support' => $baiduapp_support,
+ 'toutiaoapp_support' => $toutiaoapp_support,
+ 'welcome_support' => $welcome_support,
+ 'shortcut' => $manifest['bindings']['shortcut'],
+ 'function' => $manifest['bindings']['function'],
+ 'permissions' => $manifest['permissions'],
+ 'issystem' => 0,
+ 'application_type' => 1
+ );
+}
+
+
+function ext_module_manifest_parse($xml) {
+ if (!strexists($xml, 'loadXML($xml);
+ $root = $dom->getElementsByTagName('manifest')->item(0);
+ if (empty($root)) {
+ return array();
+ }
+ $vcode = explode(',', $root->getAttribute('versionCode'));
+ $manifest['versions'] = array();
+ if (is_array($vcode)) {
+ foreach ($vcode as $v) {
+ $v = trim($v);
+ if (!empty($v)) {
+ $manifest['versions'][] = $v;
+ }
+ }
+ $manifest['versions'][] = '0.52';
+ $manifest['versions'][] = '0.6';
+ $manifest['versions'] = array_unique($manifest['versions']);
+ }
+ $manifest['install'] = $root->getElementsByTagName('install')->item(0)->textContent;
+ $manifest['uninstall'] = $root->getElementsByTagName('uninstall')->item(0)->textContent;
+ $manifest['upgrade'] = $root->getElementsByTagName('upgrade')->item(0)->textContent;
+ $application = $root->getElementsByTagName('application')->item(0);
+ if (empty($application)) {
+ return array();
+ }
+ $manifest['application'] = array(
+ 'name' => trim($application->getElementsByTagName('name')->item(0)->textContent),
+ 'identifie' => trim($application->getElementsByTagName('identifie')->item(0)->textContent),
+ 'version' => trim($application->getElementsByTagName('version')->item(0)->textContent),
+ 'type' => trim($application->getElementsByTagName('type')->item(0)->textContent),
+ 'ability' => trim($application->getElementsByTagName('ability')->item(0)->textContent),
+ 'description' => trim($application->getElementsByTagName('description')->item(0)->textContent),
+ 'author' => trim($application->getElementsByTagName('author')->item(0)->textContent),
+ 'url' => trim($application->getElementsByTagName('url')->item(0)->textContent),
+ 'setting' => trim($application->getAttribute('setting')) == 'true',
+ );
+ $platform = $root->getElementsByTagName('platform')->item(0);
+ if (!empty($platform)) {
+ $manifest['platform'] = array(
+ 'subscribes' => array(),
+ 'handles' => array(),
+ 'isrulefields' => false,
+ 'iscard' => false,
+ 'supports' => array(),
+ 'oauth_type' => OAUTH_TYPE_BASE,
+ );
+ $subscribes = $platform->getElementsByTagName('subscribes')->item(0);
+ if (!empty($subscribes)) {
+ $messages = $subscribes->getElementsByTagName('message');
+ for ($i = 0; $i < $messages->length; $i++) {
+ $t = $messages->item($i)->getAttribute('type');
+ if (!empty($t)) {
+ $manifest['platform']['subscribes'][] = $t;
+ }
+ }
+ }
+ $handles = $platform->getElementsByTagName('handles')->item(0);
+ if (!empty($handles)) {
+ $messages = $handles->getElementsByTagName('message');
+ for ($i = 0; $i < $messages->length; $i++) {
+ $t = $messages->item($i)->getAttribute('type');
+ if (!empty($t)) {
+ $manifest['platform']['handles'][] = $t;
+ }
+ }
+ }
+ $rule = $platform->getElementsByTagName('rule')->item(0);
+ if (!empty($rule) && $rule->getAttribute('embed') == 'true') {
+ $manifest['platform']['isrulefields'] = true;
+ }
+ $card = $platform->getElementsByTagName('card')->item(0);
+ if (!empty($card) && $card->getAttribute('embed') == 'true') {
+ $manifest['platform']['iscard'] = true;
+ }
+ $oauth_type = $platform->getElementsByTagName('oauth')->item(0);
+ if (!empty($oauth_type) && $oauth_type->getAttribute('type') == OAUTH_TYPE_USERINFO) {
+ $manifest['platform']['oauth_type'] = OAUTH_TYPE_USERINFO;
+ }
+ $supports = $platform->getElementsByTagName('supports')->item(0);
+ if (!empty($supports)) {
+ $support_type = $supports->getElementsByTagName('item');
+ for ($i = 0; $i < $support_type->length; $i++) {
+ $t = $support_type->item($i)->getAttribute('type');
+ if (!empty($t)) {
+ $manifest['platform']['supports'][] = $t;
+ }
+ }
+ }
+ $plugins = $platform->getElementsByTagName('plugins')->item(0);
+ if (!empty($plugins)) {
+ $plugin_list = $plugins->getElementsByTagName('item');
+ for ($i = 0; $i < $plugin_list->length; $i++) {
+ $plugin = $plugin_list->item($i)->getAttribute('name');
+ if (!empty($plugin)) {
+ $manifest['platform']['plugin_list'][] = $plugin;
+ }
+ }
+ }
+ $plugin_main = $platform->getElementsByTagName('plugin-main')->item(0);
+ if (!empty($plugin_main)) {
+ $plugin_main = $plugin_main->getAttribute('name');
+ if (!empty($plugin_main)) {
+ $manifest['platform']['main_module'] = $plugin_main;
+ }
+ }
+ }
+ $bindings = $root->getElementsByTagName('bindings')->item(0);
+ if (!empty($bindings)) {
+ $points = ext_module_bindings();
+ if (!empty($points)) {
+ $ps = array_keys($points);
+ $manifest['bindings'] = array();
+ foreach ($ps as $p) {
+ $define = $bindings->getElementsByTagName($p)->item(0);
+ $manifest['bindings'][$p] = _ext_module_manifest_entries($define);
+ }
+ }
+ }
+ $permissions = $root->getElementsByTagName('permissions')->item(0);
+ if (!empty($permissions)) {
+ $manifest['permissions'] = array();
+ $items = $permissions->getElementsByTagName('entry');
+ for ($i = 0; $i < $items->length; $i++) {
+ $item = $items->item($i);
+ $row = array(
+ 'title' => $item->getAttribute('title'),
+ 'permission' => $item->getAttribute('do'),
+ );
+ if (!empty($row['title']) && !empty($row['permission'])) {
+ $manifest['permissions'][] = $row;
+ }
+ }
+ }
+ return $manifest;
+}
+
+
+function ext_module_manifest($modulename) {
+ $root = IA_ROOT . '/addons/' . $modulename;
+ $filename = $root . '/manifest.xml';
+ if (!file_exists($filename)) {
+ return array();
+ }
+ $xml = file_get_contents($filename);
+ $xml = ext_module_manifest_parse($xml);
+
+ if (!empty($xml)) {
+ $xml['application']['logo'] = tomedia($root . '/icon.jpg');
+ if (file_exists($root . '/preview-custom.jpg')) {
+ $xml['application']['preview'] = tomedia($root . '/preview-custom.jpg');
+ } else {
+ $xml['application']['preview'] = tomedia($root . '/preview.jpg');
+ }
+ if (empty($xml['platform']['supports'])) {
+ $xml['platform']['supports'][] = 'app';
+ }
+ }
+ return $xml;
+}
+
+
+function _ext_module_manifest_entries($elm) {
+ $ret = array();
+ if (!empty($elm)) {
+ $call = $elm->getAttribute('call');
+ if (!empty($call)) {
+ $ret[] = array('call' => $call);
+ }
+ $entries = $elm->getElementsByTagName('entry');
+ for ($i = 0; $i < $entries->length; $i++) {
+ $entry = $entries->item($i);
+ $direct = $entry->getAttribute('direct');
+ $is_multilevel_menu = $entry->getAttribute('multilevel');
+ $row = array(
+ 'title' => $entry->getAttribute('title'),
+ 'do' => $entry->getAttribute('do'),
+ 'direct' => !empty($direct) && $direct != 'false' ? true : false,
+ 'state' => $entry->getAttribute('state'),
+ 'icon' => $entry->getAttribute('icon'),
+ 'displayorder' => $entry->getAttribute('displayorder'),
+ 'multilevel' => !empty($is_multilevel_menu) && $is_multilevel_menu == 'true' ? true : false,
+ 'parent' => $entry->getAttribute('parent'),
+ );
+ if (!empty($row['title']) && !empty($row['do'])) {
+ $ret[$row['do']] = $row;
+ }
+ }
+ }
+ return $ret;
+}
+
+
+function ext_module_bindings() {
+ static $bindings = array(
+ 'cover' => array(
+ 'name' => 'cover',
+ 'title' => '功能封面',
+ 'desc' => '功能封面是定义微站里一个独立功能的入口(手机端操作), 将呈现为一个图文消息, 点击后进入微站系统中对应的功能.'
+ ),
+ 'rule' => array(
+ 'name' => 'rule',
+ 'title' => '规则列表',
+ 'desc' => '规则列表是定义可重复使用或者可创建多次的活动的功能入口(管理后台Web操作), 每个活动对应一条规则. 一般呈现为图文消息, 点击后进入定义好的某次活动中.'
+ ),
+ 'menu' => array(
+ 'name' => 'menu',
+ 'title' => '管理中心导航菜单',
+ 'desc' => '管理中心导航菜单将会在管理中心生成一个导航入口(管理后台Web操作), 用于对模块定义的内容进行管理.'
+ ),
+ 'home' => array(
+ 'name' => 'home',
+ 'title' => '微站首页导航图标',
+ 'desc' => '在微站的首页上显示相关功能的链接入口(手机端操作), 一般用于通用功能的展示.'
+ ),
+ 'profile'=> array(
+ 'name' => 'profile',
+ 'title' => '微站个人中心导航',
+ 'desc' => '在微站的个人中心上显示相关功能的链接入口(手机端操作), 一般用于个人信息, 或针对个人的数据的展示.'
+ ),
+ 'shortcut'=> array(
+ 'name' => 'shortcut',
+ 'title' => '微站快捷功能导航',
+ 'desc' => '在微站的快捷菜单上展示相关功能的链接入口(手机端操作), 仅在支持快捷菜单的微站模块上有效.'
+ ),
+ 'function'=> array(
+ 'name' => 'function',
+ 'title' => '微站独立功能',
+ 'desc' => '需要特殊定义的操作, 一般用于将指定的操作指定为(direct). 如果一个操作没有在具体位置绑定, 但是需要定义为(direct: 直接访问), 可以使用这个嵌入点'
+ ),
+ 'page'=> array(
+ 'name' => 'page',
+ 'title' => '小程序入口',
+ 'desc' => '用于小程序入口的链接'
+ ),
+ 'system_welcome' => array(
+ 'name' => 'system_welcome',
+ 'title' => '系统首页导航菜单',
+ 'desc' => '系统首页导航菜单将会在管理中心生成一个导航入口, 用于对系统首页定义的内容进行管理.',
+ ),
+ 'webapp' => array(
+ 'name' => 'webapp',
+ 'title' => 'PC入口',
+ 'desc' => '用于PC入口的链接',
+ ),
+ 'phoneapp' => array(
+ 'name' => 'phoneapp',
+ 'title' => 'APP入口',
+ 'desc' => '用于APP入口的链接',
+ )
+ );
+ return $bindings;
+}
+
+
+function ext_module_clean($modulename, $is_clean_rule = false) {
+ pdo_delete('core_queue', array('module' => $modulename));
+
+ table('modules')->deleteByName($modulename);
+ table('modules_bindings')->deleteByName($modulename);
+ pdo_delete('modules_plugin', array('main_module' => $modulename));
+
+ if ($is_clean_rule) {
+ pdo_delete('rule', array('module' => $modulename));
+ pdo_delete('rule_keyword', array('module' => $modulename));
+
+ $cover_list = pdo_getall('cover_reply', array('module' => $modulename), array('rid'), 'rid');
+ if (!empty($cover_list)) {
+ $rids = array_keys($cover_list);
+ pdo_delete('rule_keyword', array('module' => 'cover', 'rid' => $rids));
+ pdo_delete('rule', array('module' => 'cover', 'id' => $rids));
+ pdo_delete('cover_reply', array('module' => $modulename));
+ }
+ }
+
+ pdo_delete('site_nav', array('module' => $modulename));
+ pdo_delete('uni_account_modules', array('module' => $modulename));
+ pdo_delete('users_permission', array('type' => $modulename));
+
+ table('modules_recycle')->deleteByName($modulename);
+ $uni_group = pdo_getall('uni_group');
+ if (!empty($uni_group)) {
+ foreach ($uni_group as $group) {
+ $update = false;
+ $modules = (array)iunserializer($group['modules']);
+ if (!empty($modules)) {
+ foreach ($modules as $type => $value) {
+ if (!empty($value) && in_array($modulename, $value)) {
+ $modules[$type] = array_diff($modules[$type], array($modulename));
+ $update = true;
+ }
+ }
+ if ($update) {
+ pdo_update('uni_group', array('modules' => iserializer($modules)), array('id' => $group['id']));
+ }
+ }
+ }
+ }
+ $uni_account_extra_modules = table('uni_account_extra_modules')->getall();
+ if (!empty($uni_account_extra_modules)) {
+ foreach ($uni_account_extra_modules as $group) {
+ $update = false;
+ $modules = (array)iunserializer($group['modules']);
+ if (!empty($modules)) {
+ foreach ($modules as $type => $value) {
+ if (!empty($value) && in_array($modulename, $value)) {
+ $modules[$type] = array_diff($modules[$type], array($modulename));
+ $update = true;
+ }
+ }
+ if ($update) {
+ pdo_update('uni_account_extra_modules', array('modules' => iserializer($modules)), array('id' => $group['id']));
+ }
+ }
+ }
+ }
+ return true;
+}
+
+
+function ext_template_manifest($tpl, $cloud = true) {
+ $filename = IA_ROOT . '/app/themes/' . $tpl . '/manifest.xml';
+ if (!file_exists($filename)) {
+ if ($cloud) {
+ load()->model('cloud');
+ $manifest = cloud_t_info($tpl);
+ }
+ return is_error($manifest) ? array() : $manifest;
+ }
+ $manifest = ext_template_manifest_parse(file_get_contents($filename));
+ if (empty($manifest['name']) || $manifest['name'] != $tpl) {
+ return array();
+ }
+ return $manifest;
+}
+
+
+function ext_template_manifest_parse($xml) {
+ $xml = str_replace(array('&'), array('&'), $xml);
+ $xml = @isimplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
+ if (empty($xml)) {
+ return array();
+ }
+ $manifest['name'] = strval($xml->identifie);
+ $manifest['title'] = strval($xml->title);
+ if (empty($manifest['title'])) {
+ return array();
+ }
+ $manifest['type'] = !empty($xml->type) ? strval($xml->type) : 'other';
+ $manifest['description'] = strval($xml->description);
+ $manifest['author'] = strval($xml->author);
+ $manifest['url'] = strval($xml->url);
+ if (isset($xml->sections)) {
+ $manifest['sections'] = strval($xml->sections);
+ }
+ if ($xml->settings->item) {
+ foreach ($xml->settings->item as $msg) {
+ $attrs = $msg->attributes();
+ $manifest['settings'][] = array('key' => trim(strval($attrs['variable'])), 'value' => trim(strval($attrs['content'])), 'desc' => trim(strval($attrs['description'])));
+ }
+ }
+ return $manifest;
+}
+
+
+function ext_template_type() {
+ static $types = array(
+ 'often' => array(
+ 'name' => 'often',
+ 'title' => '常用模板',
+ ),
+ 'rummery' => array(
+ 'name' => 'rummery',
+ 'title' => '酒店',
+ ),
+ 'car' => array(
+ 'name' => 'car',
+ 'title' => '汽车',
+ ),
+ 'tourism' => array(
+ 'name' => 'tourism',
+ 'title' => '旅游',
+ ),
+ 'drink' => array(
+ 'name' => 'drink',
+ 'title' => '餐饮',
+ ),
+ 'realty' => array(
+ 'name' => 'realty',
+ 'title' => '房地产',
+ ),
+ 'medical' => array(
+ 'name' => 'medical',
+ 'title' => '医疗保健'
+ ),
+ 'education' => array(
+ 'name' => 'education',
+ 'title' => '教育'
+ ),
+ 'cosmetology' => array(
+ 'name' => 'cosmetology',
+ 'title' => '健身美容'
+ ),
+ 'shoot' => array(
+ 'name' => 'shoot',
+ 'title' => '婚纱摄影'
+ ),
+ 'other' => array(
+ 'name' => 'other',
+ 'title' => '其它行业'
+ )
+ );
+ return $types;
+}
+
+
+
+function ext_module_script_clean($modulename, $manifest) {
+ $moduleDir = IA_ROOT . '/addons/' . $modulename . '/';
+ $manifest['install'] = trim($manifest['install']);
+ $manifest['uninstall'] = trim($manifest['uninstall']);
+ $manifest['upgrade'] = trim($manifest['upgrade']);
+ if (strexists($manifest['install'], '.php')) {
+ if (file_exists($moduleDir . $manifest['install'])) {
+ unlink($moduleDir . $manifest['install']);
+ }
+ }
+ if (strexists($manifest['uninstall'], '.php')) {
+ if (file_exists($moduleDir . $manifest['uninstall'])) {
+ unlink($moduleDir . $manifest['uninstall']);
+ }
+ }
+ if (strexists($manifest['upgrade'], '.php')) {
+ if (file_exists($moduleDir . $manifest['upgrade'])) {
+ unlink($moduleDir . $manifest['upgrade']);
+ }
+ }
+ if (file_exists($moduleDir . 'manifest.xml')) {
+ unlink($moduleDir . 'manifest.xml');
+ }
+}
+
+
+function ext_module_msg_types() {
+ $mtypes = array();
+ $mtypes['text'] = '文本消息(重要)';
+ $mtypes['image'] = '图片消息';
+ $mtypes['voice'] = '语音消息';
+ $mtypes['video'] = '视频消息';
+ $mtypes['shortvideo'] = '小视频消息';
+ $mtypes['location'] = '位置消息';
+ $mtypes['link'] = '链接消息';
+ $mtypes['subscribe'] = '粉丝开始关注';
+ $mtypes['unsubscribe'] = '粉丝取消关注';
+ $mtypes['qr'] = '扫描二维码';
+ $mtypes['trace'] = '追踪地理位置';
+ $mtypes['click'] = '点击菜单(模拟关键字)';
+ $mtypes['view'] = '点击菜单(链接)';
+ $mtypes['merchant_order'] = '微小店消息';
+ $mtypes['user_get_card'] = '用户领取卡券事件';
+ $mtypes['user_del_card'] = '用户删除卡券事件';
+ $mtypes['user_consume_card'] = '用户核销卡券事件';
+ $mtypes['user_view_card'] = '进入会员卡事件';
+ $mtypes['user_gifting_card'] = '用户转赠卡券事件';
+ return $mtypes;
+}
+
+
+function ext_check_module_subscribe($modulename) {
+ global $_W, $_GPC;
+ if (empty($modulename)) {
+ return true;
+ }
+ if (!is_array($_W['setting']['module_receive_ban'])) {
+ $_W['setting']['module_receive_ban'] = array();
+ }
+ load()->func('communication');
+ $response = ihttp_request($_W['siteroot'] . 'web/' . url('utility/modules/check_receive', array('module_name' => $modulename)));
+ $response['content'] = json_decode($response['content'], true);
+ if (empty($response['content']['message']['errno'])) {
+ unset($_W['setting']['module_receive_ban'][$modulename]);
+ $module_subscribe_success = true;
+ } else {
+ $_W['setting']['module_receive_ban'][$modulename] = $modulename;
+ $module_subscribe_success = false;
+ }
+ setting_save($_W['setting']['module_receive_ban'], 'module_receive_ban');
+ return $module_subscribe_success;
+}
+
+
+function ext_manifest_check($module_name, $manifest) {
+ if(is_string($manifest)) {
+ return error(1, '模块 mainfest.xml 配置文件有误, 具体错误内容为: ' . $manifest);
+ }
+ $error_msg = '';
+ if(empty($manifest['application']['name'])) {
+ $error_msg .= ' <application><name>名称节点不能为空';
+ }
+ if(empty($manifest['application']['identifie']) || !preg_match('/^[a-z][a-z\d_]+$/i', $manifest['application']['identifie'])) {
+ $error_msg .= ' <application><identifie>标识符节点不能为空或格式错误(仅支持字母和数字, 且只能以字母开头)';
+ } elseif(strtolower($module_name) != strtolower($manifest['application']['identifie'])) {
+ $error_msg .= ' <application><identifie>标识符节点与模块路径名称定义不匹配';
+ }
+ if(empty($manifest['application']['version']) || !preg_match('/^[\d\.]+$/i', $manifest['application']['version'])) {
+ $error_msg .= ' <application><version>版本号节点未定义或格式不正确(仅支持数字和句点)';
+ }
+ if(empty($manifest['application']['ability'])) {
+ $error_msg .= ' <application><ability>功能简述节点不能为空';
+ }
+ if($manifest['platform']['isrulefields'] && !in_array('text', $manifest['platform']['handles'])) {
+ $error_msg .= ' 模块功能定义错误, 嵌入规则必须要能够处理文本类型消息';
+ }
+ if((!empty($manifest['cover']) || !empty($manifest['rule'])) && !$manifest['platform']['isrulefields']) {
+ $error_msg .= ' 模块功能定义错误, 存在封面或规则功能入口绑定时, 必须要嵌入规则';
+ }
+ global $points;
+ if (!empty($points)) {
+ foreach($points as $name => $point) {
+ if(is_array($manifest[$name])) {
+ foreach($manifest[$name] as $menu) {
+ if(trim($menu['title']) == '' || !preg_match('/^[a-z\d]+$/i', $menu['do']) && empty($menu['call'])) {
+ $error_msg .= " <$name>节点" . $point['title'] . ' 扩展项功能入口定义错误, (操作标题[title], 入口方法[do])格式不正确.';
+ }
+ }
+ }
+ }
+ }
+ if(is_array($manifest['permissions']) && !empty($manifest['permissions'])) {
+ foreach($manifest['permissions'] as $permission) {
+ if(trim($permission['title']) == '' || !preg_match('/^[a-z\d_]+$/i', $permission['permission'])) {
+ $error_msg .= ' ' . "<permissions>节点名称为: {$permission['title']} 的权限标识格式不正确,请检查标识名称或标识格式是否正确";
+ }
+ }
+ }
+ if(!is_array($manifest['versions'])) {
+ $error_msg .= ' <versions>节点兼容版本格式错误';
+ }
+ if (!empty($error_msg)) {
+ return error(-1, '模块 mainfest.xml 配置文件有误 ' . $error_msg);
+ }
+ return error(0);
+}
+
+function ext_file_check($module_name, $manifest) {
+ $module_path = IA_ROOT . '/addons/' . $module_name . '/';
+ if (empty($manifest['platform']['main_module']) &&
+ !file_exists($module_path . 'processor.php') &&
+ !file_exists($module_path . 'module.php') &&
+ !file_exists($module_path . 'site.php')) {
+ return error(1, '模块缺失文件,请检查模块文件中site.php, processor.php, module.php, receiver.php 文件是否存在!');
+ }
+ return true;
+}
+
+
+function ext_execute_uninstall_script($module_name) {
+ global $_W;
+ load()->model('cloud');
+ $modulepath = IA_ROOT . '/addons/' . $module_name . '/';
+ $manifest = ext_module_manifest($module_name);
+ if (empty($manifest)) {
+ $result = cloud_prepare();
+ if (is_error($result)) {
+ return error(1, $result['message']);
+ }
+ $packet = cloud_m_build($module_name, 'uninstall');
+ if ($packet['sql']) {
+ pdo_run(base64_decode($packet['sql']));
+ } elseif ($packet['script']) {
+ $uninstall_file = $modulepath . TIMESTAMP . '.php';
+ file_put_contents($uninstall_file, base64_decode($packet['script']));
+ require($uninstall_file);
+ unlink($uninstall_file);
+ }
+ } else {
+ if (!empty($manifest['uninstall'])) {
+ if (strexists($manifest['uninstall'], '.php')) {
+ if (file_exists($modulepath . $manifest['uninstall'])) {
+ require($modulepath . $manifest['uninstall']);
+ }
+ } else {
+ pdo_run($manifest['uninstall']);
+ }
+ }
+ }
+ return true;
+}
+
+function ext_module_run_script($manifest, $scripttype) {
+ if (!in_array($scripttype, array('install', 'upgrade'))) {
+ return false;
+ }
+ $modulename = $manifest['application']['identifie'];
+ $module_path = IA_ROOT . '/addons/' . $modulename . '/';
+ if (!empty($manifest[$scripttype])) {
+ if (strexists($manifest[$scripttype], '.php')) {
+ if (file_exists($module_path . $manifest[$scripttype])) {
+ include_once $module_path . $manifest[$scripttype];
+ }
+ } else {
+ pdo_run($manifest[$scripttype]);
+ }
+ }
+
+ if (defined('ONLINE_MODULE')) {
+ ext_module_script_clean($modulename, $manifest);
+ }
+ return true;
+}
\ No newline at end of file
diff --git a/framework/model/index.html b/framework/model/index.html
new file mode 100644
index 0000000..0519ecb
--- /dev/null
+++ b/framework/model/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/framework/model/material.mod.php b/framework/model/material.mod.php
new file mode 100644
index 0000000..2fed457
--- /dev/null
+++ b/framework/model/material.mod.php
@@ -0,0 +1,670 @@
+func('file');
+
+
+function material_sync($material, $exist_material, $type) {
+ global $_W;
+ $material = empty($material) ? array() : $material;
+ foreach ($material as $news) {
+ $attachid = '';
+ $material_exist = pdo_get('wechat_attachment', array('uniacid' => $_W['uniacid'], 'media_id' => $news['media_id']));
+ if (empty($material_exist)) {
+ $material_data = array(
+ 'uniacid' => $_W['uniacid'],
+ 'acid' => $_W['acid'],
+ 'media_id' => $news['media_id'],
+ 'type' => $type,
+ 'model' => 'perm',
+ 'createtime' => $news['update_time']
+ );
+ if ($type == 'image') {
+ $material_data['filename'] = $news['name'];
+ $material_data['attachment'] = $news['url'];
+ }
+ if ($type == 'voice') {
+ $material_data['filename'] = $news['name'];
+ }
+ if ($type == 'video') {
+ $material_data['tag'] = iserializer(array('title' => $news['name']));
+ }
+ pdo_insert('wechat_attachment', $material_data);
+ $attachid = pdo_insertid();
+ } else {
+ if ($type == 'image') {
+ $material_data = array(
+ 'createtime' => $news['update_time'],
+ 'attachment' => $news['url'],
+ 'filename' => $news['name']
+ );
+ pdo_update('wechat_attachment', $material_data, array('uniacid' => $_W['uniacid'], 'media_id' => $news['media_id']));
+ }
+ if ($type == 'voice') {
+ $material_data = array(
+ 'createtime' => $news['update_time'],
+ 'filename' => $news['name']
+ );
+ pdo_update('wechat_attachment', $material_data, array('uniacid' => $_W['uniacid'], 'media_id' => $news['media_id']));
+ }
+ if ($type == 'video') {
+ $tag = empty($material_exist['tag']) ? array() : iunserializer($material_exist['tag']);
+ $material_data = array(
+ 'createtime' => $news['update_time'],
+ 'tag' => iserializer(array('title' => $news['name'], 'url' => $tag['url']))
+ );
+ pdo_update('wechat_attachment', $material_data, array('uniacid' => $_W['uniacid'], 'media_id' => $news['media_id']));
+ }
+ $exist_material[] = $material_exist['id'];
+ }
+ if ($type == 'news') {
+ $attachid = empty($attachid) ? $material_exist['id'] : $attachid;
+ pdo_delete('wechat_news', array('uniacid' =>$_W['uniacid'], 'attach_id' => $attachid));
+ foreach ($news['content']['news_item'] as $key => $new) {
+ $new_data = array(
+ 'uniacid' => $_W['uniacid'],
+ 'attach_id' => $attachid,
+ 'thumb_media_id' => $new['thumb_media_id'],
+ 'thumb_url' => $new['thumb_url'],
+ 'title' => $new['title'],
+ 'author' => $new['author'],
+ 'digest' => $new['digest'],
+ 'content' => $new['content'],
+ 'content_source_url' => $new['content_source_url'],
+ 'show_cover_pic' => $new['show_cover_pic'],
+ 'url' => $new['url'],
+ 'displayorder' => $key,
+ );
+ pdo_insert('wechat_news', $new_data);
+ }
+ pdo_update('wechat_attachment', array('createtime' => $news['update_time']), array('media_id' => $news['media_id']));
+ }
+ }
+ return $exist_material;
+}
+
+
+function material_news_set($data, $attach_id) {
+ global $_W;
+ $attach_id = intval($attach_id);
+ foreach ($data as $key => $news) {
+ if (empty($news['title']) ||
+ (!empty($news['thumb']) && !parse_path($news['thumb'])) ||
+ (!empty($news['url']) && !parse_path($news['url'])) ||
+ (!empty($news['content_source_url']) && !parse_path($news['content_source_url']))
+ ) {
+ return error('-1', '参数有误');
+ }
+ if (!material_url_check($news['content_source_url']) || !material_url_check($news['url']) || !material_url_check($news['thumb'])) {
+ return error('-3', '提交链接参数不合法');
+ }
+ $post_news[] = array(
+ 'id' => intval($news['id']),
+ 'uniacid' => $_W['uniacid'],
+ 'thumb_url' => $news['thumb'],
+ 'title' => addslashes($news['title']),
+ 'author' => addslashes($news['author']),
+ 'digest' => addslashes($news['digest']),
+ 'content' => safe_gpc_html(htmlspecialchars_decode($news['content'])),
+ 'url' => $news['url'],
+ 'show_cover_pic' => intval($news['show_cover_pic']),
+ 'displayorder' => intval($key),
+ 'thumb_media_id' => addslashes($news['media_id']),
+ 'content_source_url' => $news['content_source_url'],
+ );
+ }
+ if (!empty($attach_id)){
+ $wechat_attachment = pdo_get('wechat_attachment', array(
+ 'id' => $attach_id,
+ 'uniacid' => $_W['uniacid']
+ ));
+ if (empty($wechat_attachment)){
+ return error('-2', '编辑素材不存在');
+ }
+ $wechat_attachment['model'] = 'local';
+ pdo_update('wechat_attachment', $wechat_attachment, array('id' => $attach_id, 'uniacid' => $_W['uniacid']));
+ pdo_delete('wechat_news', array('attach_id' => $attach_id, 'uniacid' => $_W['uniacid']));
+ foreach ($post_news as $id => $news) {
+ $news['attach_id'] = $attach_id;
+ unset($news['id']);
+ pdo_insert('wechat_news', $news);
+ }
+ cache_delete(cache_system_key('material_reply', array('attach_id' => $attach_id)));
+ } else {
+ $wechat_attachment = array(
+ 'uniacid' => $_W['uniacid'],
+ 'acid' => $_W['acid'],
+ 'media_id' => '',
+ 'type' => 'news',
+ 'model' => 'local',
+ 'createtime' => TIMESTAMP
+ );
+ pdo_insert('wechat_attachment', $wechat_attachment);
+ $attach_id = pdo_insertid();
+ foreach ($post_news as $key => $news) {
+ $news['attach_id'] = $attach_id;
+ pdo_insert('wechat_news', $news);
+ }
+ }
+ return $attach_id;
+}
+
+
+function material_get($attach_id) {
+ if (empty($attach_id)) {
+ return error(1, "素材id参数不能为空");
+ }
+ if (is_numeric($attach_id)) {
+ $material = table('wechat_attachment')->getById($attach_id);
+ } else {
+ $media_id = trim($attach_id);
+ $material = table('wechat_attachment')->getByMediaId($media_id);
+ }
+ if (!empty($material)) {
+ if ($material['type'] == 'news') {
+ $news = table('wechat_news')->getAllByAttachId($material['id']);
+ if (!empty($news)) {
+ foreach ($news as &$news_row) {
+ $news_row['content_source_url'] = $news_row['content_source_url'];
+ $news_row['thumb_url'] = tomedia($news_row['thumb_url']);
+ preg_match_all('/src=[\'\"]?([^\'\"]*)[\'\"]?/i', $news_row['content'], $match);
+ if (!empty($match[1])) {
+ foreach ($match[1] as $val) {
+ if ((strexists($val, 'http://') || strexists($val, 'https://')) && (strexists($val, 'mmbiz.qlogo.cn') || strexists($val, 'mmbiz.qpic.cn'))) {
+ $news_row['content'] = str_replace($val, tomedia($val), $news_row['content']);
+ }
+ }
+ }
+ $news_row['content'] = str_replace('data-src', 'src', $news_row['content']);
+ }
+ unset($news_row);
+ } else {
+ return error('1', '素材不存在');
+ }
+ $material['news'] = $news;
+ } elseif ($material['type'] == 'image') {
+ $material['url'] = $material['attachment'];
+ $material['attachment'] = tomedia($material['attachment']);
+
+ }
+ return $material;
+ } else {
+ return error('1', "素材不存在");
+ }
+}
+
+
+function material_build_reply($attach_id) {
+ if (empty($attach_id)) {
+ return error(1, "素材id参数不能为空");
+ }
+ $cachekey = cache_system_key('material_reply', array('attach_id' => $attach_id));
+ $reply = cache_load($cachekey);
+ if (!empty($reply)) {
+ return $reply;
+ }
+ $reply_material = material_get($attach_id);
+ $reply = array();
+ if ($reply_material['type'] == 'news') {
+ if (!empty($reply_material['news'])) {
+ foreach ($reply_material['news'] as $material) {
+ $reply[] = array(
+ 'title' => $material['title'],
+ 'description' => $material['digest'],
+ 'picurl' => $material['thumb_url'],
+ 'url' => !empty($material['content_source_url']) ? $material['content_source_url'] : $material['url'],
+ );
+ }
+ }
+ }
+ cache_write($cachekey, $reply, CACHE_EXPIRE_MIDDLE);
+ return $reply;
+}
+
+
+function material_strip_wechat_image_proxy($content) {
+ global $_W;
+ $match_wechat = array();
+ $content = htmlspecialchars_decode($content);
+ preg_match_all ('//iU', $content, $match_wechat);
+ if (!empty($match_wechat[1])) {
+ foreach ($match_wechat[1] as $val) {
+ $wechat_thumb_url = urldecode(str_replace($_W['siteroot'] . 'web/index.php?c=utility&a=wxcode&do=image&attach=', '', $val));
+ $content = str_replace($val, $wechat_thumb_url, $content);
+ }
+ }
+ return $content;
+}
+
+
+function material_get_image_url($content) {
+ global $_W;
+ $content = htmlspecialchars_decode ($content);
+ $match = array ();
+ $images = array ();
+ preg_match_all ('//iU', $content, $match);
+ if (!empty($match[1])) {
+ foreach ($match[1] as $val) {
+ if ((strexists ($val, 'http://') || strexists ($val, 'https://')) && !strexists ($val, 'mmbiz.qlogo.cn') && !strexists ($val, 'mmbiz.qpic.cn')) {
+ $images[] = $val;
+ } else {
+ if (strexists ($val, './attachment/images/')) {
+ $images[] = tomedia ($val);
+ }
+ }
+ }
+ }
+ return $images;
+}
+
+
+function material_parse_content($content) {
+ global $_W;
+ $content = material_strip_wechat_image_proxy($content);
+ $images = material_get_image_url($content);
+ if (!empty($images)) {
+ foreach ($images as $image) {
+ $thumb = file_remote_attach_fetch(tomedia($image), 1024, 'material/images');
+ if(is_error($thumb)) {
+ return $thumb;
+ }
+ $thumb = ATTACHMENT_ROOT . $thumb;
+ $account_api = WeAccount::createByUniacid();
+ $result = $account_api->uploadNewsThumb($thumb);
+ if (is_error($result)) {
+ return $result;
+ } else {
+ $content = str_replace($image, $result, $content);
+ }
+ }
+ }
+ return $content;
+}
+
+function material_local_news_upload($attach_id) {
+ global $_W;
+ $account_api = WeAccount::createByUniacid();
+ $material = material_get($attach_id);
+ if (is_error($material)){
+ return error('-1', '获取素材文件失败');
+ }
+ $change_media_id = 0;
+ foreach ($material['news'] as $news) {
+ if (empty($news['content'])){
+ return error('-6', '素材内容不能为空');
+ }
+ $news['content'] = material_parse_content($news['content']);
+ if (!empty($news['content_source_url'])) {
+ $news['content_source_url'] = safe_gpc_url($news['content_source_url'], false, $_W['siteroot'] . 'app/' . $news['content_source_url']);
+ }
+ if (is_error($news['content'])) {
+ return error('-2', $news['content']['message']);
+ }
+ if (empty($news['thumb_media_id'])) {
+ if (empty($news['thumb_url'])){
+ return error('-7', '图文封面不能为空');
+ }else{
+ $result = material_local_upload_by_url($news['thumb_url']);
+ if (is_error($result)){
+ return error('-3', $result['message']);
+ }
+ $news['thumb_media_id'] = $result['media_id'];
+ $news['thumb_url'] = $result['url'];
+ }
+ }
+ pdo_update('wechat_news', $news, array('id' => $news['id']));
+
+ $articles['articles'][] = $news;
+
+ if (!empty($material['media_id'])) {
+ $edit_attachment['media_id'] = $material['media_id'];
+ $edit_attachment['index'] = $news['displayorder'];
+ $edit_attachment['articles'] = $news;
+ $result = $account_api->editMaterialNews($edit_attachment);
+ if (is_error($result)) {
+ if ($result['errno'] == 40114) { $change_media_id = $material['media_id'];
+ break;
+ } else {
+ return error('-4', $result['message']);
+ }
+ }
+ }
+ }
+
+ if (empty($material['media_id']) || $change_media_id) {
+ $media_id = $account_api->addMatrialNews($articles);
+ if (is_error($media_id)) {
+ return error('-5', $media_id, '');
+ }
+ $material_info = $account_api->getMaterial($media_id, false);
+ if (!empty($material_info['news_item'])) {
+ foreach ($material_info['news_item'] as $key => $info) {
+ pdo_update('wechat_news', array('url' => $info['url']), array('uniacid' => $_W['uniacid'], 'attach_id' => $material['id'], 'displayorder' => $key));
+ }
+ }
+ pdo_update('wechat_attachment', array(
+ 'media_id' => $media_id,
+ 'model' => 'perm'
+ ), array(
+ 'uniacid' => $_W['uniacid'],
+ 'id' => $attach_id
+ ));
+ if ($change_media_id) {
+ $account_api->delMaterial($change_media_id);
+ }
+ } else {
+ pdo_update('wechat_attachment', array('model' => 'perm'), array('uniacid' => $_W['uniacid'], 'id' => $attach_id));
+ }
+ return $material;
+}
+
+function material_local_upload_by_url($url, $type='images') {
+ global $_W;
+ $account_api = WeAccount::createByUniacid();
+ if (! empty($_W['setting']['remote']['type'])) {
+ $remote_file_url = tomedia($url);
+ $filepath = file_remote_attach_fetch($remote_file_url,0,'');
+ if(is_error($filepath)) {
+ return $filepath;
+ }
+ $filepath = ATTACHMENT_ROOT . $filepath;
+ } else {
+ if (strexists(parse_url($url, PHP_URL_PATH), '/attachment/')) {
+ $url = substr(parse_url($url, PHP_URL_PATH), strpos(parse_url($url, PHP_URL_PATH), '/attachment/') + strlen('/attachment/'));
+ }
+ $filepath = ATTACHMENT_ROOT . $url;
+ }
+ $filesize = filesize($filepath);
+ $filesize = sizecount($filesize, true);
+ if ($filesize > 10 && $type == 'videos') {
+ return error(-1, '要转换的微信素材视频不能超过10M');
+ }
+ return $account_api->uploadMediaFixed($filepath, $type);
+}
+
+
+function material_local_upload($material_id){
+ global $_W;
+ $type_arr = array('1' => 'images', '2' => 'voices', '3' => 'videos');
+ $material = pdo_get('core_attachment', array('uniacid' => $_W['uniacid'], 'id' => $material_id));
+ if (empty($material)) {
+ return error('-1', '同步素材不存在或已删除');
+ }
+ return material_local_upload_by_url($material['attachment'], $type_arr[$material['type']]);
+}
+
+
+function material_upload_limit() {
+ global $_W;
+ $default = 5 * 1024 * 1024;
+ $upload_limit = array(
+ 'num' => '30',
+ 'image' => $default,
+ 'voice' => $default,
+ 'video' => $default
+ );
+ $upload = $_W['setting']['upload'];
+ if (isset($upload['image']['limit']) && (bytecount($upload['image']['limit'].'kb')>0)){
+ $upload_limit['image'] = bytecount($upload['image']['limit'].'kb');
+ }
+ if (isset($upload['image']['limit']) && (bytecount($upload['audio']['limit'].'kb')>0)){
+ $upload_limit['voice'] = $upload_limit['video'] = bytecount($upload['audio']['limit'].'kb');
+ }
+ return $upload_limit;
+}
+
+
+function material_news_delete($material_id){
+ global $_W;
+ $permission = permission_account_user_menu($_W['uid'], $_W['uniacid'], 'system');
+ if (is_error($permission)) {
+ return error(-1, $permission['message']);
+ }
+ if (empty($_W['isfounder']) && !empty($permission) && !in_array('platform_material', $permission) && !in_array('all', $permission)) {
+ return error('-1', '您没有权限删除该文件');
+ }
+ $material_id = intval($material_id);
+ $material = pdo_get('wechat_attachment', array('uniacid' => $_W['uniacid'], 'id' => $material_id));
+ if (empty($material)){
+ return error('-2', '素材文件不存在或已删除');
+ }
+ if (!empty($material['media_id'])){
+ $account_api = WeAccount::createByUniacid();
+ $result = $account_api->delMaterial($material['media_id']);
+ }
+ if (is_error($result)){
+ return $result;
+ }
+ pdo_delete('wechat_news', array('uniacid' => $_W['uniacid'], 'attach_id' => $material_id));
+ pdo_delete('wechat_attachment', array('uniacid' => $_W['uniacid'], 'id' => $material_id));
+ return $result;
+}
+
+
+function material_delete($material_id, $location){
+ global $_W;
+ if (empty($_W['isfounder']) && !permission_check_account_user('platform_material_delete')) {
+ return error('-1', '您没有权限删除该文件');
+ }
+ $material_id = intval($material_id);
+ $table = $location == 'wechat' ? 'wechat_attachment' : 'core_attachment';
+ $material = pdo_get($table, array('id' => $material_id));
+ if (empty($material)){
+ return error('-2', '素材文件不存在或已删除');
+ }
+ if ($location == 'wechat' && !empty($material['media_id'])){
+ $account_api = WeAccount::createByUniacid();
+ $result = $account_api->delMaterial($material['media_id']);
+ } else {
+ if (!empty($material['uniacid'])) {
+ $role = permission_account_user_role($_W['uid'], $material['uniacid']);
+ if (in_array($role, array(ACCOUNT_MANAGE_NAME_OPERATOR, ACCOUNT_MANAGE_NAME_MANAGER)) && $_W['uid'] != $material['uid']) {
+ return error('-1', '您没有权限删除该文件');
+ }
+ } elseif ($_W['uid'] != $material['uid']) {
+ return error('-1', '您没有权限删除该文件');
+ }
+ if (!empty($_W['setting']['remote']['type'])) {
+ $result = file_remote_delete($material['attachment']);
+ if (file_exists(IA_ROOT . '/' . $_W['config']['upload']['attachdir'] . '/' . $material['attachment'])) {
+ $result = file_delete($material['attachment']);
+ }
+ } else {
+ $result = file_delete($material['attachment']);
+ }
+ }
+ if (is_error($result)) {
+ return error('-3', '删除文件操作发生错误');
+ }
+ pdo_delete($table, array('id' => $material_id, 'uniacid' => $_W['uniacid']));
+ return $result;
+}
+
+
+function material_url_check($url) {
+ if (empty($url)){
+ return true;
+ } else {
+ $pattern ="/^((https|http|tel):\/\/|\.\/index.php)[^\s]+/i";
+ return preg_match($pattern, trim($url));
+ }
+}
+
+function material_news_list($server = '', $search ='', $page = array('page_index' => 1, 'page_size' => 24)) {
+ global $_W;
+ $wechat_news_table = table('wechat_news');
+ $wechat_attachment_table = table('wechat_attachment');
+ $material_list = array();
+ if (empty($search)) {
+ $wechat_attachment_table->searchWithUniacid($_W['uniacid']);
+ $wechat_attachment_table->searchWithType('news');
+ if (!empty($server) && in_array($server, array('local', 'perm'))) {
+ $wechat_attachment_table->searchWithModel($server);
+ }
+ $wechat_attachment_table->searchWithPage($page['page_index'], $page['page_size']);
+ $news_list = $wechat_attachment_table->orderby('createtime DESC')->getall();
+ $total = $wechat_attachment_table->getLastQueryTotal();
+
+ if (! empty($news_list)) {
+ foreach ($news_list as $news) {
+ $news['items'] = $wechat_news_table->getAllByAttachId($news['id']);
+ $material_list[$news['id']] = $news;
+ }
+ }
+ } else {
+ $wechat_news_table->searchKeyword("%$search%");
+ $wechat_news_table->searchWithUniacid($_W['uniacid']);
+ $search_attach_id = $wechat_news_table->getall();
+
+ if (!empty($search_attach_id)) {
+ foreach ($search_attach_id as $news) {
+ if (isset($material_list[$news['attach_id']]) && !empty($material_list[$news['attach_id']])) {
+ continue;
+ }
+ $wechat_attachment = $wechat_attachment_table->getById($news['attach_id']);
+ if (empty($wechat_attachment)) {
+ continue;
+ }
+ $material_list[$news['attach_id']] = $wechat_attachment;
+ $material_list[$news['attach_id']]['items'] = $wechat_news_table->getAllByAttachId($news['attach_id']);
+ }
+ }
+ }
+
+ foreach ($material_list as $key => &$news) {
+ if (isset($news['items']) && is_array($news['items'])) {
+ if (empty($news['items'][0])) {
+ $news['items'] = array_values($news['items']);
+ }
+ foreach ($news['items'] as &$item) {
+ $item['thumb_url'] = tomedia($item['thumb_url']);
+ }
+ }
+ }
+ unset($news_list);
+ $pager = pagination($total, $page['page_index'], $page['page_size'],'',$context = array('before' => 5, 'after' => 4, 'isajax' => $_W['isajax']));
+ $material_news = array('material_list' => $material_list, 'page' => $pager);
+ return $material_news;
+}
+
+function material_list($type = '', $server = '', $page = array('page_index' => 1, 'page_size' => 24)) {
+ global $_W;
+ $tables = array(MATERIAL_LOCAL => 'core_attachment', MATERIAL_WEXIN => 'wechat_attachment');
+ $conditions['uniacid'] = $_W['uniacid'];
+ $table = $tables[$server];
+ switch ($type) {
+ case 'voice' :
+ $conditions['type'] = $server == MATERIAL_LOCAL ? ATTACH_TYPE_VOICE : 'voice';
+ break;
+ case 'video' :
+ $conditions['type'] = $server == MATERIAL_LOCAL ? ATTACH_TYPE_VEDIO : 'video';
+ break;
+ default :
+ $conditions['type'] = $server == MATERIAL_LOCAL ? ATTACH_TYPE_IMAGE : 'image';
+ break;
+ }
+ if ($server == 'local') {
+ $material_list = pdo_getslice($table, $conditions, array($page['page_index'], $page['page_size']), $total, array(), '', 'createtime DESC');
+ } else {
+ $conditions['model'] = MATERIAL_WEXIN;
+ $material_list = pdo_getslice($table, $conditions, array($page['page_index'], $page['page_size']), $total, array(), '', 'createtime DESC');
+ if ($type == 'video'){
+ foreach ($material_list as &$row) {
+ $row['tag'] = $row['tag'] == '' ? array() : iunserializer($row['tag']);
+ if (empty($row['filename'])) {
+ $row['filename'] = $row['tag']['title'];
+ }
+ }
+ unset($row);
+ }
+ }
+ $pager = pagination($total, $page['page_index'], $page['page_size'],'',$context = array('before' => 5, 'after' => 4, 'isajax' => $_W['isajax']));
+ $material_news = array('material_list' => $material_list, 'page' => $pager);
+ return $material_news;
+}
+
+
+
+function material_news_to_local($attach_id) {
+ $material = material_get($attach_id);
+ if(is_error($material)) {
+ return $material;
+ }
+ $attach_id = material_news_set($material['news'],$attach_id);
+ if(is_error($attach_id)) {
+ return $attach_id;
+ }
+ $material['items'] = $material['news']; return $material;
+}
+
+
+function material_to_local($resourceid, $uniacid, $uid, $type = 'image') {
+ $material = material_get($resourceid);
+ if(is_error($material)) {
+ return $material;
+ }
+ return material_network_image_to_local($material['url'], $uniacid, $uid);
+}
+
+
+function material_network_image_to_local($url, $uniacid, $uid) {
+ return material_network_to_local($url, $uniacid, $uid, 'image');
+}
+
+
+
+function material_network_to_local($url, $uniacid, $uid, $type = 'image') {
+ $path = file_remote_attach_fetch($url); if(is_error($path)) {
+ return $path;
+ }
+ $filename = pathinfo($path,PATHINFO_FILENAME);
+ $data = array('uniacid' => $uniacid, 'uid' => $uid,
+ 'filename' => $filename,
+ 'attachment' => $path,
+ 'type' => $type == 'image' ? ATTACH_TYPE_IMAGE : ($type == 'audio'||$type == 'voice' ? ATTACH_TYPE_VOICE : ATTACH_TYPE_VEDIO),
+ 'createtime'=>TIMESTAMP
+ );
+ pdo_insert('core_attachment', $data);
+ $id = pdo_insertid();
+ $data['id'] = $id;
+ $data['url'] = tomedia($path);
+ return $data;
+}
+
+
+
+function material_to_wechat($attach_id, $uniacid, $uid, $acid, $type = 'image') {
+ $result = material_local_upload($attach_id); if (is_error($result)) {
+ return $result;
+ }
+ $tag = $result['url'];
+ if($type == 'video') {
+ $tag = serialize(array('title'=>'网络视频','description'=>'网络视频'));
+ }
+ $data = array('uniacid' => $uniacid, 'uid' => $uid, 'acid' => $acid,
+ 'media_id' => $result['media_id'],
+ 'attachment' => $result['url'],
+ 'type' => $type,
+ 'tag' => $tag,
+ 'model' => 'perm',
+ 'createtime'=>TIMESTAMP
+ );
+ pdo_insert('wechat_attachment', $data);
+ $id = pdo_insertid();
+ $data['url'] = tomedia($result['url']);
+ $data['id'] = $id;
+ return $data;
+}
+
+
+
+function material_network_image_to_wechat($url, $uniacid, $uid, $acid) {
+ return material_network_to_wechat($url, $uniacid, $uid, $acid, 'image');
+}
+
+
+function material_network_to_wechat($url, $uniacid, $uid, $acid, $type = 'image') {
+ $local = material_network_to_local($url, $uniacid, $uid, $type); if (is_error($local)) {
+ return $local;
+ }
+ return material_to_wechat($local['id'], $uniacid, $uid, $acid, $type);
+}
diff --git a/framework/model/mc.mod.php b/framework/model/mc.mod.php
new file mode 100644
index 0000000..63a8a3f
--- /dev/null
+++ b/framework/model/mc.mod.php
@@ -0,0 +1,2001 @@
+ $birth[0],
+ 'month' => $birth[1],
+ 'day' => $birth[2],
+ );
+ }
+ if (!empty($fields['birth'])) {
+ $fields['birthyear'] = $fields['birth']['year'];
+ $fields['birthmonth'] = $fields['birth']['month'];
+ $fields['birthday'] = $fields['birth']['day'];
+ }
+ if (isset($fields['reside'])) {
+ $fields['resideprovince'] = $fields['reside']['province'];
+ $fields['residecity'] = $fields['reside']['city'];
+ $fields['residedist'] = $fields['reside']['district'];
+ }
+ unset($fields['reside'], $fields['birth']);
+ foreach ($fields as $field => $value) {
+ if (!in_array($field, $struct) || is_array($value)) {
+ unset($fields[$field]);
+ }
+ }
+ if (!empty($fields['avatar'])) {
+ if (strexists($fields['avatar'], 'attachment/images/global/avatars/avatar_')) {
+ $fields['avatar'] = str_replace($_W['attachurl'], '', $fields['avatar']);
+ }
+ }
+
+ $member = table('mc_members')->getById($uid);
+ if (!empty($fields['email'])) {
+ $mc_members = table('mc_members');
+ $mc_members->searchWithUniacid(mc_current_real_uniacid());
+ $mc_members->searchWithoutUid($uid);
+ $mc_members->searchWithEmail($fields['email']);
+ $emailexists = $mc_members->getcolumn('email');
+ if ($emailexists) {
+ unset($fields['email']);
+ }
+ }
+ if (!empty($fields['mobile'])) {
+ $mc_members = table('mc_members');
+ $mc_members->searchWithUniacid(mc_current_real_uniacid());
+ $mc_members->searchWithoutUid($uid);
+ $mc_members->searchWithEmail($fields['mobile']);
+ $mobilexists = $mc_members->getcolumn('mobile');
+ if ($mobilexists) {
+ unset($fields['mobile']);
+ }
+ }
+ if (empty($member)) {
+ if(empty($fields['mobile']) && empty($fields['email'])) {
+ return false;
+ }
+ $fields['uniacid'] = mc_current_real_uniacid();
+ $fields['createtime'] = TIMESTAMP;
+ pdo_insert('mc_members', $fields);
+ $insert_id = pdo_insertid();
+ } else {
+ if (!empty($fields)) {
+ pdo_update('mc_members', $fields, array('uid' => $uid, 'uniacid' => $_W['uniacid']));
+ }
+ }
+
+ if (!empty($openid) && empty($uid)) {
+ table('mc_mapping_fans')->fill(array('uid' => $insert_id))->where(array('uniacid' => mc_current_real_uniacid(), 'openid' => $openid))->save();
+ }
+ cache_build_memberinfo($uid);
+ return true;
+}
+
+
+function mc_fetch($uid, $fields = array()) {
+ if (empty($uid)) {
+ return array();
+ }
+ $struct = mc_fields();
+ $struct = array_keys($struct);
+ if (!empty($fields)) {
+ foreach ($fields as $key => $field) {
+ if (!in_array($field, $struct)) {
+ unset($fields[$key]);
+ }
+ if ($field == 'birth') {
+ $fields[] = 'birthyear';
+ $fields[] = 'birthmonth';
+ $fields[] = 'birthday';
+ }
+ if ($field == 'reside') {
+ $fields[] = 'resideprovince';
+ $fields[] = 'residecity';
+ $fields[] = 'residedist';
+ }
+ }
+ unset($fields['birth'], $fields['reside']);
+ }
+ $result = array();
+ if (is_array($uid)) {
+ foreach ($uid as $id) {
+ $user_info = mc_fetch_one($id);
+ if (!empty($user_info) && !empty($fields)) {
+ foreach ($fields as $field) {
+ $result[$id][$field] = $user_info[$field];
+ }
+ $result[$id]['uid'] = $id;
+ } else {
+ $result[$id] = $user_info;
+ }
+ }
+ } else {
+ $user_info = mc_fetch_one($uid);
+ if (!empty($user_info) && !empty($fields)) {
+ foreach ($fields as $field) {
+ $result[$field] = $user_info[$field];
+ }
+ $result['uid'] = $uid;
+ } else {
+ $result = $user_info;
+ }
+ }
+ return $result;
+}
+
+
+function mc_fetch_one($uid, $uniacid = 0) {
+ global $_W;
+ $uid = mc_openid2uid($uid);
+ if (empty($uid)) {
+ return array();
+ }
+ $cachekey = cache_system_key('memberinfo', array('uid' => $uid));
+ $cache = cache_load($cachekey);
+
+ if (!empty($cache)) {
+ return $cache;
+ }
+ $params = array('uid' => $uid);
+ $params['uniacid'] = intval($uniacid) > 0 ? intval($uniacid) : $_W['uniacid'];
+ $result = pdo_get('mc_members', $params);
+ if (!empty($result)) {
+ $result['avatar'] = tomedia($result['avatar']);
+ $result['credit1'] = floatval($result['credit1']);
+ $result['credit2'] = floatval($result['credit2']);
+ $result['credit3'] = floatval($result['credit3']);
+ $result['credit4'] = floatval($result['credit4']);
+ $result['credit5'] = floatval($result['credit5']);
+ $result['credit6'] = floatval($result['credit6']);
+ } else {
+ $result = array();
+ }
+ cache_write($cachekey, $result);
+ return $result;
+}
+
+function mc_fansinfo($openidOruid, $acid = 0, $uniacid = 0) {
+ global $_W;
+ if (empty($openidOruid)) {
+ return array();
+ }
+ if (is_numeric($openidOruid)) {
+ $openid = mc_uid2openid($openidOruid);
+ if (empty($openid)) {
+ return array();
+ }
+ } else {
+ $openid = $openidOruid;
+ }
+
+ $mc_mapping_fans_table = table('mc_mapping_fans');
+ if (!empty($uniacid)) {
+ $mc_mapping_fans_table->searchWithUniacid($uniacid);
+ }
+ $mc_mapping_fans_table->searchWithOpenid($openid);
+ $fan = $mc_mapping_fans_table->get();
+
+ if (!empty($fan)) {
+ $mc_fans_tag_table = table('mc_fans_tag');
+ $tags_info = $mc_fans_tag_table->getByOpenid($openid);
+// if (empty($tags_info)) {
+ if (!empty($fan['tag']) && is_string($fan['tag'])) {
+ if (is_base64($fan['tag'])) {
+ $fan['tag'] = @base64_decode($fan['tag']);
+ }
+ if (is_serialized($fan['tag'])) {
+ $fan['tag'] = @iunserializer($fan['tag']);
+ }
+ if (is_array($fan['tag']) && !empty($fan['tag']['headimgurl'])) {
+ $fan['tag']['avatar'] = tomedia($fan['tag']['headimgurl']);
+ unset($fan['tag']['headimgurl']);
+ if (empty($fan['nickname']) && !empty($fan['tag']['nickname'])) {
+ $fan['nickname'] = strip_emoji($fan['tag']['nickname']);
+ }
+ $fan['gender'] = $fan['sex'] = $fan['tag']['sex'];
+ $fan['avatar'] = $fan['headimgurl'] = $fan['tag']['avatar'];
+ }
+ } else {
+ $fan['tag'] = array();
+ }
+// } else {
+// $fan['tag'] = $tags_info;
+// $fan['tag']['avatar'] = $tags_info['headimgurl'];
+//
+// if (empty($fan['nickname']) && !empty($fan['tag']['nickname'])) {
+// $fan['nickname'] = strip_emoji($fan['tag']['nickname']);
+// }
+// $fan['gender'] = $fan['sex'] = $fan['tag']['sex'];
+// $fan['avatar'] = $fan['headimgurl'] = $fan['tag']['avatar'];
+// }
+ }
+
+ if (empty($fan) && $openid == $_W['openid'] && !empty($_SESSION['userinfo'])) {
+ $fan['tag'] = iunserializer(base64_decode($_SESSION['userinfo']));
+ $fan['uid'] = 0;
+ $fan['openid'] = $fan['tag']['openid'];
+ $fan['follow'] = 0;
+ if (empty($fan['nickname']) && !empty($fan['tag']['nickname'])) {
+ $fan['nickname'] = strip_emoji($fan['tag']['nickname']);
+ }
+ $fan['gender'] = $fan['sex'] = $fan['tag']['sex'];
+ $fan['avatar'] = $fan['headimgurl'] = $fan['tag']['headimgurl'];
+ $mc_oauth_fan = mc_oauth_fans($fan['openid']);
+ if (!empty($mc_oauth_fan)) {
+ $fan['uid'] = $mc_oauth_fan['uid'];
+ }
+ }
+ return $fan;
+}
+
+
+function mc_oauth_fans($openid, $uniacid = 0){
+ $mc_oauth_fans_table = table('mc_oauth_fans');
+ if (!empty($uniacid)) {
+ $mc_oauth_fans_table->searchWithUniacid($uniacid);
+ }
+ $mc_oauth_fans_table->searchWithoAuthopenid($openid);
+ $fan = $mc_oauth_fans_table->get();
+ return $fan;
+}
+
+
+function mc_oauth_userinfo($acid = 0) {
+ global $_W;
+ if (isset($_SESSION['userinfo'])) {
+ $userinfo = iunserializer(base64_decode($_SESSION['userinfo']));
+ if (!empty($userinfo) || is_array($userinfo)) {
+ return $userinfo;
+ }
+ }
+ if ($_W['container'] != 'wechat') {
+ return array();
+ }
+ $result = mc_oauth_account_userinfo();
+ if (is_error($result)) {
+ load()->func('tpl');
+ include template('mc/iswxapp', TEMPLATE_INCLUDEPATH);
+ exit;
+ }
+ return $result;
+
+}
+
+function mc_oauth_account_userinfo($url = '') {
+ global $_W;
+ if ($_W['account']->typeSign != 'account') {
+ error(-4, '该账号非公众号类型,不支持使用该函数!');
+ }
+ if (empty($_W['account']['oauth'])) {
+ return error(-1, '未指定网页授权公众号, 无法获取用户信息.');
+ }
+ if (empty($_W['account']['oauth']['key'])) {
+ return error(-2, '公众号未设置 appId 或 secret.');
+ }
+ if (intval($_W['account']['oauth']['level']) < 4 && !in_array($_W['account']['oauth']['level'], array(ACCOUNT_TYPE_APP_NORMAL, ACCOUNT_TYPE_APP_AUTH, ACCOUNT_TYPE_WXAPP_WORK))) {
+ return error(-3, '公众号非认证服务号, 无法获取用户信息.');
+ }
+
+ if (!empty($_SESSION['openid']) && intval($_W['account']['level']) >= 3) {
+ $oauth_account = WeAccount::createByUniacid();
+ $userinfo = $oauth_account->fansQueryInfo($_SESSION['openid']);
+ if (!is_error($userinfo) && !empty($userinfo) && is_array($userinfo) && !empty($userinfo['nickname'])) {
+ $userinfo['nickname'] = stripcslashes($userinfo['nickname']);
+ $userinfo['avatar'] = $userinfo['headimgurl'];
+ $_SESSION['userinfo'] = base64_encode(iserializer($userinfo));
+ $fan = mc_fansinfo($_SESSION['openid']);
+ if (!empty($fan)) {
+ $record = array(
+ 'updatetime' => TIMESTAMP,
+ 'nickname' => stripslashes($userinfo['nickname']),
+ 'follow' => $userinfo['subscribe'],
+ 'followtime' => $userinfo['subscribe_time'],
+ 'unionid' => $userinfo['unionid'],
+ 'tag' => base64_encode(iserializer($userinfo))
+ );
+ pdo_update('mc_mapping_fans', $record, array('openid' => $_SESSION['openid'], 'uniacid' => $_W['uniacid']));
+ } else {
+ $record = array();
+ $record['updatetime'] = TIMESTAMP;
+ $record['nickname'] = stripslashes($userinfo['nickname']);
+ $record['tag'] = base64_encode(iserializer($userinfo));
+ $record['openid'] = $_SESSION['openid'];
+ $record['acid'] = $_W['acid'];
+ $record['uniacid'] = $_W['uniacid'];
+ $record['unionid'] = $userinfo['unionid'];
+ $record['user_from'] = $_W['account']->typeSign == 'wxapp' ? 1 : 0;
+
+ pdo_insert('mc_mapping_fans', $record);
+ }
+
+ if (!empty($fan['uid']) || !empty($_SESSION['uid'])) {
+ $uid = intval($fan['uid']);
+ if (empty($uid)) {
+ $uid = intval($_SESSION['uid']);
+ }
+ $member = mc_fetch($uid, array('nickname', 'gender', 'residecity', 'resideprovince', 'nationality', 'avatar'));
+ $record = array();
+ if (empty($member['nickname']) && !empty($userinfo['nickname'])) {
+ $record['nickname'] = stripslashes($userinfo['nickname']);
+ }
+ if (empty($member['gender']) && !empty($userinfo['sex'])) {
+ $record['gender'] = $userinfo['sex'];
+ }
+ if (empty($member['residecity']) && !empty($userinfo['city'])) {
+ $record['residecity'] = $userinfo['city'] . '市';
+ }
+ if (empty($member['resideprovince']) && !empty($userinfo['province'])) {
+ $record['resideprovince'] = $userinfo['province'] . '省';
+ }
+ if (empty($member['nationality']) && !empty($userinfo['country'])) {
+ $record['nationality'] = $userinfo['country'];
+ }
+ if (empty($member['avatar']) && !empty($userinfo['headimgurl'])) {
+ $record['avatar'] = $userinfo['headimgurl'];
+ }
+ if (!empty($record)) {
+ pdo_update('mc_members', $record, array('uid' => $uid));
+ cache_build_memberinfo($uid);
+ }
+ }
+ return $userinfo;
+ }
+ }
+
+ $state = 'we7sid-' . $_W['session_id'];
+ $_SESSION['dest_url'] = urlencode($_W['siteurl']);
+ if (!empty($url)) {
+ $_SESSION['dest_url'] = urlencode($url);
+ }
+ $oauth_url = uni_account_oauth_host();
+ $url = $oauth_url . "app/index.php?i={$_W['uniacid']}&c=auth&a=oauth&scope=userinfo";
+ $callback = urlencode($url);
+
+ $oauth_account = WeAccount::create($_W['account']['oauth']);
+ $forward = $oauth_account->getOauthUserInfoUrl($callback, $state);
+ header('Location: ' . $forward);
+ exit;
+}
+
+
+function mc_require($uid, $fields, $pre = '') {
+ global $_W, $_GPC;
+ if (empty($fields) || !is_array($fields)) {
+ return false;
+ }
+ $flipfields = array_flip($fields);
+ if (in_array('birth', $fields) || in_array('birthyear', $fields) || in_array('birthmonth', $fields) || in_array('birthday', $fields)) {
+ unset($flipfields['birthyear'], $flipfields['birthmonth'], $flipfields['birthday'], $flipfields['birth']);
+ $flipfields['birthyear'] = 'birthyear';
+ $flipfields['birthmonth'] = 'birthmonth';
+ $flipfields['birthday'] = 'birthday';
+ }
+ if (in_array('reside', $fields) || in_array('resideprovince', $fields) || in_array('residecity', $fields) || in_array('residedist', $fields)) {
+ unset($flipfields['residedist'], $flipfields['resideprovince'], $flipfields['residecity'], $flipfields['reside']);
+ $flipfields['resideprovince'] = 'resideprovince';
+ $flipfields['residecity'] = 'residecity';
+ $flipfields['residedist'] = 'residedist';
+ }
+ $fields = array_keys($flipfields);
+ if (!in_array('uniacid', $fields)) {
+ $fields[] = 'uniacid';
+ }
+ if (!empty($pre)) {
+ $pre .= ' ';
+ }
+ if (empty($uid)) {
+ foreach ($fields as $field) {
+ $profile[$field] = '';
+ }
+ $uniacid = $_W['uniacid'];
+ } else {
+ $profile = mc_fetch($uid, $fields);
+ $uniacid = $profile['uniacid'];
+ }
+ $mc_member_fields = table('mc_member_fields');
+ $mc_member_fields->searchWithUniacid($_W['uniacid']);
+ $mc_member_fields->selectFields(array('b.field', 'b.id as fid', 'a.*'));
+ $system_fields = $mc_member_fields->getAllFields();
+ if (empty($system_fields)) {
+ $system_fields = pdo_getall('profile_fields', array(), array('id', 'field', 'title'), '');
+ }
+
+ $titles = array();
+ foreach ($system_fields as $field) {
+ $titles[$field['field']] = $field['title'];
+ }
+
+ $message = '';
+ $ks = array();
+ foreach ($profile as $k => $v) {
+ if (empty($v)) {
+ $ks[] = $k;
+ $message .= $system_fields[$k]['title'] . ', ';
+ }
+ }
+
+ if (!empty($message)) {
+ $title = '完善资料';
+ if (checksubmit('submit')) {
+ if (in_array('resideprovince', $fields)) {
+ $_GPC['resideprovince'] = $_GPC['reside']['province'];
+ $_GPC['residecity'] = $_GPC['reside']['city'];
+ $_GPC['residedist'] = $_GPC['reside']['district'];
+ }
+ if (in_array('birthyear', $fields)) {
+ $_GPC['birthyear'] = $_GPC['birth']['year'];
+ $_GPC['birthmonth'] = $_GPC['birth']['month'];
+ $_GPC['birthday'] = $_GPC['birth']['day'];
+ }
+ $record = array_elements($fields, $_GPC);
+ if (isset($record['uniacid'])) {
+ unset($record['uniacid']);
+ }
+
+ foreach ($record as $field => $value) {
+ if ($field == 'gender') {
+ continue;
+ }
+ if (empty($value)) {
+ itoast('请填写完整所有资料.', referer(), 'error');
+ }
+ }
+ if (empty($record['nickname']) && !empty($_W['fans']['nickname'])) {
+ $record['nickname'] = $_W['fans']['nickname'];
+ }
+ if (empty($record['avatar']) && !empty($_W['fans']['tag']['avatar'])) {
+ $record['avatar'] = $_W['fans']['tag']['avatar'];
+ }
+ $condition = " AND uid != {$uid} ";
+ if (in_array('email', $fields)) {
+ $mc_members = table('mc_members');
+ $mc_members->searchWithUniacid(mc_current_real_uniacid());
+ $mc_members->searchWithoutUid($uid);
+ $mc_members->searchWithEmail(trim($record['email']));
+ $emailexists = $mc_members->getcolumn('email');
+ if ($emailexists) {
+ itoast('抱歉,您填写的手机号已经被使用,请更新。', 'refresh', 'error');
+ }
+ }
+ if (in_array('mobile', $fields)) {
+ $mc_members = table('mc_members');
+ $mc_members->searchWithUniacid(mc_current_real_uniacid());
+ $mc_members->searchWithoutUid($uid);
+ $mc_members->searchWithEmail(trim($record['mobile']));
+ $mobilexists = $mc_members->getcolumn('mobile');
+ if ($mobilexists) {
+ itoast('抱歉,您填写的手机号已经被使用,请更新。', 'refresh', 'error');
+ }
+ }
+ $insertuid = mc_update($uid, $record);
+ if (empty($uid)) {
+ pdo_update('mc_oauth_fans', array('uid' => $insertuid), array('oauth_openid' => $_W['openid']));
+ pdo_update('mc_mapping_fans', array('uid' => $insertuid), array('openid' => $_W['openid']));
+ }
+ itoast('资料完善成功.', 'refresh', 'success');
+ }
+ load()->func('tpl');
+ load()->model('activity');
+ $filter = array();
+ $filter['status'] = 1;
+ $coupons = activity_coupon_owned($_W['member']['uid'], $filter);
+ $tokens = activity_token_owned($_W['member']['uid'], $filter);
+
+ $setting = uni_setting($_W['uniacid'], array('creditnames', 'creditbehaviors'));
+ $behavior = $setting['creditbehaviors'];
+ $creditnames = $setting['creditnames'];
+ $credits = mc_credit_fetch($_W['member']['uid'], '*');
+ include template('mc/require', TEMPLATE_INCLUDEPATH);
+ exit;
+ }
+ return $profile;
+}
+
+
+function mc_credit_update($uid, $credittype, $creditval = 0, $log = array()) {
+ global $_W;
+ $creditnames = uni_setting_load('creditnames');
+ $creditnames = $creditnames['creditnames'];
+
+ $credittype = trim($credittype);
+ $credittypes = mc_credit_types();
+ $clerk_types = array(
+ '1' => '线上操作',
+ '2' => '系统后台',
+ '3' => '店员',
+ );
+ if (!in_array($credittype, $credittypes)) {
+ return error('-1', "指定的用户积分类型 “{$credittype}”不存在.");
+ }
+ $creditval = floatval($creditval);
+ if (empty($creditval)) {
+ return true;
+ }
+ $value = pdo_getcolumn('mc_members', array('uid' => $uid), $credittype);
+ if ($creditval > 0 || ($value + $creditval >= 0) || $credittype == 'credit6') {
+ pdo_update('mc_members', array($credittype => $value + $creditval), array('uid' => $uid));
+ cache_build_memberinfo($uid);
+ } else {
+ return error('-1', "积分类型为“{$credittype}”的积分不够,无法操作。");
+ }
+ if (empty($log) || !is_array($log)) {
+ load()->func('logging');
+ if (!empty($GLOBALS['site']) && $GLOBALS['site'] instanceof WeModuleSite) {
+ $log = array(
+ $uid,
+ $GLOBALS['site']->module['title'] . '模块内消费' . logging_implode($_GET),
+ $GLOBALS['site']->module['name'],
+ 0,
+ );
+ } elseif (!empty($GLOBALS['_GPC']['m'])) {
+ $modules = uni_modules();
+ $log = array(
+ $uid,
+ $modules[$GLOBALS['_GPC']['m']]['title'] . '模块内消费' . logging_implode($_GET),
+ $GLOBALS['_GPC']['m'],
+ 0,
+ );
+ } else {
+ $log = array($uid, '未记录', 0, 0);
+ }
+ }
+ if ($credittype == 'credit1') {
+ $credittype_name = $creditnames['credit1']['title'];
+ } elseif ($credittype == 'credit2') {
+ $credittype_name = '元';
+ }
+ if (empty($log[1])) {
+ if ($creditval > 0) {
+ $log[1] = $clerk_types[$log[5]] . ': 添加' . $creditval . $credittype_name;
+ } else {
+ $log[1] = $clerk_types[$log[5]] . ': 减少' . -$creditval . $credittype_name;
+ }
+
+ }
+ $clerk_type = intval($log[5]) ? intval($log[5]) : 1;
+ $data = array(
+ 'uid' => $uid,
+ 'credittype' => $credittype,
+ 'uniacid' => $_W['uniacid'],
+ 'num' => $creditval,
+ 'createtime' => TIMESTAMP,
+ 'operator' => intval($log[0]),
+ 'module' => trim($log[2]),
+ 'clerk_id' => intval($log[3]),
+ 'store_id' => intval($log[4]),
+ 'clerk_type' => $clerk_type,
+ 'remark' => $log[1],
+ 'real_uniacid' => mc_current_real_uniacid()
+ );
+ pdo_insert('mc_credits_record', $data);
+ return true;
+}
+
+
+function mc_account_change_operator($clerk_type, $store_id, $clerk_id) {
+ global $stores, $clerks, $_W;
+ if(empty($stores) || empty($clerks)) {
+ $clerks = pdo_getall('activity_clerks', array('uniacid' => $_W['uniacid']), array('id', 'name'), 'id');
+ $stores = pdo_getall('activity_stores', array('uniacid' => $_W['uniacid']), array('id', 'business_name', 'branch_name'), 'id');
+ }
+ $data = array(
+ 'clerk_cn' => '',
+ 'store_cn' => '',
+ );
+ if($clerk_type == 1) {
+ $data['clerk_cn'] = '系统';
+ } elseif($clerk_type == 2) {
+ $data['clerk_cn'] = pdo_getcolumn('users', array('uid' => $clerk_id), 'username');
+ } elseif($clerk_type == 3) {
+ if (empty($clerk_id)) {
+ $data['clerk_cn'] = '本人操作';
+ } else {
+ $data['clerk_cn'] = $clerks[$clerk_id]['name'];
+ }
+ $data['store_cn'] = $stores[$store_id]['business_name'] . ' ' . $stores[$store_id]['branch_name'];
+ }
+ if (empty($data['store_cn'])) {
+ $data['store_cn'] = '暂无门店信息';
+ }
+ if (empty($data['clerk_cn'])) {
+ $data['clerk_cn'] = '暂无操作员信息';
+ }
+ return $data;
+}
+
+function mc_credit_fetch($uid, $types = array()) {
+ if (empty($types) || $types == '*') {
+ $select = array('credit1', 'credit2', 'credit3', 'credit4', 'credit5', 'credit6');
+ } else {
+ $struct = mc_credit_types();
+ foreach ($types as $key => $type) {
+ if (!in_array($type, $struct)) {
+ unset($types[$key]);
+ }
+ }
+ $select = $types;
+ }
+ return pdo_get('mc_members', array('uid' => $uid), $select);
+}
+
+
+function mc_credit_types(){
+ static $struct = array('credit1','credit2','credit3','credit4','credit5','credit6');
+ return $struct;
+}
+
+
+function mc_groups($uniacid = 0) {
+ global $_W;
+ $uniacid = intval($uniacid);
+ if (empty($uniacid)) {
+ $uniacid = $_W['uniacid'];
+ }
+ return pdo_getall('mc_groups', array('uniacid' => $uniacid), array(), 'groupid', 'credit');
+}
+
+
+function mc_fans_groups($force_update = false) {
+ global $_W;
+ $results = table('mc_fans_groups')->getByUniacid($_W['uniacid']);
+ $results = empty($results['groups']) ? array() : $results['groups'];
+
+ if(!empty($results) && !$force_update) {
+ return $results;
+ }
+ $account_api = WeAccount::createByUniacid();
+ if (!$account_api->isTagSupported()) {
+ return array();
+ }
+ $tags = $account_api->fansTagFetchAll();
+ if (is_error($tags)) {
+ itoast($tags['message'], '', 'error');
+ }
+ if (!empty($tags['tags'])) {
+ $tags_tmp = array();
+ foreach ($tags['tags'] as $da) {
+ if ($da['id'] == 1) {
+ continue;
+ }
+ $tags_tmp[$da['id']] = $da;
+ }
+ }
+ if (empty($results)) {
+ $data = array('acid' => $_W['acid'], 'uniacid' => $_W['uniacid'], 'groups' => iserializer($tags_tmp));
+ pdo_insert('mc_fans_groups', $data);
+ } else {
+ $data = array('groups' => iserializer($tags_tmp));
+ pdo_update('mc_fans_groups', $data, array('uniacid' => $_W['uniacid']));
+ }
+ return $tags_tmp;
+}
+
+
+function _mc_login($member) {
+ global $_W;
+ if (!empty($member) && !empty($member['uid'])) {
+ $member = pdo_get('mc_members', array('uid' => $member['uid'], 'uniacid' => $_W['uniacid']), array('uid', 'realname', 'mobile', 'email', 'groupid', 'credit1', 'credit2', 'credit6'));
+ if (!empty($member) && (!empty($member['mobile']) || !empty($member['email']))) {
+ $_W['member'] = $member;
+ $_W['member']['groupname'] = $_W['uniaccount']['groups'][$member['groupid']]['title'];
+ $_SESSION['uid'] = $member['uid'];
+ mc_group_update();
+ if (empty($_W['openid'])) {
+ $fan = mc_fansinfo($member['uid']);
+ if (!empty($fan)) {
+ $_SESSION['openid'] = $fan['openid'];
+ $_W['openid'] = $fan['openid'];
+ $_W['fans'] = $fan;
+ $_W['fans']['from_user'] = $_W['openid'];
+ } else {
+ $_W['openid'] = $member['uid'];
+ $_W['fans'] = array(
+ 'from_user' => $member['uid'],
+ 'follow' => 0
+ );
+ }
+ }
+ isetcookie('logout', '', -60000);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+function mc_fields() {
+ $fields = cache_load(cache_system_key('usersfields'));
+ if (empty($fields)) {
+ load()->model('cache');
+ cache_build_users_struct();
+ $fields = cache_load(cache_system_key('usersfields'));
+ }
+ return $fields;
+}
+
+
+function mc_acccount_fields($uniacid = 0, $is_available = true) {
+ global $_W;
+ $uniacid = !empty($uniacid) ? intval($uniacid) : $_W['uniacid'];
+ $is_available = !empty($is_available) ? 1 : 0;
+
+ $mc_member_fields = table('mc_member_fields');
+ $mc_member_fields->searchWithUniacid($uniacid);
+ $mc_member_fields->searchWithAvailable($is_available);
+ $mc_member_fields->selectFields(array('a.title', 'b.field'));
+ $data = $mc_member_fields->getAllFields();
+ $fields = array();
+ foreach($data as $row) {
+ $fields[$row['field']] = $row['title'];
+ }
+ return $fields;
+}
+
+
+function mc_handsel($touid, $fromuid, $handsel, $uniacid = '') {
+ global $_W;
+ $touid = intval($touid);
+ $fromuid = intval($fromuid);
+ if (empty($uniacid)) {
+ $uniacid = $_W['uniacid'];
+ }
+ $touid_exist = mc_fetch($touid, array('uniacid'));
+ if (empty($touid_exist)) {
+ return error(-1, '赠送积分用户不存在');
+ }
+ if (empty($handsel['module'])) {
+ return error(-1, '没有填写模块名称');
+ }
+ if (empty($handsel['sign'])) {
+ return error(-1, '没有填写赠送积分对象信息');
+ }
+ if (empty($handsel['action'])) {
+ return error(-1, '没有填写赠送积分动作');
+ }
+ $credit_value = intval($handsel['credit_value']);
+
+ $params = array('uniacid' => $uniacid, 'touid' => $touid, 'fromuid' => $fromuid, 'module' => $handsel['module'], 'sign' => $handsel['sign'], 'action' => $handsel['action']);
+ $handsel_exists = pdo_get('mc_handsel', $params);
+ if (!empty($handsel_exists)) {
+ return error(-1, '已经赠送过积分,每个用户只能赠送一次');
+ }
+ $creditbehaviors = pdo_fetchcolumn('SELECT creditbehaviors FROM ' . tablename('uni_settings') . ' WHERE uniacid = :uniacid', array(':uniacid' => $uniacid));
+ $creditbehaviors = iunserializer($creditbehaviors) ? iunserializer($creditbehaviors) : array();
+ if (empty($creditbehaviors['activity'])) {
+ return error(-1, '公众号没有配置积分行为参数');
+ } else {
+ $credittype = $creditbehaviors['activity'];
+ }
+
+ $data = array(
+ 'uniacid' => $uniacid,
+ 'touid' => $touid,
+ 'fromuid' => $fromuid,
+ 'module' => $handsel['module'],
+ 'sign' => $handsel['sign'],
+ 'action' => $handsel['action'],
+ 'credit_value' => $credit_value,
+ 'createtime' => TIMESTAMP
+ );
+ pdo_insert('mc_handsel', $data);
+ $log = array($fromuid, $handsel['credit_log']);
+ mc_credit_update($touid, $credittype, $credit_value, $log);
+ return true;
+}
+
+
+function mc_openid2uid($openid) {
+ global $_W;
+ if (is_numeric($openid)) {
+ return $openid;
+ }
+ if (is_string($openid)) {
+ $fans_info = pdo_get('mc_mapping_fans', array('uniacid' => mc_current_real_uniacid(), 'openid' => $openid), array('uid'));
+ return !empty($fans_info) ? $fans_info['uid'] : false;
+ }
+ if (is_array($openid)) {
+ $uids = array();
+ foreach ($openid as $k => $v) {
+ if (is_numeric($v)) {
+ $uids[] = intval($v);
+ } elseif (is_string($v)) {
+ $fans[] = istripslashes(str_replace(' ', '', $v));
+ }
+ }
+ if (!empty($fans)) {
+ $fans = pdo_getall('mc_mapping_fans', array('uniacid' => mc_current_real_uniacid(), 'openid' => $fans), array('uid', 'openid'), 'uid');
+ $fans = array_keys($fans);
+ $uids = array_merge((array)$uids, $fans);
+ }
+ return $uids;
+ }
+ return false;
+}
+
+
+function mc_uid2openid($uid) {
+ global $_W;
+ if (is_numeric($uid)) {
+ $fans_info = pdo_get('mc_mapping_fans', array('uniacid' => mc_current_real_uniacid(), 'uid' => $uid), 'openid');
+ return !empty($fans_info['openid']) ? $fans_info['openid'] : false;
+ }
+ if (is_string($uid)) {
+ $openid = trim($uid);
+ $openid_exist = pdo_get('mc_mapping_fans', array('openid' => $openid));
+ if (!empty($openid_exist)) {
+ return $openid;
+ } else {
+ return false;
+ }
+ }
+ if (is_array($uid)) {
+ $openids = array();
+ foreach ($uid as $key => $value) {
+ if (is_string($value)) {
+ $openids[] = $value;
+ } elseif (is_numeric($value)) {
+ $uids[] = $value;
+ }
+ }
+ if (!empty($uids)) {
+ $fans_info = pdo_getall('mc_mapping_fans', array('uniacid' => mc_current_real_uniacid(), 'uid' => $uids), array('uid', 'openid'), 'openid');
+ $fans_info = array_keys($fans_info);
+ $openids = array_merge($openids, $fans_info);
+ }
+ return $openids;
+ }
+ return false;
+}
+
+function mc_group_update($uid = 0) {
+ global $_W;
+ if(!$_W['uniaccount']['grouplevel']) {
+ $_W['uniaccount']['grouplevel'] = pdo_getcolumn('uni_settings', array('uniacid' => $_W['uniacid']), 'grouplevel');
+ if (empty($_W['uniaccount']['grouplevel'])) {
+ return true;
+ }
+ }
+ $uid = intval($uid);
+ if($uid <= 0) {
+ $uid = $_W['member']['uid'];
+ $user = $_W['member'];
+ $user['openid'] = $_W['openid'];
+ } else {
+ $user = pdo_get('mc_members', array('uniacid' => $_W['uniacid'], 'uid' => $uid), array('uid', 'realname', 'credit1', 'credit6', 'groupid'));
+ $user['openid'] = pdo_getcolumn('mc_mapping_fans', array('uniacid' => $_W['uniacid'], 'uid' => $uid), 'openid');
+ }
+ if(empty($user)) {
+ return false;
+ }
+ $groupid = $user['groupid'];
+ $credit = $user['credit1'] + $user['credit6'];
+ $groups = mc_groups();
+ if(empty($groups)) {
+ return false;
+ }
+ $data = array();
+ foreach($groups as $group) {
+ $data[$group['groupid']] = $group['credit'];
+ }
+ asort($data);
+ if($_W['uniaccount']['grouplevel'] == 1) {
+ foreach($data as $k => $da) {
+ if($credit >= $da) {
+ $groupid = $k;
+ }
+ }
+ } else {
+ $now_group_credit = $data[$user['groupid']];
+ if($now_group_credit < $credit) {
+ foreach($data as $k => $da) {
+ if($credit >= $da) {
+ $groupid = $k;
+ }
+ }
+ }
+ }
+ if($groupid > 0 && $groupid != $user['groupid']) {
+ pdo_update('mc_members', array('groupid' => $groupid), array('uniacid' => $_W['uniacid'], 'uid' => $uid));
+ cache_build_memberinfo($uid);
+ mc_notice_group($user['openid'], $_W['uniaccount']['groups'][$user['groupid']]['title'], $_W['uniaccount']['groups'][$groupid]['title']);
+ }
+ $user['groupid'] = $groupid;
+ $_W['member']['groupid'] = $groupid;
+ $_W['member']['groupname'] = $_W['uniaccount']['groups'][$groupid]['title'];
+ return $user['groupid'];
+}
+
+function mc_notice_init() {
+ global $_W;
+ if(empty($_W['account'])) {
+ $_W['account'] = uni_fetch($_W['uniacid']);
+ }
+ if(empty($_W['account'])) {
+ return error(1, '创建公众号操作类失败');
+ }
+ if($_W['account']['level'] < 3) {
+ return error(1, '公众号没有经过认证,不能使用模板消息和客服消息');
+ }
+ $account = WeAccount::createByUniacid($_W['uniacid']);
+ if(is_null($account)) {
+ return error(1, '创建公众号操作对象失败');
+ }
+ $setting = uni_setting();
+ $noticetpl = $setting['tplnotice'];
+ $account->noticetpl = $noticetpl;
+ return $account;
+}
+
+
+function mc_notice_public($openid, $title, $sender, $content, $url = '', $remark = '') {
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ $data = array(
+ 'first' => array(
+ 'value' => $title,
+ 'color' => '#ff510'
+ ),
+ 'keyword1' => array(
+ 'value' => $sender,
+ 'color' => '#ff510'
+ ),
+ 'keyword2' => array(
+ 'value' => $content,
+ 'color' => '#ff510'
+ ),
+ 'remark' => array(
+ 'value' => $remark,
+ 'color' => '#ff510'
+ ),
+ );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['public'], $data, $url);
+ return $status;
+}
+
+
+function mc_notice_recharge($openid, $uid = 0, $num = 0, $url = '', $remark = '') {
+ global $_W;
+ if(!$uid) {
+ $uid = $_W['member']['uid'];
+ }
+ if(!$uid || !$num || empty($openid)) {
+ return error(-1, '参数错误');
+ }
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ $credit = mc_credit_fetch($uid);
+ $time = date('Y-m-d H:i');
+ if(empty($url)) {
+ $url = murl('mc/bond/credits', array('credittype' => 'credit2', 'type' => 'record', 'period' => '1'), true, true);
+ }
+ if($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY && !empty($account->noticetpl['recharge']['tpl'])) {
+ $data = array(
+ 'first' => array(
+ 'value' => "您好,您在{$time}进行会员余额充值,充值金额{$num}元,充值后余额为{$credit['credit2']}元",
+ 'color' => '#ff510'
+ ),
+ 'accountType' => array(
+ 'value' => '会员UID',
+ 'color' => '#ff510'
+ ),
+ 'account' => array(
+ 'value' => $uid,
+ 'color' => '#ff510'
+ ),
+ 'amount' => array(
+ 'value' => $num . '元',
+ 'color' => '#ff510'
+ ),
+ 'result' => array(
+ 'value' => '充值成功',
+ 'color' => '#ff510'
+ ),
+ 'remark' => array(
+ 'value' => "{$remark}" ,
+ 'color' => '#ff510'
+ ),
+ );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['recharge']['tpl'], $data, $url);
+ }
+ if($_W['account']['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || is_error($status) || empty($account->noticetpl['recharge']['tpl'])) {
+ $info = "【{$_W['account']['name']}】充值通知\n";
+ $info .= "您在{$time}进行会员余额充值,充值金额【{$num}】元,充值后余额【{$credit['credit2']}】元。\n";
+ $info .= !empty($remark) ? "备注:{$remark}\n\n" : '';
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ }
+ return $status;
+}
+
+
+function mc_notice_credit2($openid, $uid, $credit2_num, $credit1_num = 0, $store = '线下消费', $url = '', $remark = '谢谢惠顾,点击查看详情') {
+ global $_W;
+ if(!$uid) {
+ $uid = $_W['member']['uid'];
+ }
+ if(!$uid || !$credit2_num || empty($openid)) {
+ return error(-1, '参数错误');
+ }
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ $credit = mc_credit_fetch($uid);
+ $time = date('Y-m-d H:i');
+ if(empty($url)) {
+ $url = murl('mc/bond/credits', array('credittype' => 'credit2', 'type' => 'record', 'period' => '1'), true, true);
+ }
+ $credit_setting = uni_setting_load('creditnames');
+ $credit1_title = empty($credit_setting['creditnames']['credit1']['title']) ? '积分' : $credit_setting['creditnames']['credit1']['title'];
+ $credit2_title = empty($credit_setting['creditnames']['credit2']['title']) ? '余额' : $credit_setting['creditnames']['credit2']['title'];
+
+ if($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY && !empty($account->noticetpl['credit2']['tpl'])) {
+ $data = array(
+ 'first' => array(
+ 'value' => "您好,您在{$time}有{$credit2_title}消费",
+ 'color' => '#ff510'
+ ),
+ 'keyword1' => array(
+ 'value' => abs($credit2_num) . '元',
+ 'color' => '#ff510'
+ ),
+ 'keyword2' => array(
+ 'value' => floatval($credit1_num) . $credit1_title,
+ 'color' => '#ff510'
+ ),
+ 'keyword3' => array(
+ 'value' => trim($store),
+ 'color' => '#ff510'
+ ),
+ 'keyword4' => array(
+ 'value' => $credit['credit2'] . '元',
+ 'color' => '#ff510'
+ ),
+ 'keyword5' => array(
+ 'value' => $credit['credit1'] . $credit1_title,
+ 'color' => '#ff510'
+ ),
+ 'remark' => array(
+ 'value' => "{$remark}" ,
+ 'color' => '#ff510'
+ ),
+ );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['credit2']['tpl'], $data, $url);
+ }
+ if($_W['account']['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || is_error($status) || empty($account->noticetpl['credit2']['tpl'])) {
+ $info = "【{$_W['account']['name']}】消费通知\n";
+ $info .= "您在{$time}进行会员{$credit2_title}消费,消费金额【{$credit2_num}】元,获得{$credit1_title}【{$credit1_num}】,消费后余额【{$credit['credit2']}】元,消费后{$credit1_title}【{$credit['credit1']}】。\n";
+ $info .= !empty($remark) ? "备注:{$remark}\n\n" : '';
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ }
+ return $status;
+}
+
+
+function mc_notice_credit1($openid, $uid, $credit1_num, $tip, $url = '', $remark = '谢谢惠顾,点击查看详情') {
+ global $_W;
+ if(!$uid) {
+ $uid = $_W['member']['uid'];
+ }
+ if(!$uid || !$credit1_num || empty($tip)) {
+ return error(-1, '参数错误');
+ }
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ $credit = mc_credit_fetch($uid);
+ $time = date('Y-m-d H:i');
+ if(empty($url)) {
+ $url = murl('mc/bond/credits', array('credittype' => 'credit1', 'type' => 'record', 'period' => '1'), true, true);
+ }
+ $credit1_num = floatval($credit1_num);
+ $type = '消费';
+ if($credit1_num > 0) {
+ $type = '到账';
+ }
+ $username = $_W['member']['realname'];
+ if(empty($username)) {
+ $username = $_W['member']['nickname'];
+ }
+ if(empty($username)) {
+ $username = $uid;
+ }
+ $credit_setting = uni_setting_load('creditnames');
+ $credit1_title = empty($credit_setting['creditnames']['credit1']['title']) ? '积分' : $credit_setting['creditnames']['credit1']['title'];
+
+ if($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY && !empty($account->noticetpl['credit1']['tpl'])) {
+ $data = array(
+ 'first' => array(
+ 'value' => "您好,您在{$time}有{$credit1_title}变更",
+ 'color' => '#ff510'
+ ),
+ 'keyword1' => array(
+ 'value' => "原有{$credit1_title} : " . ($credit['credit1'] - $credit1_num),
+ 'color' => '#ff510'
+ ),
+ 'keyword2' => array(
+ 'value' => "现有{$credit1_title} : " . $credit['credit1'],
+ 'color' => '#ff510'
+ ),
+ 'keyword3' => array(
+ 'value' => "时间 : {$time} ",
+ 'color' => '#ff510'
+ ),
+ 'remark' => array(
+ 'value' => "{$remark}" ,
+ 'color' => '#ff510'
+ ),
+ );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['credit1']['tpl'], $data, $url);
+ }
+ if($_W['account']['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || empty($account->noticetpl['credit1']['tpl']) || is_error($status)) {
+ $info = "【{$_W['account']['name']}】{$credit1_title}变更通知\n";
+ $info .= "您在{$time}有{$credit1_title}{$type},{$type}{$credit1_title}【{$credit1_num}】,变更原因:【{$tip}】,消费后账户{$credit1_title}余额【{$credit['credit1']}】。\n";
+ $info .= !empty($remark) ? "备注:{$remark}\n\n" : '';
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ }
+ return $status;
+}
+
+function mc_notice_group($openid, $old_group, $now_group, $url = '', $remark = '点击查看详情') {
+ global $_W;
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ $time = date('Y-m-d H:i');
+ if(empty($url)) {
+ $url = murl('mc/home', array(), true, true);
+ }
+ if($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY && !empty($account->noticetpl['group']['tpl'])) {
+ $data = array(
+ 'first' => array(
+ 'value' => "您好,您的会员组变更为{$now_group}",
+ 'color' => '#ff510'
+ ),
+ 'grade1' => array(
+ 'value' => $old_group,
+ 'color' => '#ff510'
+ ),
+ 'grade2' => array(
+ 'value' => $now_group,
+ 'color' => '#ff510'
+ ),
+ 'time' => array(
+ 'value' => $time,
+ 'color' => '#ff510'
+ ),
+ 'remark' => array(
+ 'value' => "{$remark}",
+ 'color' => '#ff510'
+ ),
+ );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['group']['tpl'], $data, $url);
+ }
+ if($_W['account']['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || is_error($status) || empty($account->noticetpl['group']['tpl'])) {
+ $info = "【{$_W['account']['name']}】会员组变更通知\n";
+ $info .= "您的会员等级在{$time}由{$old_group}变更为{$now_group}。\n";
+ $info .= !empty($remark) ? "备注:{$remark}\n\n" : '';
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ }
+ return $status;
+}
+
+
+function mc_notice_nums_plus($openid, $type, $num, $total_num, $remark = '感谢您的支持,祝您生活愉快!') {
+ global $_W;
+ if(empty($num) || empty($total_num) || empty($type)) {
+ return error(-1, '参数错误');
+ }
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ $time = date('Y-m-d H:i');
+ if($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY && !empty($account->noticetpl['nums_plus']['tpl'])) {
+ $data = array(
+ 'first' => array(
+ 'value' => "您好,您的{$type}已充次成功",
+ 'color' => '#ff510'
+ ),
+ 'keyword1' => array(
+ 'value' => $time,
+ 'color' => '#ff510'
+ ),
+ 'keyword2' => array(
+ 'value' => $num . '次',
+ 'color' => '#ff510'
+ ),
+ 'keyword3' => array(
+ 'value' => $total_num . '次',
+ 'color' => '#ff510'
+ ),
+ 'keyword4' => array(
+ 'value' => '用完为止',
+ 'color' => '#ff510'
+ ),
+ 'remark' => array(
+ 'value' => "{$remark}" ,
+ 'color' => '#ff510'
+ ),
+ );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['nums_plus']['tpl'], $data);
+ }
+ if($_W['account']['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || is_error($status) || empty($account->noticetpl['nums_plus']['tpl'])) {
+ $info = "【{$_W['account']['name']}】-【{$type}】充值通知\n";
+ $info .= "您的{$type}已充值成功,本次充次【{$num}】次,总剩余【{$total_num}】次。\n";
+ $info .= !empty($remark) ? "备注:{$remark}\n\n" : '';
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ }
+ return $status;
+}
+
+
+function mc_notice_nums_times($openid, $card_id, $type, $num, $remark = '感谢您对本店的支持,欢迎下次再来!') {
+ global $_W;
+ if(empty($num) || empty($type) || empty($card_id)) {
+ return error(-1, '参数错误');
+ }
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ $time = date('Y-m-d H:i');
+ if($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY && !empty($account->noticetpl['nums_times']['tpl'])) {
+ $data = array(
+ 'first' => array(
+ 'value' => "您好,您的{$type}已成功使用了【1】次。",
+ 'color' => '#ff510'
+ ),
+ 'keyword1' => array(
+ 'value' => $card_id,
+ 'color' => '#ff510'
+ ),
+ 'keyword2' => array(
+ 'value' => $time,
+ 'color' => '#ff510'
+ ),
+ 'keyword3' => array(
+ 'value' => $num . '次',
+ 'color' => '#ff510'
+ ),
+ 'keyword4' => array(
+ 'value' => '用完为止',
+ 'color' => '#ff510'
+ ),
+ 'remark' => array(
+ 'value' => "{$remark}" ,
+ 'color' => '#ff510'
+ ),
+ );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['nums_times']['tpl'], $data);
+ }
+ if($_W['account']['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || is_error($status) || empty($account->noticetpl['nums_times']['tpl'])) {
+ $info = "【{$_W['account']['name']}】-【{$type}】消费通知\n";
+ $info .= "您的{$type}已成功使用了一次,总剩余【{$num}】次,消费时间【{$time}】。\n";
+ $info .= !empty($remark) ? "备注:{$remark}\n\n" : '';
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ }
+ return $status;
+}
+
+
+function mc_notice_times_plus($openid, $card_id, $type, $fee, $days, $endtime = '', $remark = '感谢您对本店的支持,欢迎下次再来!') {
+ global $_W;
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ if($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY && empty($account->noticetpl['times_plus']['tpl'])) {
+ $data = array(
+ 'first' => array(
+ 'value' => "您好,您的{$type}已续费成功。",
+ 'color' => '#ff510'
+ ),
+ 'keynote1' => array(
+ 'value' => $type,
+ 'color' => '#ff510'
+ ),
+ 'keynote2' => array(
+ 'value' => $card_id,
+ 'color' => '#ff510'
+ ),
+ 'keynote3' => array(
+ 'value' => $fee . '元',
+ 'color' => '#ff510'
+ ),
+ 'keynote4' => array(
+ 'value' => $days . '天',
+ 'color' => '#ff510'
+ ),
+ 'keynote5' => array(
+ 'value' => $endtime,
+ 'color' => '#ff510'
+ ),
+ 'remark' => array(
+ 'value' => "{$remark}" ,
+ 'color' => '#ff510'
+ ),
+ );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['times_plus']['tpl'], $data);
+ }
+ if($_W['account']['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || is_error($status) || empty($account->noticetpl['times_plus']['tpl'])) {
+ $info = "【{$_W['account']['name']}】-【{$type}】续费通知\n";
+ $info .= "您的{$type}已成功续费,续费时长【{$days}】天,续费金额【{$fee}】元,有效期至【{$endtime}】。\n";
+ $info .= !empty($remark) ? "备注:{$remark}\n\n" : '';
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ }
+ return $status;
+}
+
+
+function mc_notice_times_times($openid, $title, $type, $endtime = '', $remark = '请注意时间,防止服务失效!', $card_sn = '', $use_time = '', $has_time = '') {
+ global $_W;
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+
+ if($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY && !empty($account->noticetpl['times_times']['tpl'])) {
+ $data = array(
+ 'first' => array('value' => $title, 'color' => '#ff510'), 'keyword1' => array('value' => $card_sn, 'color' => '#ff510'), 'keyword2' => array('value' => $use_time, 'color' => '#ff510'), 'keyword3' => array('value' => $has_time, 'color' => '#ff510'), 'keyword4' => array('value' => $endtime, 'color' => '#ff510'), 'remark' => array('value' => "{$remark}" ,'color' => '#ff510'), );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['times_times']['tpl'], $data);
+ }
+ if($_W['account']['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || is_error($status) || empty($account->noticetpl['times_times']['tpl'])) {
+ $info = "【{$_W['account']['name']}】-【{$type}】服务到期通知\n";
+ $info .= "您的{$type}即将到期,有效期至【{$endtime}】。\n";
+ $info .= !empty($remark) ? "备注:{$remark}\n\n" : '';
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ }
+ return $status;
+}
+
+
+function mc_notice_pay_success($openid, $username, $order_sn, $money, $goods_info, $title = '尊敬的客户,您的订单已支付成功', $remark = '', $url = '') {
+ global $_W;
+ $money = sprintf("%.2f", $money);
+ if(empty($money)|| empty($openid)) {
+ return error(-1, '参数错误');
+ }
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ if($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY && !empty($account->noticetpl['pay_success']['tpl'])) {
+ $data = array(
+ 'first' => array(
+ 'value' => $title,
+ 'color' => '#ff510'
+ ),
+ 'keyword1' => array(
+ 'value' => $username,
+ 'color' => '#ff510'
+ ),
+ 'keyword2' => array(
+ 'value' => $order_sn,
+ 'color' => '#ff510'
+ ),
+ 'keyword3' => array(
+ 'value' => $money. '元',
+ 'color' => '#ff510'
+ ),
+ 'keyword4' => array(
+ 'value' => $goods_info,
+ 'color' => '#ff510'
+ ),
+ 'remark' => array(
+ 'value' => $remark ,
+ 'color' => '#ff510'
+ ),
+ );
+ $status = $account->sendTplNotice($openid, $account->noticetpl['pay_success']['tpl'], $data, $url);
+ }
+ if($_W['account']['level'] == ACCOUNT_SUBSCRIPTION_VERIFY || is_error($status) || empty($account->noticetpl['pay_success']['tpl'])) {
+ $info = "【{$_W['account']['name']}】付款成功通知\n";
+ $info .= "您编号为{$order_sn}的订单已成功支付{$money}。\n";
+ $info .= "商品信息:{$goods_info}。\n";
+ $info .= !empty($remark) ? "备注:{$remark}\n\n" : '';
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ }
+ return $status;
+}
+
+
+function mc_notice_consume($openid, $title, $content, $url = '') {
+ global $_W;
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ if($_W['account']['level'] == 4) {
+ mc_notice_credit2($openid, $content['uid'], $content['credit2_num'], $content['credit1_num'], $content['store'], '', $content['remark']);
+ }
+ if($_W['account']['level'] == 3) {
+ mc_notice_custom_text($openid, $title, $content);
+ }
+ return true;
+}
+
+function mc_notice_custom_text($openid, $title, $info) {
+ global $_W;
+ $account = mc_notice_init();
+ if(is_error($account)) {
+ return error(-1, $account['message']);
+ }
+ $custom = array(
+ 'msgtype' => 'text',
+ 'text' => array('content' => urlencode($title . '\n' . $info)),
+ 'touser' => $openid,
+ );
+ $status = $account->sendCustomNotice($custom);
+ return $status;
+}
+
+function mc_plugins() {
+ $plugins = array(
+ 'mc_card_manage' => array(
+ 'title' => '会员卡',
+ 'name' => 'mc_card_manage',
+ 'description' => '提供粉丝可开通会员卡并可以设置充值、消费金额及积分的增减策略',
+ ),
+ 'activity_discount_manage' => array(
+ 'title' => '兑换中心',
+ 'name' => 'activity_discount_manage',
+ 'description' => '提供粉丝可通过积分进行代金劵、折扣劵或是真实物品的兑换',
+ ),
+ 'wechat_card_manage' => array(
+ 'title' => '微信卡券',
+ 'name' => 'wechat_card_manage',
+ 'description' => '提供粉丝可通过积分进行代金劵、折扣劵或是真实物品的兑换',
+ ),
+
+ );
+ return $plugins;
+}
+
+
+function mc_init_fans_info($openid, $force_init_member = false){
+ global $_W;
+ static $account_api;
+ if (empty($account_api)) {
+ $account_api = WeAccount::createByUniacid();
+ }
+ if (is_array($openid)) {
+ $fans_list = $account_api->fansBatchQueryInfo($openid);
+ } else {
+ $fans_list = $account_api->fansQueryInfo($openid);
+ }
+ if (empty($fans_list) || is_error($fans_list)) {
+ if ($fans_list['errno'] == '48001') {
+ $fans_list = array(
+ 'openid' => $openid,
+ 'subscribe_time' => TIMESTAMP,
+ 'subscribe' => 1,
+ );
+ } else {
+ return true;
+ }
+ }
+ if (!is_array($openid)) {
+ $fans_list = array($fans_list);
+ }
+ foreach ($fans_list as $fans) {
+ $fans_mapping = mc_fansinfo($fans['openid']);
+ if (empty($fans['subscribe']) && empty($fans_mapping)) {
+ pdo_update('mc_mapping_fans', array('follow' => 0, 'unfollowtime' => TIMESTAMP), array('openid' => $fans['openid']));
+ continue;
+ }
+ if (!empty($fans_mapping) && $fans['openid'] == $fans_mapping['openid']) {
+ $fans = array_merge($fans_mapping['tag'], $fans);
+ }
+ unset($fans['remark'], $fans['subscribe_scene'], $fans['qr_scene'], $fans['qr_scene_str']);
+ $fans_update_info = array(
+ 'openid' => $fans['openid'],
+ 'acid' => $_W['acid'],
+ 'uniacid' => $_W['uniacid'],
+ 'updatetime' => TIMESTAMP,
+ 'followtime' => $fans['subscribe_time'],
+ 'follow' => $fans['subscribe'],
+ 'nickname' => strip_emoji(stripcslashes($fans['nickname'])),
+ 'tag' => '',
+ 'unionid' => $fans['unionid'],
+ 'groupid' => !empty($fans['tagid_list']) ? (','.join(',', $fans['tagid_list']).',') : '',
+ 'user_from' => $_W['account']->typeSign == 'wxapp' ? 1 : 0,
+ );
+ if (empty($fans_update_info['groupid'])) {
+ unset($fans_update_info['groupid']);
+ }
+ if ($force_init_member) {
+ $member_update_info = array(
+ 'uniacid' => $_W['uniacid'],
+ 'nickname' => $fans_update_info['nickname'],
+ 'avatar' => $fans['headimgurl'],
+ 'gender' => $fans['sex'],
+ 'nationality' => $fans['country'],
+ 'resideprovince' => $fans['province'] . '省',
+ 'residecity' => $fans['city'] . '市',
+ );
+
+ if (empty($fans_mapping['uid'])) {
+ $email = md5($fans['openid']).'@we7.cc';
+ $email_exists_member = pdo_getcolumn('mc_members', array('email' => $email, 'uniacid' => $_W['uniacid']), 'uid');
+ if (!empty($email_exists_member)) {
+ $uid = $email_exists_member;
+ } else {
+ $member_update_info['groupid'] = pdo_getcolumn('mc_groups', array('uniacid' => $_W['uniacid'], 'isdefault' => 1), 'groupid');
+ $member_update_info['salt'] = random(8);
+ $member_update_info['password'] = md5($fans['openid'] . $member_update_info['salt'] . $_W['config']['setting']['authkey']);
+ $member_update_info['email'] = $email;
+ $member_update_info['createtime'] = TIMESTAMP;
+
+ pdo_insert('mc_members', $member_update_info);
+ $uid = pdo_insertid();
+ }
+ $fans_update_info['uid'] = $uid;
+ } else {
+ $fans_update_info['uid'] = $fans_mapping['uid'];
+ pdo_update('mc_members', $member_update_info, array('uid' => $fans_mapping['uid']));
+ cache_delete(cache_system_key('memberinfo', array('uid' => $fans_mapping['uid'])));
+ }
+ }
+
+ if (!empty($fans_mapping)) {
+ pdo_update('mc_mapping_fans', $fans_update_info, array('fanid' => $fans_mapping['fanid']));
+ pdo_update('mc_fans_tag', array('fanid' => $fans_mapping['fanid']), array('openid' => $fans_mapping['openid']));
+ } else {
+ $fans_update_info['salt'] = random(8);
+ $fans_update_info['unfollowtime'] = 0;
+ $fans_update_info['followtime'] = TIMESTAMP;
+ pdo_insert('mc_mapping_fans', $fans_update_info);
+ $fans_mapping['fanid'] = pdo_insertid();
+ }
+ if (!empty($fans['tagid_list'])) {
+ $groupid = $fans['tagid_list'];
+ @sort($groupid, SORT_NATURAL);
+ mc_insert_fanstag_mapping($fans_mapping['fanid'], $groupid);
+ }
+
+ $mc_fans_tag_table = table('mc_fans_tag');
+ $mc_fans_tag_fields = mc_fans_tag_fields();
+ $fans_tag_update_info = array();
+ foreach ($fans as $fans_field_key => $fans_field_info) {
+ if (in_array($fans_field_key, array_keys($mc_fans_tag_fields))) {
+ $fans_tag_update_info[$fans_field_key] = $fans_field_info;
+ }
+ $fans_tag_update_info['tagid_list'] = iserializer($fans_tag_update_info['tagid_list']);
+ }
+
+ $fans_tag_exists = $mc_fans_tag_table->getByOpenid($fans_tag_update_info['openid']);
+ if (!empty($fans_tag_exists)) {
+ pdo_update('mc_fans_tag', $fans_tag_update_info, array('openid' => $fans_tag_update_info['openid']));
+ } else {
+ pdo_insert('mc_fans_tag', $fans_tag_update_info);
+ }
+ }
+ if (is_string($openid) && !empty($fans_update_info)) {
+ return $fans_update_info;
+ } else {
+ return true;
+ }
+}
+
+
+function mc_insert_fanstag_mapping($fanid, $groupid_list){
+ if (empty($groupid_list)) {
+ return true;
+ }
+
+ foreach ($groupid_list as $groupid) {
+ $record_mapping = array(
+ 'fanid' => $fanid,
+ 'tagid' => $groupid
+ );
+ $isfound = pdo_getcolumn('mc_fans_tag_mapping', $record_mapping, 'id');
+ if (empty($isfound)) {
+ pdo_insert('mc_fans_tag_mapping', $record_mapping);
+ }
+ }
+ pdo_delete('mc_fans_tag_mapping', array('fanid' => $fanid, 'tagid !=' => $groupid_list));
+ return true;
+}
+
+
+function mc_batch_insert_fanstag_mapping($fanid_list, $tagid_list){
+ if (!is_array($fanid_list) || !is_array($tagid_list)) {
+ return false;
+ }
+ foreach ($fanid_list as $fanid) {
+ foreach ($tagid_list as $tagid) {
+ $fanid = intval($fanid);
+ $tagid = intval($tagid);
+ pdo_insert('mc_fans_tag_mapping', array('fanid' => $fanid, 'tagid' => $tagid), true);
+ }
+ }
+ return true;
+}
+
+
+function mc_show_tag($groupid){
+ if ($groupid) {
+ $fans_tag = mc_fans_groups();
+ $tagid_arr = explode(',', trim($groupid, ','));
+ foreach ($tagid_arr as $tagid) {
+ $tag_show .= $fans_tag[$tagid]['name'] . ', ';
+ }
+ $tag_show = rtrim($tag_show, ', ');
+ } else {
+ $tag_show = '无标签';
+ }
+ return $tag_show;
+}
+
+function mc_card_settings_hide($item = '') {
+ $mcFields = mc_acccount_fields();
+ if ($item == 'personal_info') {
+ if (empty($mcFields['idcard']) && empty($mcFields['height']) && empty($mcFields['weight']) && empty($mcFields['bloodtype']) && empty($mcFields['zodiac']) && empty($mcFields['constellation']) && empty($mcFields['site']) && empty($mcFields['affectivestatus']) && empty($mcFields['lookingfor']) && empty($mcFields['bio']) && empty($mcFields['interest'])) {
+ return true;
+ }
+ } elseif ($item == 'contact_method') {
+ if (empty($mcFields['telephone']) && empty($mcFields['qq']) && empty($mcFields['msn']) && empty($mcFields['taobao']) && empty($mcFields['alipay'])) {
+ return true;
+ }
+ } elseif ($item == 'education_info') {
+ if (empty($mcFields['education']) && empty($mcFields['graduateschool']) && empty($mcFields['studentid'])) {
+ return true;
+ }
+ } elseif ($item == 'jobedit') {
+ if (empty($mcFields['company']) && empty($mcFields['occupation']) && empty($mcFields['position']) && empty($mcFields['revenue'])) {
+ return true;
+ }
+ } elseif (empty($item)) {
+ if (empty($mcFields['idcard']) && empty($mcFields['height']) && empty($mcFields['weight'])
+ && empty($mcFields['bloodtype']) && empty($mcFields['zodiac']) && empty($mcFields['constellation'])
+ && empty($mcFields['site']) && empty($mcFields['affectivestatus']) && empty($mcFields['lookingfor'])
+ && empty($mcFields['bio']) && empty($mcFields['interest']) && empty($mcFields['telephone'])
+ && empty($mcFields['qq']) && empty($mcFields['msn']) && empty($mcFields['taobao'])
+ && empty($mcFields['alipay']) && empty($mcFields['education']) && empty($mcFields['graduateschool'])
+ && empty($mcFields['studentid']) && empty($mcFields['company']) && empty($mcFields['occupation'])
+ && empty($mcFields['position']) && empty($mcFields['revenue']) && empty($mcFields['avatar'])
+ && empty($mcFields['nickname']) && empty($mcFields['realname']) && empty($mcFields['gender'])
+ && empty($mcFields['birthyear']) && empty($mcFields['resideprovince'])) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+function mc_card_grant_credit($openid, $card_fee, $storeid = 0, $modulename) {
+ global $_W;
+ $setting = uni_setting($_W['uniacid'], array('creditbehaviors'));
+ load()->model('card');
+ $recharges_set = card_params_setting('cardRecharge');
+ $card_settings = card_setting();
+ $grant_rate = $card_settings['grant_rate'];
+ $grant_rate_switch = intval($recharges_set['params']['grant_rate_switch']);
+ $grant_credit1_enable = false;
+ if (!empty($grant_rate)) {
+ if (empty($recharges_set['params']['recharge_type'])) {
+ $grant_credit1_enable = true;
+ } else {
+ if ($grant_rate_switch == '1') {
+ $grant_credit1_enable = true;
+ }
+ }
+ }
+ if (!empty($grant_credit1_enable)) {
+ $num = $card_fee * $grant_rate;
+ $tip = "用户消费{$card_fee}元,支付金额{$card_fee},积分赠送比率为:【1:{$grant_rate}】,共赠送【{$num}】积分";
+ mc_credit_update($openid, 'credit1', $num, array('0', $tip, $modulename, 0, $storeid, 3));
+ return error(0, $num);
+ } else {
+ return error(-1, '');
+ }
+}
+
+
+function mc_current_real_uniacid() {
+ global $_W;
+ if (!empty($_W['account']['link_uniacid']) || (!empty($_W['account']) && $_W['uniacid'] != $_W['account']['uniacid'])) {
+ return $_W['account']['uniacid'];
+ } else {
+ return $_W['uniacid'];
+ }
+}
+
+function mc_parse_profile($profile) {
+ global $_W;
+ if (empty($profile)) {
+ return array();
+ }
+ if (!empty($profile['avatar'])) {
+ $profile['avatar'] = tomedia($profile['avatar']);
+ } else {
+ $profile['avatar'] = './resource/images/nopic.jpg';
+ }
+ $profile['avatarUrl'] = $profile['avatar'];
+ $profile['birth'] = array(
+ 'year' => $profile['birthyear'],
+ 'month' => $profile['birthmonth'],
+ 'day' => $profile['birthday'],
+ );
+ $profile['reside'] = array(
+ 'province' => $profile['resideprovince'],
+ 'city' => $profile['city'],
+ 'district' => $profile['dist']
+ );
+ if(empty($profile['email']) || (!empty($profile['email']) && substr($profile['email'], -6) == 'we7.cc' && strlen($profile['email']) == 39)) {
+ $profile['email'] = '';
+ }
+ return $profile;
+};
+
+function mc_member_export_parse($members, $header = array(), $type = 'userinfo'){
+ if (empty($members)) {
+ return false;
+ }
+ if ('userinfo' == $type) {
+ $groups = mc_groups();
+ }
+ $keys = array_keys($header);
+ $html = "\xEF\xBB\xBF";
+ foreach ($header as $li) {
+ $html .= $li . "\t ,";
+ }
+ $html .= "\n";
+ $count = count($members);
+ $pagesize = ceil($count/5000);
+ for ($j = 1; $j <= $pagesize; $j++) {
+ $list = array_slice($members, ($j-1) * 5000, 5000);
+ if (!empty($list)) {
+ $size = ceil(count($list) / 500);
+ for ($i = 0; $i < $size; $i++) {
+ $buffer = array_slice($list, $i * 500, 500);
+ $user = array();
+ foreach ($buffer as $row) {
+ if ('userinfo' == $type) {
+ if (strexists($row['email'], 'we7.cc')) {
+ $row['email'] = '';
+ }
+ $row['groupid'] = $groups[$row['groupid']]['title'];
+ } elseif ('creditinfo' == $type) {
+ $row['credittype'] = $row['credittype'] == 'credit1' ? '积分' : '余额';
+ }
+ $row['createtime'] = date('Y-m-d H:i:s', $row['createtime']);
+ foreach ($keys as $key) {
+ $data[] = $row[$key];
+ }
+ $user[] = implode("\t ,", $data) . "\t ,";
+ unset($data);
+ }
+ $html .= implode("\n", $user) . "\n";
+ }
+ }
+ }
+ return $html;
+}
+
+
+function mc_fans_has_member_info($tag) {
+ if (is_base64($tag)) {
+ $tag = base64_decode($tag);
+ }
+ if (is_serialized($tag)) {
+ $tag = iunserializer($tag);
+ }
+ $profile = array();
+ if (!empty($tag)) {
+ if(!empty($tag['nickname'])) {
+ $profile['nickname'] = $tag['nickname'];
+ }
+ if(!empty($tag['sex'])) {
+ $profile['gender'] =$tag['sex'];
+ }
+ if(!empty($tag['province'])) {
+ $profile['resideprovince'] = $tag['province'];
+ }
+ if(!empty($tag['city'])) {
+ $profile['residecity'] = $tag['city'];
+ }
+ if(!empty($tag['country'])) {
+ $profile['nationality'] = $tag['country'];
+ }
+ if(!empty($tag['headimgurl'])) {
+ $profile['avatar'] = rtrim($tag['headimgurl']);
+ }
+ }
+ return $profile;
+}
+
+
+function mc_fans_chats_record_formate($chat_record) {
+ load()->model('material');
+ if (empty($chat_record)) {
+ return array();
+ }
+ foreach ($chat_record as &$record) {
+ if ($record['flag'] == FANS_CHATS_FROM_SYSTEM) {
+ $record['content'] = iunserializer($record['content']);
+ if (isset($record['content']['media_id']) && !empty($record['content']['media_id'])) {
+ $material = material_get($record['content']['media_id']);
+ switch($record['msgtype']) {
+ case 'image':
+ $record['content'] = tomedia($material['attachment']);
+ break;
+ case 'mpnews':
+ $record['content'] = $material['news'][0]['thumb_url'];
+ break;
+ case 'music':
+ $record['content'] = $material['filename'];
+ break;
+ case 'voice':
+ $record['content'] = $material['filename'];
+ break;
+ case 'voice':
+ $record['content'] = $material['filename'];
+ break;
+ }
+ } else {
+ $record['content'] = urldecode($record['content']['content']);
+ }
+ }
+
+ $record['createtime'] = date('Y-m-d H:i', $record['createtime']);
+ }
+ return $chat_record;
+}
+
+
+function mc_send_content_formate($data) {
+ $type = addslashes($data['type']);
+ if ($type == 'image') {
+ $contents = explode(',', htmlspecialchars_decode($data['content']));
+ $get_content = array_rand($contents, 1);
+ $content = trim($contents[$get_content], '\"');
+ }
+ if ($type == 'text' || $type == 'voice') {
+ $contents = htmlspecialchars_decode($data['content']);
+ $contents = explode(',', $contents);
+ $get_content = array_rand($contents, 1);
+ $content = trim($contents[$get_content], '\"');
+ }
+ if ($type == 'news' || $type == 'music') {
+ $contents = htmlspecialchars_decode($data['content']);
+ $contents = json_decode('[' . $contents . ']', true);
+ $get_content = array_rand($contents, 1);
+ $content = $contents[$get_content];
+ }
+
+ $send['touser'] = trim($data['openid']);
+ $send['msgtype'] = $type;
+ if ($type == 'text') {
+ $send['text'] = array('content' => urlencode(emoji_unicode_decode($content)));
+ } elseif ($type == 'image') {
+ $send['image'] = array('media_id' => $content);
+ $material = material_get($content);
+ $content = $material['attachment'];
+ } elseif ($type == 'voice') {
+ $send['voice'] = array('media_id' => $content);
+ } elseif($type == 'video') {
+ $content = json_decode($content, true);
+ $send['video'] = array(
+ 'media_id' => $content['mediaid'],
+ 'thumb_media_id' => '',
+ 'title' => urlencode($content['title']),
+ 'description' => ''
+ );
+ } elseif($type == 'music') {
+ $send['music'] = array(
+ 'musicurl' => tomedia($content['url']),
+ 'hqmusicurl' => tomedia($content['hqurl']),
+ 'title' => urlencode($content['title']),
+ 'description' => urlencode($content['description']),
+ 'thumb_media_id' => $content['thumb_media_id'],
+ );
+ } elseif($type == 'news') {
+ $send['msgtype'] = 'mpnews';
+ $send['mpnews'] = array(
+ 'media_id' => $content['mediaid']
+ );
+ }
+ return array(
+ 'send' => $send,
+ 'content' => $content
+ );
+}
+
+function mc_fans_tag_fields() {
+ return array(
+ 'subscribe' => '用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息',
+ 'openid' => '用户的标识,对当前公众号唯一',
+ 'nickname' => '用户的昵称',
+ 'sex' => '用户的性别,值为1时是男性,值为2时是女性,值为0时是未知',
+ 'city' => '用户所在城市',
+ 'country' => '用户所在国家',
+ 'province' => '用户所在省份',
+ 'language' => '用户的语言,简体中文为zh_CN',
+ 'headimgurl'=> '用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效',
+ 'subscribe_time' => '用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间',
+ 'unionid' => '只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段',
+ 'remark' => '公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注',
+ 'groupid' => '用户所在的分组ID(暂时兼容用户分组旧接口)',
+ 'tagid_list' => '用户被打上的标签ID列表',
+ 'subscribe_scene' => '返回用户关注的渠道来源,ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,ADD_SCENEPROFILE LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,ADD_SCENE_PAID 支付后关注,ADD_SCENE_OTHERS 其他',
+ 'qr_scene' => '二维码扫码场景(开发者自定义)',
+ 'qr_scene_str' => '二维码扫码场景描述(开发者自定义)',
+ );
+}
diff --git a/framework/model/menu.mod.php b/framework/model/menu.mod.php
new file mode 100644
index 0000000..cf5da9d
--- /dev/null
+++ b/framework/model/menu.mod.php
@@ -0,0 +1,239 @@
+'简体中文', 'en'=>'zh_CN'),
+ array('ch'=>'繁体中文TW', 'en'=>'zh_TW'),
+ array('ch'=>'繁体中文HK', 'en'=>'zh_HK'),
+ array('ch'=>'英文', 'en'=>'en'),
+ array('ch'=>'印尼', 'en'=>'id'),
+ array('ch'=>'马来', 'en'=>'ms'),
+ array('ch'=>'西班牙', 'en'=>'es'),
+ array('ch'=>'韩国', 'en'=>'ko'),
+ array('ch'=>'意大利 ', 'en'=>'it'),
+ array('ch'=>'日本', 'en'=>'ja'),
+ array('ch'=>'波兰', 'en'=>'pl'),
+ array('ch'=>'葡萄牙', 'en'=>'pt'),
+ array('ch'=>'俄国', 'en'=>'ru'),
+ array('ch'=>'泰文', 'en'=>'th'),
+ array('ch'=>'越南', 'en'=>'vi'),
+ array('ch'=>'阿拉伯语', 'en'=>'ar'),
+ array('ch'=>'北印度', 'en'=>'hi'),
+ array('ch'=>'希伯来', 'en'=>'he'),
+ array('ch'=>'土耳其', 'en'=>'tr'),
+ array('ch'=>'德语', 'en'=>'de'),
+ array('ch'=>'法语', 'en'=>'fr')
+ );
+ return $languages;
+}
+
+
+function menu_get($id) {
+ global $_W;
+ $id = intval($id);
+ if (empty($id)) {
+ return array();
+ }
+ $menu_info = table('uni_account_menus')->getById($id);
+ if (!empty($menu_info)) {
+ return $menu_info;
+ } else {
+ return array();
+ }
+}
+
+
+function menu_default() {
+ return table('uni_account_menus')->where('status', STATUS_ON)->getByType(MENU_CURRENTSELF);
+}
+
+
+function menu_update_currentself() {
+ global $_W;
+ $account_api = WeAccount::createByUniacid();
+ $default_menu_info = $account_api->menuCurrentQuery();
+ if (is_error($default_menu_info)) {
+ return error(-1, $default_menu_info['message']);
+ }
+
+ if (empty($default_menu_info['is_menu_open']) || empty($default_menu_info['selfmenu_info'])) {
+ return true;
+ }
+ $default_menu = $default_menu_info['selfmenu_info'];
+
+ $default_sub_button = array();
+ if (!empty($default_menu['button'])) {
+ foreach ($default_menu['button'] as $key => &$button) {
+ if (!empty($button['sub_button'])) {
+ $default_sub_button[$key] = $button['sub_button'];
+ } else {
+ unset($button['sub_button']);
+ }
+ ksort($button);
+ }
+ unset($button);
+ }
+ if (!empty($default_menu)) {
+ ksort($default_menu);
+ }
+ $wechat_menu_data = base64_encode(iserializer($default_menu));
+ $all_default_menus = table('uni_account_menus')->getAllByType(MENU_CURRENTSELF);
+ if (!empty($all_default_menus)) {
+ foreach ($all_default_menus as $menus_key => $menu_data) {
+ if (empty($menu_data['data'])) {
+ continue;
+ }
+ $single_menu_info = iunserializer(base64_decode($menu_data['data']));
+ if (!is_array($single_menu_info) || empty($single_menu_info['button'])) {
+ continue;
+ }
+ foreach ($single_menu_info['button'] as $key => &$single_button) {
+ if (!empty($default_sub_button[$key])) {
+ $single_button['sub_button'] = $default_sub_button[$key];
+ } else {
+ unset($single_button['sub_button']);
+ }
+ ksort($single_button);
+ }
+ unset($single_button);
+ ksort($single_menu_info);
+ $local_menu_data = base64_encode(iserializer($single_menu_info));
+ if ($wechat_menu_data == $local_menu_data) {
+ $default_menu_id = $menus_key;
+ }
+ }
+ }
+
+ if (!empty($default_menu_id)) {
+ pdo_update('uni_account_menus', array('status' => STATUS_ON), array('id' => $default_menu_id));
+ pdo_update('uni_account_menus', array('status' => STATUS_OFF), array('uniacid' => $_W['uniacid'], 'type' => MENU_CURRENTSELF, 'id !=' => $default_menu_id));
+ } else {
+ $insert_data = array(
+ 'uniacid' => $_W['uniacid'],
+ 'type' => MENU_CURRENTSELF,
+ 'group_id' => -1,
+ 'sex' => 0,
+ 'data' => $wechat_menu_data,
+ 'client_platform_type' => 0,
+ 'area' => '',
+ 'menuid' => 0,
+ 'status' => STATUS_ON
+ );
+ pdo_insert('uni_account_menus', $insert_data);
+ $insert_id = pdo_insertid();
+ pdo_update('uni_account_menus', array('title' => '默认菜单_'.$insert_id), array('id' => $insert_id));
+ pdo_update('uni_account_menus', array('status' => STATUS_OFF), array('uniacid' => $_W['uniacid'], 'type' => MENU_CURRENTSELF, 'id !=' => $insert_id));
+ }
+ return true;
+}
+
+
+function menu_update_conditional() {
+ global $_W;
+ $account_api = WeAccount::createByUniacid();
+ $conditional_menu_info = $account_api->menuQuery();
+ if (is_error($conditional_menu_info)) {
+ return error(-1, $conditional_menu_info['message']);
+ }
+ pdo_update('uni_account_menus', array('status' => STATUS_OFF), array('uniacid' => $_W['uniacid'], 'type' => MENU_CONDITIONAL));
+ if (!empty($conditional_menu_info['conditionalmenu'])) {
+ foreach ($conditional_menu_info['conditionalmenu'] as $menu) {
+ $data = array(
+ 'uniacid' => $_W['uniacid'],
+ 'type' => MENU_CONDITIONAL,
+ 'group_id' => isset($menu['matchrule']['tag_id']) ? $menu['matchrule']['tag_id'] : (isset($menu['matchrule']['group_id']) ? $menu['matchrule']['group_id'] : '-1'),
+ 'sex' => $menu['matchrule']['sex'],
+ 'client_platform_type' => $menu['matchrule']['client_platform_type'],
+ 'area' => trim($menu['matchrule']['country']) . trim($menu['matchrule']['province']) . trim($menu['matchrule']['city']),
+ 'data' => base64_encode(iserializer($menu)),
+ 'menuid' => $menu['menuid'],
+ 'status' => STATUS_ON,
+ );
+ if (!empty($menu['matchrule'])) {
+ $menu_info = table('uni_account_menus')->where('menuid',$menu['menuid'])->getByType(MENU_CONDITIONAL);
+ $menu_id = $menu_info['id'];
+ }
+ if (!empty($menu_id)) {
+ $data['title'] = !empty($menu_info['title']) ? $menu_info['title'] : '个性化菜单_' . $menu_id;
+ pdo_update('uni_account_menus', $data, array('uniacid' => $_W['uniacid'], 'id' => $menu_id));
+ } else {
+ pdo_insert('uni_account_menus', $data);
+ $insert_id = pdo_insertid();
+ pdo_update('uni_account_menus', array('title' => '个性化菜单_'.$insert_id), array('id' => $insert_id));
+ }
+ }
+ }
+ return true;
+}
+
+
+function menu_delete($id) {
+ global $_W;
+ $menu_info = menu_get($id);
+ if (empty($menu_info)) {
+ return error(-1, '菜单不存在或已经删除');
+ }
+ if ($menu_info['status'] == STATUS_OFF) {
+ pdo_delete('uni_account_menus', array('uniacid' => $_W['uniacid'], 'id' => $id));
+ return error(0, '删除菜单成功!');
+ }
+ if ($menu_info['type'] == MENU_CONDITIONAL && $menu_info['menuid'] > 0 && $menu_info['status'] != STATUS_OFF) {
+ $account_api = WeAccount::createByUniacid();
+ $result = $account_api->menuDelete($menu_info['menuid']);
+ if (is_error($result)) {
+ return error(-1, $result['message']);
+ }
+ pdo_delete('uni_account_menus', array('uniacid' => $_W['uniacid'], 'id' => $id));
+ }
+ return true;
+}
+
+
+function menu_push($id) {
+ global $_W;
+ $menu_info = menu_get($id);
+ if (empty($menu_info)) {
+ return error(-1, '菜单不存在或已删除');
+ }
+ if ($menu_info['status'] == STATUS_OFF) {
+ $post = iunserializer(base64_decode($menu_info['data']));
+ if (empty($post)) {
+ return error(-1, '菜单数据错误');
+ }
+ $is_conditional = (!empty($post['matchrule']) && $menu_info['type'] == MENU_CONDITIONAL) ? true : false;
+
+ $account_api = WeAccount::createByUniacid();
+ $menu = $account_api->menuBuild($post, $is_conditional);
+ $result = $account_api->menuCreate($menu);
+ if (is_error($result)) {
+ return error(-1, $result['message']);
+ }
+ if ($menu_info['type'] == MENU_CURRENTSELF) {
+ pdo_update('uni_account_menus', array('status' => '1'), array('id' => $menu_info['id']));
+ pdo_update('uni_account_menus', array('status' => '0'), array('id !=' => $menu_info['id'], 'uniacid' => $_W['uniacid'], 'type' => MENU_CURRENTSELF));
+ } elseif ($menu_info['type'] == MENU_CONDITIONAL) {
+ if ($post['matchrule']['group_id'] != -1) {
+ $menu['matchrule']['groupid'] = $menu['matchrule']['tag_id'];
+ unset($menu['matchrule']['tag_id']);
+ }
+ $status = pdo_update('uni_account_menus', array('status' => STATUS_ON, 'menuid' => $result), array('uniacid' => $_W['uniacid'], 'id' => $menu_info['id']));
+ }
+ return true;
+ }
+ if ($menu_info['status'] == STATUS_ON && $menu_info['type'] == MENU_CONDITIONAL && $menu_info['menuid'] > 0) {
+ $account_api = WeAccount::createByUniacid();
+ $result = $account_api->menuDelete($menu_info['menuid']);
+ if (is_error($result)) {
+ return error(-1, $result['message']);
+ } else {
+ pdo_update('uni_account_menus', array('status' => STATUS_OFF), array('id' => $menu_info['id']));
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/model/module.mod.php b/framework/model/module.mod.php
new file mode 100644
index 0000000..1d04ee0
--- /dev/null
+++ b/framework/model/module.mod.php
@@ -0,0 +1,708 @@
+ array(
+ 'name' => 'business',
+ 'title' => '主要业务',
+ 'desc' => ''
+ ),
+ 'customer' => array(
+ 'name' => 'customer',
+ 'title' => '客户关系',
+ 'desc' => ''
+ ),
+ 'activity' => array(
+ 'name' => 'activity',
+ 'title' => '营销及活动',
+ 'desc' => ''
+ ),
+ 'services' => array(
+ 'name' => 'services',
+ 'title' => '常用服务及工具',
+ 'desc' => ''
+ ),
+ 'biz' => array(
+ 'name' => 'biz',
+ 'title' => '行业解决方案',
+ 'desc' => ''
+ ),
+ 'enterprise' => array(
+ 'name' => 'enterprise',
+ 'title' => '企业应用',
+ 'desc' => ''
+ ),
+ 'h5game' => array(
+ 'name' => 'h5game',
+ 'title' => 'H5游戏',
+ 'desc' => ''
+ ),
+ 'other' => array(
+ 'name' => 'other',
+ 'title' => '其他',
+ 'desc' => ''
+ )
+ );
+ return $types;
+}
+
+function module_support_type()
+{
+ $module_support_type = array(
+ 'wxapp_support' => array(
+ 'type' => WXAPP_TYPE_SIGN,
+ 'type_name' => '微信小程序',
+ 'support' => MODULE_SUPPORT_WXAPP,
+ 'not_support' => MODULE_NONSUPPORT_WXAPP,
+ 'store_type' => STORE_TYPE_WXAPP_MODULE,
+ ),
+ 'account_support' => array(
+ 'type' => ACCOUNT_TYPE_SIGN,
+ 'type_name' => '公众号',
+ 'support' => MODULE_SUPPORT_ACCOUNT,
+ 'not_support' => MODULE_NONSUPPORT_ACCOUNT,
+ 'store_type' => STORE_TYPE_MODULE,
+ ),
+ 'welcome_support' => array(
+ 'type' => WELCOMESYSTEM_TYPE_SIGN,
+ 'type_name' => '系统首页',
+ 'support' => MODULE_SUPPORT_SYSTEMWELCOME,
+ 'not_support' => MODULE_NONSUPPORT_SYSTEMWELCOME,
+ ),
+ 'webapp_support' => array(
+ 'type' => WEBAPP_TYPE_SIGN,
+ 'type_name' => 'PC',
+ 'support' => MODULE_SUPPORT_WEBAPP,
+ 'not_support' => MODULE_NOSUPPORT_WEBAPP,
+ 'store_type' => STORE_TYPE_WEBAPP_MODULE,
+ ),
+ 'phoneapp_support' => array(
+ 'type' => PHONEAPP_TYPE_SIGN,
+ 'type_name' => 'APP',
+ 'support' => MODULE_SUPPORT_PHONEAPP,
+ 'not_support' => MODULE_NOSUPPORT_PHONEAPP,
+ 'store_type' => STORE_TYPE_PHONEAPP_MODULE,
+ ),
+ 'aliapp_support' => array(
+ 'type' => ALIAPP_TYPE_SIGN,
+ 'type_name' => '支付宝小程序',
+ 'support' => MODULE_SUPPORT_ALIAPP,
+ 'not_support' => MODULE_NOSUPPORT_ALIAPP,
+ 'store_type' => STORE_TYPE_ALIAPP_MODULE,
+ ),
+ 'baiduapp_support' => array(
+ 'type' => BAIDUAPP_TYPE_SIGN,
+ 'type_name' => '百度小程序',
+ 'support' => MODULE_SUPPORT_BAIDUAPP,
+ 'not_support' => MODULE_NOSUPPORT_BAIDUAPP,
+ 'store_type' => STORE_TYPE_BAIDUAPP_MODULE,
+ ),
+ 'toutiaoapp_support' => array(
+ 'type' => TOUTIAOAPP_TYPE_SIGN,
+ 'type_name' => '字节跳动小程序',
+ 'support' => MODULE_SUPPORT_TOUTIAOAPP,
+ 'not_support' => MODULE_NOSUPPORT_TOUTIAOAPP,
+ 'store_type' => STORE_TYPE_TOUTIAOAPP_MODULE,
+ )
+ );
+ return $module_support_type;
+}
+
+
+function module_entries($name, $types = array(), $rid = 0, $args = null)
+{
+ load()->func('communication');
+
+ global $_W;
+
+ $ts = array('rule', 'cover', 'menu', 'home', 'profile', 'shortcut', 'function', 'mine', 'system_welcome');
+
+
+ if (empty($types)) {
+ $types = $ts;
+ } else {
+ $types = array_intersect($types, $ts);
+ }
+ $bindings = pdo_getall('modules_bindings', array('module' => $name, 'entry' => $types), array(), '', 'displayorder DESC, multilevel DESC, eid ASC');
+ $entries = array();
+ $cache_key = cache_system_key('module_entry_call', array('module_name' => $name));
+ $entry_call = cache_load($cache_key);
+ if (empty($entry_call)) {
+ $entry_call = array();
+ }
+ foreach ($bindings as $bind) {
+ if (!empty($bind['call'])) {
+ if (empty($entry_call[$bind['entry']])) {
+ $call_url = url('utility/bindcall', array('modulename' => $bind['module'], 'callname' => $bind['call'], 'args' => $args, 'uniacid' => $_W['uniacid']));
+ $response = ihttp_request($call_url);
+ if (is_error($response) || $response['code'] != 200) {
+ $response = ihttp_request($_W['siteroot'] . 'web/' . $call_url);
+ if (is_error($response) || $response['code'] != 200) {
+ continue;
+ }
+ }
+ $response = json_decode($response['content'], true);
+ $ret = $response['message']['message'];
+ if (is_array($ret)) {
+ foreach ($ret as $i => $et) {
+ if (empty($et['url'])) {
+ continue;
+ }
+ $urlinfo = url_params($et['url']);
+ $et['do'] = empty($et['do']) ? $urlinfo['do'] : $et['do'];
+ $et['url'] = $et['url'] . '&__title=' . urlencode($et['title']);
+ $entry_call[$bind['entry']][] = array('eid' => 'user_' . $i, 'title' => $et['title'], 'do' => $et['do'], 'url' => $et['url'], 'from' => 'call', 'icon' => $et['icon'], 'displayorder' => $et['displayorder']);
+ }
+ }
+ cache_write($cache_key, $entry_call, 300);
+ }
+ $entries[$bind['entry']] = $entry_call[$bind['entry']];
+
+ } else {
+ if (in_array($bind['entry'], array('cover', 'home', 'profile', 'shortcut'))) {
+ $url = murl('entry', array('eid' => $bind['eid']));
+ }
+ if (in_array($bind['entry'], array('menu', 'system_welcome'))) {
+ $url = wurl("site/entry", array('eid' => $bind['eid']));
+ }
+ if ($bind['entry'] == 'mine') {
+ $url = $bind['url'];
+ }
+ if ($bind['entry'] == 'rule') {
+ $par = array('eid' => $bind['eid']);
+ if (!empty($rid)) {
+ $par['id'] = $rid;
+ }
+ $url = wurl("site/entry", $par);
+ }
+
+ if (empty($bind['icon'])) {
+ $bind['icon'] = 'wi wi-appsetting';
+ }
+ if (!defined('SYSTEM_WELCOME_MODULE') && $bind['entry'] == 'system_welcome') {
+ continue;
+ }
+ $entries[$bind['entry']][] = array(
+ 'eid' => $bind['eid'],
+ 'title' => $bind['title'],
+ 'do' => $bind['do'],
+ 'url' => !$bind['multilevel'] ? $url : '',
+ 'from' => 'define',
+ 'icon' => $bind['icon'],
+ 'displayorder' => $bind['displayorder'],
+ 'direct' => $bind['direct'],
+ 'multilevel' => $bind['multilevel'],
+ 'parent' => $bind['parent'],
+ );
+ }
+ }
+ return $entries;
+}
+
+function module_app_entries($name, $types = array(), $args = null)
+{
+ global $_W;
+ $ts = array('rule', 'cover', 'menu', 'home', 'profile', 'shortcut', 'function');
+ if (empty($types)) {
+ $types = $ts;
+ } else {
+ $types = array_intersect($types, $ts);
+ }
+ $bindings = pdo_getall('modules_bindings', array('module' => $name, 'entry' => $types));
+ $entries = array();
+ foreach ($bindings as $bind) {
+ if (!empty($bind['call'])) {
+ $extra = array();
+ $extra['Host'] = $_SERVER['HTTP_HOST'];
+ load()->func('communication');
+ $urlset = parse_url($_W['siteurl']);
+ $urlset = pathinfo($urlset['path']);
+ $response = ihttp_request($_W['sitescheme'] . $extra['Host'] . $urlset['dirname'] . '/' . url('utility/bindcall', array('modulename' => $bind['module'], 'callname' => $bind['call'], 'args' => $args, 'uniacid' => $_W['uniacid'])), array('W' => base64_encode(iserializer($_W))), $extra);
+ if (is_error($response)) {
+ continue;
+ }
+ $response = json_decode($response['content'], true);
+ $ret = $response['message']['message'];
+ if (is_array($ret)) {
+ foreach ($ret as $et) {
+ $et['url'] = $et['url'] . '&__title=' . urlencode($et['title']);
+ $entries[$bind['entry']][] = array('title' => $et['title'], 'url' => $et['url'], 'from' => 'call');
+ }
+ }
+ } else {
+ if ($bind['entry'] == 'cover') {
+ $url = murl("entry", array('eid' => $bind['eid']));
+ }
+ if ($bind['entry'] == 'home') {
+ $url = murl("entry", array('eid' => $bind['eid']));
+ }
+ if ($bind['entry'] == 'profile') {
+ $url = murl("entry", array('eid' => $bind['eid']));
+ }
+ if ($bind['entry'] == 'shortcut') {
+ $url = murl("entry", array('eid' => $bind['eid']));
+ }
+ $entries[$bind['entry']][] = array('title' => $bind['title'], 'do' => $bind['do'], 'url' => $url, 'from' => 'define');
+ }
+ }
+ return $entries;
+}
+
+function module_entry($eid)
+{
+ $sql = "SELECT * FROM " . tablename('modules_bindings') . " WHERE `eid`=:eid";
+ $pars = array();
+ $pars[':eid'] = $eid;
+ $entry = pdo_fetch($sql, $pars);
+ if (empty($entry)) {
+ return error(1, '模块菜单不存在');
+ }
+ $module = module_fetch($entry['module']);
+ if (empty($module)) {
+ return error(2, '模块不存在');
+ }
+ $querystring = array(
+ 'do' => $entry['do'],
+ 'm' => $entry['module'],
+ );
+ if (!empty($entry['state'])) {
+ $querystring['state'] = $entry['state'];
+ }
+
+ $entry['url'] = murl('entry', $querystring);
+ $entry['url_show'] = murl('entry', $querystring, true, true);
+ return $entry;
+}
+
+
+function module_build_form($name, $rid, $option = array())
+{
+ $rid = intval($rid);
+ $m = WeUtility::createModule($name);
+ if (!empty($m)) {
+ return $m->fieldsFormDisplay($rid, $option);
+ } else {
+ return null;
+ }
+
+}
+
+
+function module_save_group_package($package)
+{
+ global $_W;
+ load()->model('user');
+ load()->model('cache');
+
+ if (empty($package['name'])) {
+ return error(-1, '请输入套餐名');
+ }
+
+ if (!empty($package['modules'])) {
+ $package['modules'] = iserializer($package['modules']);
+ }
+
+ if (!empty($package['templates'])) {
+ $templates = array();
+ foreach ($package['templates'] as $id) {
+ $templates[] = $id;
+ }
+ $package['templates'] = iserializer($templates);
+ }
+
+ if (!empty($package['id'])) {
+ $name_exist = pdo_get('uni_group', array('uniacid' => 0, 'id <>' => $package['id'], 'name' => $package['name']));
+ } else {
+ $name_exist = pdo_get('uni_group', array('uniacid' => 0, 'name' => $package['name']));
+ }
+
+ if (!empty($name_exist)) {
+ return error(-1, '套餐名已存在');
+ }
+
+ if (!empty($package['id'])) {
+ pdo_update('uni_group', $package, array('id' => $package['id']));
+ cache_build_account_modules();
+ } else {
+ pdo_insert('uni_group', $package);
+ $uni_group_id = pdo_insertid();
+ if (user_is_vice_founder()) {
+ $table = table('users_founder_own_uni_groups');
+ $table->addOwnUniGroup($_W['uid'], $uni_group_id);
+ }
+ }
+ cache_build_uni_group();
+ return error(0, '添加成功');
+}
+
+function module_fetch($name, $enabled = true)
+{
+ global $_W;
+ $cachekey = cache_system_key('module_info', array('module_name' => $name));
+
+ $module = cache_load($cachekey);
+
+ if (empty($module)) {
+ $module_info = table('modules')->getByName($name);
+ if (empty($module_info)) {
+ return array();
+ }
+ $module_info['isdisplay'] = 1;
+ $module_info['logo'] = tomedia($module_info['logo']);
+ $module_info['preview'] = tomedia(IA_ROOT . '/addons/' . $module_info['name'] . '/preview.jpg', '', true);
+ if (file_exists(IA_ROOT . '/addons/' . $module_info['name'] . '/preview-custom.jpg')) {
+ $module_info['preview'] = tomedia(IA_ROOT . '/addons/' . $module_info['name'] . '/preview-custom.jpg', '', true);
+ }
+ if (APPLICATION_TYPE_TEMPLATES == $module_info['application_type']) {
+ $module_info['preview'] = tomedia(IA_ROOT . '/app/themes/' . $module_info['name'] . '/preview-custom.jpg', '', true);
+ }
+ $module = $module_info;
+ cache_write($cachekey, $module_info);
+ }
+
+ if (!empty($enabled)) {
+ if (!empty($module['is_delete'])) {
+ return array();
+ }
+ }
+
+ if (!empty($module) && !empty($_W['uniacid'])) {
+ $setting_cachekey = cache_system_key('module_setting', array('module_name' => $name, 'uniacid' => $_W['uniacid']));
+ $setting = cache_load($setting_cachekey);
+ if (empty($setting)) {
+ $setting = table('uni_account_modules')->getByUniacidAndModule($name, $_W['uniacid']);
+ $setting = empty($setting) ? array('module' => $name) : $setting;
+ cache_write($setting_cachekey, $setting);
+ }
+ $module['config'] = $setting['settings'];
+ $module['enabled'] = $module['issystem'] || !isset($setting['enabled']) ? 1 : $setting['enabled'];
+ $module['displayorder'] = $setting['displayorder'];
+ $module['shortcut'] = $setting['shortcut'];
+ $module['module_shortcut'] = $setting['module_shortcut'];
+ }
+ return $module;
+}
+
+function module_main_info($module_name)
+{
+ $cachekey = cache_system_key('module_main_info', array('module_name' => $module_name));
+ $module = cache_load($cachekey);
+ if (empty($module)) {
+ $fileds = array('name', 'title', 'version', 'logo', 'account_support', 'wxapp_support', 'webapp_support', 'phoneapp_support', 'aliapp_support', 'baiduapp_support', 'toutiaoapp_support', 'welcome_support');
+ $module_info = pdo_get('modules', array('name' => $module_name), $fileds);
+ if (empty($module_info)) {
+ return array();
+ }
+ $module_info['logo'] = tomedia($module_info['logo']);
+ $module = $module_info;
+ cache_write($cachekey, $module_info);
+ }
+ return $module;
+}
+
+function module_permission_fetch($name)
+{
+ $module = module_fetch($name);
+ $data = array();
+ if ($module['settings']) {
+ $data[] = array('title' => '参数设置', 'permission' => $name . '_settings');
+ }
+ if ($module['isrulefields']) {
+ $data[] = array('title' => '回复规则列表', 'permission' => $name . '_rule');
+ }
+ $entries = module_entries($name);
+ if (!empty($entries['home'])) {
+ $data[] = array('title' => '微站首页导航', 'permission' => $name . '_home');
+ }
+ if (!empty($entries['profile'])) {
+ $data[] = array('title' => '个人中心导航', 'permission' => $name . '_profile');
+ }
+ if (!empty($entries['shortcut'])) {
+ $data[] = array('title' => '快捷菜单', 'permission' => $name . '_shortcut');
+ }
+ if (!empty($entries['cover'])) {
+ foreach ($entries['cover'] as $cover) {
+ $data[] = array('title' => $cover['title'], 'permission' => $name . '_cover_' . $cover['do']);
+ }
+ }
+ if (!empty($entries['menu'])) {
+ foreach ($entries['menu'] as $menu) {
+ if (!empty($menu['multilevel'])) {
+ continue;
+ }
+ $data[$menu['do']] = array('title' => $menu['title'], 'permission' => $name . '_menu_' . $menu['do']);
+ }
+ }
+ unset($entries);
+ if (!empty($module['permissions'])) {
+ $module['permissions'] = (array)iunserializer($module['permissions']);
+ foreach ($module['permissions'] as $permission) {
+ if (!empty($permission['parent']) && !empty($data[$permission['parent']])) {
+ $sub_permission = array(
+ 'title' => $permission['title'],
+ 'permission' => $name . '_menu_' . $permission['parent'] . '_' . $permission['permission'],
+ );
+ if (empty($data[$permission['parent']]['sub_permission'])) {
+ $data[$permission['parent']]['sub_permission'] = array($sub_permission);
+ } else {
+ array_push($data[$permission['parent']]['sub_permission'], $sub_permission);
+ }
+ }
+ $data[] = array('title' => $permission['title'], 'permission' => $name . '_permission_' . $permission['permission']);
+ }
+ }
+ return $data;
+}
+
+
+function module_get_plugin_list($module_name)
+{
+ $module_info = module_fetch($module_name);
+ if (!empty($module_info['plugin_list']) && is_array($module_info['plugin_list'])) {
+ $plugin_list = array();
+ foreach ($module_info['plugin_list'] as $plugin) {
+ $plugin_info = module_fetch($plugin);
+ if (!empty($plugin_info)) {
+ $plugin_list[$plugin] = $plugin_info;
+ }
+ }
+ return $plugin_list;
+ } else {
+ return array();
+ }
+}
+
+
+function module_exist_in_account($module_name, $uniacid)
+{
+ load()->model('user');
+ $module_name = trim($module_name);
+ $uniacid = intval($uniacid);
+ if (empty($module_name) || empty($uniacid)) {
+ return false;
+ }
+ $result = table('uni_modules')->where(array('uniacid' => $uniacid, 'module_name' => $module_name))->getcolumn('id');
+ return $result ? true : false;
+}
+
+
+function module_check_notinstalled_support($module, $manifest_support)
+{
+ if (empty($manifest_support)) {
+ return array();
+ }
+ $has_notinstalled_support = false;
+ $notinstalled_support = array();
+ $module_support_type = module_support_type();
+
+ foreach ($manifest_support as $support) {
+ if ($support == 'app') {
+ $support = 'account';
+ } elseif ($support == 'system_welcome') {
+ $support = 'welcome';
+ } elseif ($support == 'android' || $support == 'ios') {
+ $support = 'phoneapp';
+ }
+ $support .= '_support';
+ if (!in_array($support, array_keys($module_support_type))) {
+ continue;
+ }
+
+ if ($module[$support] != $module_support_type[$support]['support']) {
+ $has_notinstalled_support = true;
+ $notinstalled_support[$support] = $module_support_type[$support]['support'];
+ } else {
+ $notinstalled_support[$support] = $module_support_type[$support]['not_support'];
+ }
+ }
+ if ($has_notinstalled_support) {
+ return $notinstalled_support;
+ } else {
+ return array();
+ }
+}
+
+
+function module_add_to_uni_group($module, $uni_group_id, $support)
+{
+ if (!in_array($support, array_keys(module_support_type()))) {
+ return error(1, '支持类型不存在');
+ }
+ if (empty($module[$support]) || $module[$support] != MODULE_SUPPORT_ACCOUNT) {
+ return error(1, '模块支持不存在');
+ }
+ $unigroup_table = table('uni_group');
+ $uni_group = $unigroup_table->getById($uni_group_id);
+ if (empty($uni_group)) {
+ return error(1, '应用权限组不存在');
+ }
+ if (!empty($uni_group['modules'])) {
+ $uni_group['modules'] = iunserializer($uni_group['modules']);
+ }
+ $update_data = $uni_group['modules'];
+
+ $key = str_replace('_support', '', $support);
+ $key = $key == 'account' ? 'modules' : $key;
+ if (!in_array($module['name'], $update_data[$key])) {
+ $update_data[$key][] = $module['name'];
+ }
+ return $unigroup_table->fill('modules', iserializer($update_data))->where('id', $uni_group_id)->save();
+}
+
+
+function module_recycle($modulename, $type, $support)
+{
+ global $_W;
+ $module_support_types = module_support_type();
+ $module_support_type = $module_support_types[$support]['type'];
+ $all_support = array_keys($module_support_types);
+
+ if ($type == MODULE_RECYCLE_INSTALL_DISABLED) {
+ table('system_welcome_binddomain')->where(array('module_name' => $modulename))->delete();
+ $uni_modules_table = table('uni_modules');
+ $uni_accounts = $uni_modules_table->where('module_name', $modulename)->getall('uniacid');
+ if (!empty($uni_accounts)) {
+ foreach ($uni_accounts as $uni_account_val) {
+ $account_info = uni_fetch($uni_account_val['uniacid']);
+ if ($account_info['type_sign'] == $module_support_type) {
+ $uni_modules_table->deleteUniModules($modulename, $uni_account_val['uniacid']);
+ }
+ }
+ }
+
+ $lastuse_table = table('users_lastuse');
+ $lastuse_accounts = switch_getall_lastuse_by_module($modulename);
+ if (!empty($lastuse_accounts)) {
+ foreach ($lastuse_accounts as $lastuse_account_val) {
+ $lastuse_account_info = uni_fetch($lastuse_account_val['uniacid']);
+ if ($lastuse_account_info['type_sign'] == $module_support_type) {
+ $lastuse_table->searchWithUid($_W['uid']);
+ $lastuse_table->searchWithUniacid($lastuse_account_val['uniacid']);
+ $lastuse_table->searchWithModule($modulename);
+ $lastuse_table->delete();
+ }
+ }
+ }
+ }
+
+ if (!in_array($support, $all_support)) {
+ return false;
+ }
+ if ($type == MODULE_RECYCLE_UNINSTALL_IGNORE) {
+ table('modules_cloud')->fill(array($support => 1, 'module_status' => MODULE_CLOUD_UNINSTALL_NORMAL))->where('name', $modulename)->save();
+ }
+ $module_recycle = table('modules_recycle');
+ $record = $module_recycle->searchWithNameType($modulename, $type)->get();
+ if (empty($record)) {
+ return $module_recycle->fill(array('name' => $modulename, 'type' => $type, $support => 1))->save();
+ } else {
+ $record[$support] = 1;
+ return $module_recycle->where('id', $record['id'])->fill($record)->save();
+ }
+}
+
+
+function module_cancel_recycle($modulename, $type, $support)
+{
+ $all_support = array_keys(module_support_type());
+ if (!in_array($support, $all_support)) {
+ return false;
+ }
+ $module_recycle = table('modules_recycle');
+ $record = $module_recycle->searchWithNameType($modulename, $type)->get();
+ if (empty($record)) {
+ return true;
+ }
+ $record[$support] = 0;
+ $is_update = false;
+ foreach ($all_support as $s) {
+ if ($record[$s] == 1) {
+ $is_update = true;
+ }
+ }
+ if ($type == MODULE_RECYCLE_UNINSTALL_IGNORE) {
+ table('modules_cloud')->fill(array($support => 2, 'module_status' => MODULE_CLOUD_UNINSTALL_NORMAL))->where('name', $modulename)->save();
+ }
+ if ($is_update) {
+ return $module_recycle->where('id', $record['id'])->fill($record)->save();
+ } else {
+ return $module_recycle->where('id', $record['id'])->delete();
+ }
+}
+
+
+function module_get_direct_enter_status($module_name)
+{
+ global $_W;
+ if (empty($module_name)) {
+ return STATUS_OFF;
+ }
+ $module_setting = table('uni_account_modules')->getByUniacidAndModule($module_name, $_W['uniacid']);
+ $status = !empty($module_setting['settings']) && $module_setting['settings']['direct_enter'] == STATUS_ON ? STATUS_ON : STATUS_OFF;
+ return $status;
+}
+
+function module_change_direct_enter_status($module_name)
+{
+ global $_W;
+ if (empty($module_name)) {
+ return false;
+ }
+ $module_setting = table('uni_account_modules')->getByUniacidAndModule($module_name, $_W['uniacid']);
+ $direct_enter_status = !empty($module_setting['settings']) && $module_setting['settings']['direct_enter'] == STATUS_ON ? STATUS_OFF : STATUS_ON;
+ if (empty($module_setting)) {
+ $data = array('direct_enter' => $direct_enter_status);
+ $result = table('uni_account_modules')->fill(array('settings' => iserializer($data), 'uniacid' => $_W['uniacid'], 'module' => $module_name))->save();
+ } else {
+ $module_setting['settings']['direct_enter'] = $direct_enter_status;
+ $data = $module_setting['settings'];
+ $result = table('uni_account_modules')->fill(array('settings' => iserializer($data)))->where('module', $module_name)->where('uniacid', $_W['uniacid'])->save();
+ }
+ return $result ? true : false;
+}
+
+function module_delete_store_wish_goods($module_name, $support_name)
+{
+ load()->model('store');
+ $all_type = store_goods_type_info();
+ foreach ($all_type as $info) {
+ if ($info['group'] == 'module' && $support_name == $info['sign'] . '_support') {
+ $type = $info['type'];
+ break;
+ }
+ }
+ if (!empty($type)) {
+ pdo_update('site_store_goods', array('status' => 2), array('module' => $module_name, 'type' => $type));
+ }
+ return true;
+}
+
+function module_expire_notice()
+{
+ $module_expire = setting_load('module_expire');
+ $module_expire = !empty($module_expire['module_expire']) ? $module_expire['module_expire'] : array();
+ foreach ($module_expire as $value) {
+ if ($value['status'] == 1) {
+ $expire_notice = $value['notice'];
+ break;
+ }
+ }
+ if (empty($expire_notice)) {
+ $system_module_expire = setting_load('system_module_expire');
+ $expire_notice = !empty($system_module_expire['system_module_expire']) ? $system_module_expire['system_module_expire'] : '您访问的功能模块不存在,请重新进入';
+ }
+ return $expire_notice;
+}
\ No newline at end of file
diff --git a/framework/model/permission.mod.php b/framework/model/permission.mod.php
new file mode 100644
index 0000000..9f7a779
--- /dev/null
+++ b/framework/model/permission.mod.php
@@ -0,0 +1,725 @@
+model('system');
+ $w7_file_permission = $acl;
+ $permission_frames = system_menu();
+ if (!in_array($_W['role'], array(ACCOUNT_MANAGE_NAME_OPERATOR, ACCOUNT_MANAGE_NAME_MANAGER)) || empty($_W['uniacid'])) {
+ return $w7_file_permission;
+ }
+
+ $cachekey = cache_system_key('permission', array('uniacid' => $_W['uniacid'], 'uid' => $_W['uid']));
+ $cache = cache_load($cachekey);
+
+ if (!empty($cache)) {
+ return $cache;
+ }
+ $permission_exist = permission_account_user_permission_exist($_W['uid'], $_W['uniacid']);
+ if (empty($permission_exist)) {
+ cache_write($cachekey, $w7_file_permission);
+ return $w7_file_permission;
+ }
+ $user_account_permission = permission_account_user_menu($_W['uid'], $_W['uniacid'], PERMISSION_ACCOUNT);
+ $user_wxapp_permission = permission_account_user_menu($_W['uid'], $_W['uniacid'], PERMISSION_WXAPP);
+ $account_info = uni_fetch($_W['uniacid']);
+ $user_other_permission = permission_account_user_menu($_W['uid'], $_W['uniacid'], $account_info->typeSign);
+ $user_permission = array_merge($user_account_permission, $user_wxapp_permission, $user_other_permission);
+
+ $permission_contain = array('account', 'wxapp', 'system', 'phoneapp');
+ $section = array();
+ $permission_result = array();
+ foreach ($permission_frames as $key => $frames) {
+ if (!in_array($key, $permission_contain) || empty($frames['section'])) {
+ continue;
+ }
+ foreach ($frames['section'] as $frame_key => $frame) {
+ if (empty($frame['menu'])) {
+ continue;
+ }
+ $section[$key][$frame_key] = $frame['menu'];
+ }
+ }
+ $account = permission_get_nameandurl($section[$permission_contain[0]]);
+ $wxapp = permission_get_nameandurl($section[$permission_contain[1]]);
+ $system = permission_get_nameandurl($section[$permission_contain[2]]);
+ $permission_result = array_merge($account, $wxapp, $system);
+
+ foreach ($permission_result as $permission_val) {
+ if (in_array($permission_val['permission_name'], $user_permission)) {
+ $w7_file_permission[$permission_val['controller']][$_W['role']][] = $permission_val['action'];
+ }
+ }
+ cache_write($cachekey, $w7_file_permission);
+ return $w7_file_permission;
+}
+
+
+function permission_get_nameandurl($permission) {
+ $result = array();
+ if (empty($permission)) {
+ return $result;
+ }
+ foreach ($permission as $menu) {
+ if (empty($menu)) {
+ continue;
+ }
+ foreach ($menu as $permission_name) {
+ $url_query_array = url_params($permission_name['url']);
+ $result[] = array(
+ 'url' => $permission_name['url'],
+ 'controller' => $url_query_array['c'],
+ 'action' => $url_query_array['a'],
+ 'permission_name' => $permission_name['permission_name']
+ );
+ if (!empty($permission_name['sub_permission'])) {
+ foreach ($permission_name['sub_permission'] as $key => $sub_permission_name) {
+ $sub_url_query_array = url_params($sub_permission_name['url']);
+ $result[] = array(
+ 'url' => $sub_permission_name['url'],
+ 'controller' => $sub_url_query_array['c'],
+ 'action' => $sub_url_query_array['a'],
+ 'permission_name' => $sub_permission_name['permission_name'],
+ );
+ }
+ }
+ }
+ }
+ return $result;
+}
+
+
+function permission_account_user_role($uid = 0, $uniacid = 0) {
+ global $_W;
+ load()->model('user');
+ $role = '';
+ $uid = empty($uid) ? $_W['uid'] : intval($uid);
+
+ if (user_is_founder($uid, true)) {
+ return ACCOUNT_MANAGE_NAME_FOUNDER;
+ } else {
+ $user_info = pdo_get('users', array('uid' => $uid));
+ if (!empty($user_info['endtime']) && $user_info['endtime'] != USER_ENDTIME_GROUP_EMPTY_TYPE && $user_info['endtime'] != USER_ENDTIME_GROUP_UNLIMIT_TYPE && $user_info['endtime'] < TIMESTAMP) {
+ return ACCOUNT_MANAGE_NAME_EXPIRED;
+ }
+ if (!user_is_bind()) {
+ return ACCOUNT_MANAGE_NAME_UNBIND_USER;
+ }
+ if ($user_info['type'] == ACCOUNT_OPERATE_CLERK) {
+ return ACCOUNT_MANAGE_NAME_CLERK;
+ }
+ }
+
+ if (!empty($uniacid)) {
+ $role = table('uni_account_users')->getUserRoleByUniacid($uid, $uniacid);
+ if ($role == ACCOUNT_MANAGE_NAME_OWNER) {
+ $role = ACCOUNT_MANAGE_NAME_OWNER;
+ } elseif ($role == ACCOUNT_MANAGE_NAME_VICE_FOUNDER) {
+ $role = ACCOUNT_MANAGE_NAME_VICE_FOUNDER;
+ } elseif ($role == ACCOUNT_MANAGE_NAME_MANAGER) {
+ $role = ACCOUNT_MANAGE_NAME_MANAGER;
+ } elseif ($role == ACCOUNT_MANAGE_NAME_OPERATOR) {
+ $role = ACCOUNT_MANAGE_NAME_OPERATOR;
+ } elseif ($role == ACCOUNT_MANAGE_NAME_CLERK) {
+ $role = ACCOUNT_MANAGE_NAME_CLERK;
+ }
+ return $role;
+ } else {
+ if (user_is_vice_founder($uid)) {
+ return ACCOUNT_MANAGE_NAME_VICE_FOUNDER;
+ }
+ $roles = table('uni_account_users')->getAllUserRole($uid);
+ $roles = array_keys($roles);
+ if (in_array(ACCOUNT_MANAGE_NAME_VICE_FOUNDER, $roles)) {
+ $role = ACCOUNT_MANAGE_NAME_VICE_FOUNDER;
+ } elseif (in_array(ACCOUNT_MANAGE_NAME_OWNER, $roles)) {
+ $role = ACCOUNT_MANAGE_NAME_OWNER;
+ } elseif (in_array(ACCOUNT_MANAGE_NAME_MANAGER, $roles)) {
+ $role = ACCOUNT_MANAGE_NAME_MANAGER;
+ } elseif (in_array(ACCOUNT_MANAGE_NAME_OPERATOR, $roles)) {
+ $role = ACCOUNT_MANAGE_NAME_OPERATOR;
+ }
+ }
+ $role = empty($role) ? user_is_vice_founder($uid) ? ACCOUNT_MANAGE_NAME_VICE_FOUNDER : ACCOUNT_MANAGE_NAME_OPERATOR : $role;
+ return $role;
+}
+
+
+function permission_account_user_permission_exist($uid = 0, $uniacid = 0) {
+ global $_W;
+ load()->model('user');
+ $uid = intval($uid) > 0 ? $uid : $_W['uid'];
+ $uniacid = intval($uniacid) > 0 ? $uniacid : $_W['uniacid'];
+ if (user_is_founder($uid, true)) {
+ return false;
+ }
+ if (defined('FRAME') && FRAME == 'system') {
+ return true;
+ }
+ $is_exist = table('users_permission')->getUserPermissionByType($uid, $uniacid);
+ if(empty($is_exist)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+
+function permission_account_user($type = 'system') {
+ global $_W;
+ $user_permission = table('users_permission')->getUserPermissionByType($_W['uid'], $_W['uniacid'], $type);
+ $user_permission = $user_permission['permission'];
+ if (empty($user_permission)) {
+ $user_permission = array('account*', 'wxapp*', 'phoneapp*');
+ }
+ $permission_append = frames_menu_append();
+ if (!empty($permission_append[$_W['role']])) {
+ $user_permission = array_merge($user_permission, $permission_append[$_W['role']]);
+ }
+ if (empty($_W['role']) && empty($_W['uniacid'])) {
+ $user_permission = array_merge($user_permission, $permission_append['operator']);
+ }
+ return (array)$user_permission;
+}
+
+
+function permission_account_user_menu($uid, $uniacid, $type) {
+ $user_menu_permission = array();
+
+ $uid = intval($uid);
+ $uniacid = intval($uniacid);
+ $type = trim($type);
+ if (empty($uid) || empty($uniacid) || empty($type)) {
+ return error(-1, '参数错误!');
+ }
+ $permission_exist = permission_account_user_permission_exist($uid, $uniacid);
+ if (empty($permission_exist)) {
+ return array('all');
+ }
+ $user_permission_table = table('users_permission');
+ $user_menu_permission = $user_permission_table->getAllUserModulePermission($uid, $uniacid);
+ if ($type == 'modules') {
+ if ($user_menu_permission['modules'] && $user_menu_permission['modules']['permission'] == 'all') {
+ return array('all');
+ }
+ } else {
+ $module = uni_modules_by_uniacid($uniacid);
+ $module = array_keys($module);
+ if (in_array($type, $module) && $user_menu_permission['modules'] && $user_menu_permission['modules']['permission'] == 'all') {
+ return array('all');
+ }
+ if (in_array($type, $module) || in_array($type, array(PERMISSION_ACCOUNT, PERMISSION_WXAPP, PERMISSION_WEBAPP, PERMISSION_PHONEAPP, PERMISSION_ALIAPP, PERMISSION_BAIDUAPP, PERMISSION_TOUTIAOAPP, PERMISSION_SYSTEM))) {
+ $menu_permission = $user_permission_table->getUserPermissionByType($uid, $uniacid, $type);
+ $user_menu_permission = !empty($menu_permission['permission']) ? $menu_permission['permission'] : array();
+ }
+ }
+
+ return $user_menu_permission;
+}
+
+
+function permission_menu_name() {
+ load()->model('system');
+ $menu_permission = array();
+
+ $menu_list = system_menu_permission_list();
+ $middle_menu = array();
+ $middle_sub_menu = array();
+ if (!empty($menu_list)) {
+ foreach ($menu_list as $nav_id => $section) {
+ if (empty($section['section'])) {
+ continue;
+ }
+ foreach ($section['section'] as $section_id => $section) {
+ if (!empty($section['menu'])) {
+ $middle_menu[] = $section['menu'];
+ }
+ }
+ }
+ }
+
+ if (!empty($middle_menu)) {
+ foreach ($middle_menu as $menu) {
+ foreach ($menu as $menu_val) {
+ $menu_permission[] = $menu_val['permission_name'];
+ if (!empty($menu_val['sub_permission'])) {
+ $middle_sub_menu[] = $menu_val['sub_permission'];
+ }
+ }
+ }
+ }
+
+ if (!empty($middle_sub_menu)) {
+ foreach ($middle_sub_menu as $sub_menu) {
+ foreach ($sub_menu as $sub_menu_val) {
+ $menu_permission[] = $sub_menu_val['permission_name'];
+ }
+ }
+ }
+ return $menu_permission;
+}
+
+
+function permission_update_account_user($uid, $uniacid, $data) {
+ $uid = intval($uid);
+ $uniacid = intval($uniacid);
+ if (empty($uid) || empty($uniacid) || !in_array($data['type'], array(PERMISSION_ACCOUNT, PERMISSION_WXAPP, PERMISSION_WEBAPP, PERMISSION_PHONEAPP, PERMISSION_ALIAPP, PERMISSION_BAIDUAPP, PERMISSION_TOUTIAOAPP, PERMISSION_SYSTEM))) {
+ return error('-1', '参数错误!');
+ }
+ $user_menu_permission = permission_account_user_menu($uid, $uniacid, $data['type']);
+ if (is_error($user_menu_permission)) {
+ return error('-1', '参数错误!');
+ }
+ $permission = table('users_permission')->getUserPermissionByType($uid, $uniacid, $data['type']);
+ if (empty($permission)) {
+ $result = table('users_permission')->fill(array(
+ 'uniacid' => $uniacid,
+ 'uid' => $uid,
+ 'type' => $data['type'],
+ 'permission' => $data['permission'],
+ ))->save();
+ } else {
+ $result = table('users_permission')->fill(array('permission' => $data['permission']))->whereId($permission['id'])->save();
+ }
+ return $result;
+}
+
+
+
+function permission_check_account_user($permission_name, $show_message = true, $action = '') {
+ global $_W, $_GPC, $acl;
+ load()->model('module');
+ $see_more_info = $acl['see_more_info'];
+
+ if (strpos($permission_name, 'see_') === 0) {
+ $can_see_more = false;
+ if (in_array(FRAME, array('system', 'site', 'account_manage', 'myself', 'user_manage', 'permission'))) {
+ $can_see_more = in_array($permission_name, $see_more_info[$_W['highest_role']]) ? true : false;
+ } else {
+ if (is_array($see_more_info[$_W['role']]) && !empty($see_more_info[$_W['role']])) {
+ $can_see_more = in_array($permission_name, $see_more_info[$_W['role']]) ? true : false;
+ }
+ }
+
+ $uniacid = safe_gpc_int($_GPC['uniacid']);
+ if(($can_see_more == true && $permission_name == 'see_account_manage_users_edit_vicefounder') || $permission_name == 'see_account_manage_users_add_viceuser') {
+ $founder_uid = pdo_getcolumn('uni_account_users', array('uniacid'=>$uniacid, 'role'=>'owner'), 'uid');
+ if(empty($founder_uid)) $can_see_more = false;
+ $owner_uid = pdo_getcolumn('users', array('uid'=>$founder_uid), 'owner_uid');
+ if($owner_uid) $can_see_more = false;
+ }
+
+ return $can_see_more;
+ }
+
+ $user_has_permission = permission_account_user_permission_exist();
+ if (empty($user_has_permission)) {
+ return true;
+ }
+ $modulename = safe_gpc_string($_GPC['module_name']) ?: safe_gpc_string($_GPC['m']);
+ $do = trim($_GPC['do']);
+ $entry_id = intval($_GPC['eid']);
+
+ if ($action == 'reply') {
+ $system_modules = module_system();
+ if (!empty($modulename) && !in_array($modulename, $system_modules)) {
+ $permission_name = $modulename . '_rule';
+ $users_permission = permission_account_user($modulename);
+ }
+ } elseif ($action == 'cover' && $entry_id > 0) {
+ load()->model('module');
+ $entry = module_entry($entry_id);
+ if (!empty($entry)) {
+ $permission_name = $entry['module'] . '_cover_' . trim($entry['do']);
+ $users_permission = permission_account_user($entry['module']);
+ }
+ } elseif ($action == 'nav') {
+ if(!empty($modulename)) {
+ $permission_name = "{$modulename}_{$do}";
+ $users_permission = permission_account_user($modulename);
+ } else {
+ return true;
+ }
+ } elseif ($action == 'wxapp' || !empty($_W['account']) && $_W['account']['type_sign'] == WXAPP_TYPE_SIGN) {
+ $users_permission = permission_account_user('wxapp');
+ } else {
+ $users_permission = permission_account_user('system');
+ }
+ if (!isset($users_permission)) {
+ $users_permission = permission_account_user('system');
+ }
+ if ($users_permission[0] != 'all' && !in_array($permission_name, $users_permission) && !in_array(FRAME . '*', $users_permission)) {
+ if (in_array($permission_name, permission_first_sub_permission()) && !empty($show_message)) {
+ load()->model('system');
+ $permission_string = explode('_', $permission_name);
+ $goto_permission = permission_subpermission($permission_string[0] . '_' . $permission_string[1] . '_');
+ $system_menu = system_menu_permission_list(ACCOUNT_MANAGE_NAME_OPERATOR);
+ $goto_url = $system_menu[FRAME]['section'][$permission_string[0]]['menu'][$permission_string[0] . '_' . $permission_string[1]]['sub_permission'][$goto_permission]['url'];
+ itoast('', $goto_url);
+ }
+ if ($show_message) {
+ empty($_W['isajax']) ? itoast('您没有进行该操作的权限!', '', '') : iajax(-1, '您没有进行该操作的权限');
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+function permission_first_sub_permission() {
+ return array(
+ 'platform_reply_keyword',
+ 'platform_menu_default',
+ 'platform_qr_qr',
+ 'platform_masstask_post',
+ 'platform_material_news',
+ 'platform_site_multi',
+ 'mc_fans_display',
+ 'mc_member_diaplsy',
+ 'profile_setting_remote',
+ 'profile_payment_pay',
+ 'statistics_visit_app',
+ 'wxapp_payment_pay',
+ );
+}
+
+
+function permission_check_account_user_module($action = '', $module_name = '') {
+ global $_W, $_GPC;
+ $status = permission_account_user_permission_exist();
+ if(empty($status)) {
+ return true;
+ }
+ $a = trim($_GPC['a']);
+ $do = trim($_GPC['do']);
+ $m = trim($_GPC['module_name']);
+ if ($a == 'manage-account' && $do == 'setting' && !empty($m)) {
+ $permission_name = $m . '_settings';
+ $users_permission = permission_account_user($m);
+ if ($users_permission[0] != 'all' && !in_array($permission_name, $users_permission)) {
+ return false;
+ }
+ } elseif (!empty($do) && !empty($m)) {
+ $is_exist = table('modules_bindings')->isEntryExists($m, 'menu', $do);
+ if(empty($is_exist)) {
+ return true;
+ }
+ }
+ if(empty($module_name)) {
+ $module_name = IN_MODULE;
+ }
+ $permission = permission_account_user($module_name);
+ if(empty($permission) || ($permission[0] != 'all' && !empty($action) && !in_array($action, $permission))) {
+ return false;
+ }
+ return true;
+}
+
+
+function permission_user_account_num($uid = 0) {
+ global $_W;
+ $uid = intval($uid);
+ $user = $uid > 0 ? user_single($uid) : $_W['user'];
+ if (empty($user)) {
+ return array();
+ }
+ $user_founder_info = table('users_founder_own_users')->getFounderByUid($user['uid']);
+ $account_all_type = uni_account_type();
+ $account_all_type_sign = array_keys(uni_account_type_sign());
+ $extra_group_table = table('users_extra_group');
+ $extra_limit_table = table('users_extra_limit');
+
+ if (user_is_vice_founder($user['uid']) || !empty($user_founder_info['founder_uid'])) {
+ if (!empty($user_founder_info['founder_uid']) && !user_is_vice_founder($user['uid'])) {
+ $role = ACCOUNT_MANAGE_NAME_OWNER;
+ $group = table('users_group')->getById($user['groupid']);
+ $user_uid = $user_founder_info['founder_uid'];
+ } else {
+ $role = ACCOUNT_MANAGE_NAME_VICE_FOUNDER;
+ $group = table('users_founder_group')->getById($user['groupid']);
+ $user_uid = $user['uid'];
+ }
+
+ foreach ($account_all_type_sign as $type_info) {
+ $key_name = $type_info . '_num';
+ $group_num[$key_name] = 0;
+ }
+ $fouder_own_users_owner_account = table('account')->searchAccountList(false, 1, $fields = 'a.uniacid, b.type', $user['uid']);
+ $current_vice_founder_user_group_nums = 0;
+ if (!empty($fouder_own_users_owner_account)) {
+ foreach ($fouder_own_users_owner_account as $account) {
+ foreach ($account_all_type as $type_key => $type_info) {
+ if ($type_key == $account['type']) {
+ $key_name = $type_info['type_sign'] . '_num';
+ $group_num[$key_name] += 1;
+ $current_vice_founder_user_group_nums += 1;
+ continue;
+ }
+ }
+ }
+ }
+ } else {
+ $role = ACCOUNT_MANAGE_NAME_OWNER;
+ $group = table('users_group')->getById($user['groupid']);
+ $group_num = uni_owner_account_nums($user['uid'], $role);
+ if (empty($_W['isfounder'])) {
+ if (!empty($user['owner_uid'])) {
+ $owner_info = table('users')->getById($user['owner_uid']);
+ $group_vice = table('users_founder_group')->getById($owner_info['groupid']);
+
+ $founder_group_num = uni_owner_account_nums($owner_info['uid'], ACCOUNT_MANAGE_NAME_VICE_FOUNDER);
+ foreach ($account_all_type_sign as $sign) {
+ $maxsign = 'max' . $sign;
+ $group[$maxsign] = min(intval($group[$maxsign]), intval($group_vice[$maxsign]));
+ }
+ }
+ }
+ }
+ if (!empty($user_founder_info['founder_uid'])) {
+ $owner_info = table('users')->getById($user_founder_info['founder_uid']);
+ $group_vice = table('users_founder_group')->getById($owner_info['groupid']);
+ $founder_group_num = uni_owner_account_nums($owner_info['uid'], ACCOUNT_MANAGE_NAME_VICE_FOUNDER);
+ }
+ $store_order_table = table('site_store_order');
+ $store_create_table = table('site_store_create_account');
+ foreach ($account_all_type_sign as $type_sign) {
+ $create_buy_num[$type_sign] = $store_create_table->getUserCreateNumByType($user['uid'], $type_sign);
+ }
+ foreach ($account_all_type_sign as $type_sign) {
+ $store_buy[$type_sign] = $store_order_table->getUserBuyNumByType($user['uid'], $type_sign);
+ $store_buy[$type_sign] = $store_buy[$type_sign] < 0 ? 0 : $store_buy[$type_sign];
+ }
+
+ $extra_create_group_info = array_keys($extra_group_table->getCreateGroupsByUid($user['uid']));
+ $extra_limits_info = $extra_limit_table->getExtraLimitByUid($user['uid']);
+ if (!empty($user_founder_info['founder_uid'])) {
+ $founder_extra_create_group_info = array_keys($extra_group_table->getCreateGroupsByUid($user_founder_info['founder_uid']));
+ $founder_extra_limits_info = $extra_limit_table->getExtraLimitByUid($user_founder_info['founder_uid']);
+
+ $vice_founder_own_users_create_accounts = table('account')->searchAccountList(false, 1, $fields = 'a.uniacid, b.type', $user_founder_info['founder_uid']);
+ $vice_founder_own_users_create_nums = array();
+ foreach ($account_all_type_sign as $type_info) {
+ $key_name = $type_info . '_num';
+ $vice_founder_own_users_create_nums[$key_name] = 0;
+ }
+ if (!empty($vice_founder_own_users_create_accounts)) {
+ foreach ($vice_founder_own_users_create_accounts as $vice_founder_own_users_create_account){
+ foreach ($account_all_type as $type_key => $type_info) {
+ if ($vice_founder_own_users_create_account['type'] == $type_key) {
+ $key_name = $type_info['type_sign'] . '_num';
+ $vice_founder_own_users_create_nums[$key_name] += 1;
+ continue;
+ }
+ }
+ }
+ }
+
+ }
+ $create_group_info_all = array();
+ if (!empty($extra_create_group_info)) {
+ $create_group_table = table('users_create_group');
+ $create_groups = array();
+ foreach($extra_create_group_info as $create_group_id) {
+ $create_group_info = $create_group_table->getById($create_group_id);
+ $create_groups[] = $create_group_info;
+ foreach ($account_all_type_sign as $sign) {
+ $maxsign = 'max' . $sign;
+ $create_group_info_all[$maxsign] += $create_group_info[$maxsign];
+ }
+ }
+ }
+ $founcder_create_group_info_all = array();
+ if (!empty($user_founder_info['founder_uid']) && !empty($extra_create_group_info)) {
+ $create_group_table = table('users_create_group');
+ $founder_create_groups = array();
+ foreach($founder_extra_create_group_info as $create_group_id) {
+ $create_group_info = $create_group_table->getById($create_group_id);
+ $founder_create_groups[] = $create_group_info;
+ foreach ($account_all_type_sign as $sign) {
+ $maxsign = 'max' . $sign;
+ $founcder_create_group_info_all[$maxsign] += $create_group_info[$maxsign];
+ }
+ }
+ }
+ $extra = $limit = $founder_limit = array();
+ $founder_limit_total = 0;
+
+ foreach ($account_all_type_sign as $sign) {
+ $maxsign = 'max' . $sign;
+ $extra[$sign] = $create_group_info_all[$maxsign] + $extra_limits_info[$maxsign];
+ if (!empty($user_founder_info['founder_uid'])){
+ $founder_extra[$sign] = $founcder_create_group_info_all[$maxsign] + $founder_extra_limits_info[$maxsign];
+ } else {
+ $founder_extra[$sign] = 0;
+ }
+ $sign_num = $sign . '_num';
+ $limit[$sign] = max((intval($group[$maxsign]) + $extra[$sign] + intval($store_buy[$sign]) - $group_num[$sign_num]), 0);
+ $founder_limit[$sign] = max((intval($group_vice[$maxsign]) + $founder_extra[$sign]), 0);
+
+ if (!empty($vice_founder_own_users_create_nums)) {
+ $founder_limit[$sign] -= $vice_founder_own_users_create_nums[$sign_num];
+ }
+ $founder_limit_total += $founder_limit[$sign];
+ }
+ $founder_limit_total = max(0, $founder_limit_total);
+ $data = array(
+ 'group_name' => $group['name'],
+ 'vice_group_name' => $group_vice['name'],
+ 'create_groups' => $create_groups,
+ 'founder_limit_total' => $founder_limit_total,
+ );
+ $data['max_total'] = 0;
+ $data['created_total'] = 0;
+ $data['limit_total'] = 0;
+ foreach ($account_all_type_sign as $sign) {
+ $data["store_buy_{$sign}"] = $store_buy[$sign];
+ $data["store_{$sign}_limit"] = intval($store_buy[$sign]) - intval($create_buy_num[$sign]) <= 0 ? 0 : intval($store_buy[$sign]);
+ $data['store_limit_total' ] += $data["store_{$sign}_limit"];
+
+ $maxsign = 'max' . $sign;
+ $sign_num = $sign . '_num';
+ $data['user_group_max' . $sign] = $group[$maxsign];
+ $data['usergroup_' . $sign . '_limit'] = max($group[$maxsign] - $group_num[$sign_num] - intval($create_buy_num[$sign]), 0);
+ $data[$maxsign] = $group[$maxsign] + intval($store_buy[$sign]) + $extra[$sign];
+ $data[$sign_num] = $group_num[$sign_num];
+ $data[$sign . '_limit'] = max($limit[$sign], 0);
+ $data['extra_' . $sign] = $extra_limits_info[$maxsign];
+ $data['founder_' . $sign . '_limit'] = max($founder_limit[$sign], 0);
+ $data['max_total'] = $data[$maxsign] + $data['max_total'];
+ $data['created_total'] = $data[$sign_num] + $data['created_total'];
+ $data['limit_total'] = $data[$sign . '_limit'] + $data['limit_total'];
+ $data['current_vice_founder_user_created_total'] = !empty($current_vice_founder_user_group_nums) ? $current_vice_founder_user_group_nums : 0;
+ if (!empty($vice_founder_own_users_create_nums)) {
+ $data['vice_founder_own_users_' . $sign_num] = $vice_founder_own_users_create_nums[$sign_num]; }
+ }
+
+ if (!empty($vice_founder_own_users_create_nums)) {
+ foreach ($vice_founder_own_users_create_nums as $vice_founder_own_users_create_num) {
+ $data['vice_founder_own_users_created_total'] += $vice_founder_own_users_create_num; }
+ }
+ ksort($data);
+ return $data;
+}
+
+function permission_subpermission($prefix, $module = '') {
+ global $_W;
+ $result = '';
+ if (empty($prefix)) {
+ return $result;
+ }
+ $type = !empty($module) ? safe_gpc_string($module) : ($_W['account']['type_sign'] == 'account' ? 'system' : $_W['account']['type_sign']);
+ $account_premission = table('users_permission')->getUserPermissionByType($_W['uid'], $_W['uniacid'], $type);
+ if (!empty($account_premission['permission'])) {
+ foreach ($account_premission['permission'] as $permission) {
+ $if_exist = strpos($permission, $prefix);
+ $result = $if_exist !== false ? $permission : '';
+ if (!empty($result)) break;
+ }
+ }
+ return $result;
+}
+
+
+function permission_user_account_creatable($uid = 0, $type_sign = '') {
+ global $_W;
+ $uid = empty($uid) ? $_W['uid'] : $uid;
+ $type_sign = empty($type_sign) ? 'account' : $type_sign;
+ if(user_is_founder($uid) && !user_is_vice_founder()) {
+ return true;
+ }
+ $key = $type_sign . '_limit';
+ $data = permission_user_account_num($uid);
+ return isset($data[$key]) && $data[$key] > 0;
+}
+
+
+function permission_user_timelimits($uid = 0) {
+ global $_W;
+ $uid = empty($uid) ? $_W['uid'] : $uid;
+ $user = user_single($uid);
+
+ if (user_is_founder($uid) && !user_is_vice_founder()) {
+ return 0;
+ }
+
+ if (user_is_vice_founder($uid)) {
+ $group_info = user_founder_group_detail_info($user['groupid']);
+ } else {
+ $group_info = user_group_detail_info($user['groupid']);
+ }
+
+ $users_extra_limit_table = table('users_extra_limit');
+ $extra_limit_info = $users_extra_limit_table->getExtraLimitByUid($uid);
+
+ $limits = array();
+ $limits['user_group'] = $group_info['timelimit'];
+ $limits['user_extra'] = $extra_limit_info['timelimit'];
+ $limits['total'] = $group_info['timelimit'] + $extra_limit_info['timelimit'];
+ return $limits;
+}
+
+
+function permission_check_vice_founder_limit($group_info) {
+ global $_W;
+ $timelimits = permission_user_timelimits();
+ $user_end_time = user_end_time($_W['uid']);
+ if ($group_info['timelimit'] > $timelimits['total'] && !empty($user_end_time)) {
+ return error(-1, '当前用户组的有效期不能超过' . $timelimits['total'] . '天!');
+ }
+
+ $account_nums = permission_user_account_num();
+ $account_all_type_sign = uni_account_type_sign();
+ foreach ($account_all_type_sign as $account_type_key => $account_type_info) {
+ $maxtype = 'max' . $account_type_key;
+ if ($group_info[$maxtype] > $account_nums[$maxtype]) {
+ return error(-1, "当前用户组的" . $account_type_info['title'] . "个数不能超过" . $account_nums[$maxtype] . '个!');
+ }
+ }
+ return true;
+}
+
+
+function permission_account_user_init($uid, $uniacid) {
+ $uid = intval($uid);
+ $uniacid = intval($uniacid);
+
+ if (empty($uid) || empty($uniacid)) {
+ return error(-1, '参数错误');
+ }
+
+ $account = uni_fetch($uniacid);
+ $account_all_type_sign = uni_account_type_sign();
+ foreach ($account_all_type_sign as $account_type_sign => $account_type_info) {
+ if (in_array($account['type'], $account_type_info['contain_type'])) {
+ $account_type = $account_type_sign == 'account' ? 'system' : $account_type_sign;
+ }
+ }
+
+ $user_own_menu_permission = table('users_permission')->getUserPermissionByType($uid, $uniacid, $account_type);
+ $user_own_module_permission = table('users_permission')->getAllUserModulePermission($uid, $uniacid);
+
+ if (empty($user_own_menu_permission)) {
+ $all_menu_permission = permission_menu_name();
+ $user_menu_permission_data = array(
+ 'type' => $account_type,
+ 'permission' => implode('|', $all_menu_permission),
+ );
+ permission_update_account_user($uid, $uniacid, $user_menu_permission_data);
+
+ }
+
+ if (empty($user_own_module_permission)) {
+ $insert = array(
+ 'uniacid' => $uniacid,
+ 'uid' => $uid,
+ 'type' => 'modules',
+ 'permission' => 'all',
+
+ );
+ pdo_insert('users_permission', $insert);
+ }
+ return true;
+}
\ No newline at end of file
diff --git a/framework/model/refund.mod.php b/framework/model/refund.mod.php
new file mode 100644
index 0000000..b91f734
--- /dev/null
+++ b/framework/model/refund.mod.php
@@ -0,0 +1,194 @@
+ $tid, 'module' => $module);
+ if ($module != 'store') {
+ $params['uniacid'] = $_W['uniacid'];
+ }
+ $paylog = pdo_get('core_paylog', $params);
+ if (empty($paylog)) {
+ return error(1, '订单不存在');
+ }
+ if ($paylog['status'] != 1) {
+ return error(1, '此订单还未支付成功不可退款');
+ }
+ $refund_params = array('status' => 1, 'uniontid' => $paylog['uniontid']);
+ if ($module != 'store') {
+ $refund_params['uniacid'] = $_W['uniacid'];
+ }
+ $refund_amount = pdo_getcolumn('core_refundlog', $refund_params, 'SUM(fee)');
+ if ($refund_amount >= $paylog['card_fee']) {
+ return error(1, '订单已退款成功');
+ }
+ return true;
+}
+
+
+function refund_create_order($tid, $module, $fee = 0, $reason = '') {
+ global $_W;
+ load()->model('module');
+ $order_can_refund = refund_order_can_refund($module, $tid);
+ if (is_error($order_can_refund)) {
+ return $order_can_refund;
+ }
+ $module_info = module_fetch($module);
+ $moduleid = empty($module_info['mid']) ? '000000' : sprintf("%06d", $module_info['mid']);
+ $refund_uniontid = date('YmdHis') . $moduleid . random(8,1);
+ $params = array('tid' => $tid, 'module' => $module);
+ if ($module != 'store') {
+ $params['uniacid'] = $_W['uniacid'];
+ }
+ $paylog = pdo_get('core_paylog', $params);
+ $uniacid = $module == 'store' ? $paylog['uniacid'] : $_W['uniacid'];
+ $refund = array (
+ 'uniacid' => $uniacid,
+ 'uniontid' => $paylog['uniontid'],
+ 'fee' => empty($fee) ? $paylog['card_fee'] : number_format($fee, 2, '.', ''),
+ 'status' => 0,
+ 'refund_uniontid' => $refund_uniontid,
+ 'reason' => safe_gpc_string($reason),
+ 'is_wish' => $paylog['is_wish'],
+ );
+ pdo_insert('core_refundlog', $refund);
+ return pdo_insertid();
+}
+
+
+function refund($refund_id) {
+ load()->classs('pay');
+ global $_W;
+ $refundlog = pdo_get('core_refundlog', array('id' => $refund_id));
+ $params = array('uniontid' => $refundlog['uniontid']);
+ $params['uniacid'] = $refundlog['is_wish'] == 1 ? $refundlog['uniacid'] : $_W['uniacid'];
+ $paylog = pdo_get('core_paylog', $params);
+ if ($paylog['type'] == 'wechat' || $paylog['type'] == 'wxapp') {
+ $refund_param = reufnd_wechat_build($refund_id, $refundlog['is_wish']);
+ if (is_error($refund_param)) {
+ return $refund_param;
+ }
+ if ($refundlog['is_wish'] == 1) {
+ $module = 'store';
+ $cert_file = ATTACHMENT_ROOT . 'store_wechat_refund_all.pem';
+ } else {
+ $module = '';
+ $cert_file = ATTACHMENT_ROOT . $_W['uniacid'] . '_wechat_refund_all.pem';
+ }
+
+ $wechat = Pay::create('wechat', $module);
+ $response = $wechat->refund($refund_param, $module);
+ unlink($cert_file);
+ if (is_error($response)) {
+ pdo_update('core_refundlog', array('status' => '-1'), array('id' => $refund_id));
+ return $response;
+ } else {
+ return $response;
+ }
+ } elseif ($paylog['type'] == 'alipay') {
+ $refund_param = reufnd_ali_build($refund_id, $refundlog['is_wish']);
+ if (is_error($refund_param)) {
+ return $refund_param;
+ }
+ $module = $refundlog['is_wish'] == 1 ? 'store' : '';
+ $ali = Pay::create('alipay', $module);
+ $response = $ali->refund($refund_param, $refund_id);
+ if (is_error($response)) {
+ pdo_update('core_refundlog', array('status' => '-1'), array('id' => $refund_id));
+ return $response;
+ } else {
+ return $response;
+ }
+ }
+ return error(1, '此订单退款方式不存在');
+}
+
+
+function reufnd_ali_build($refund_id, $is_wish = 0) {
+ global $_W;
+ if ($is_wish == 1) {
+ $setting = setting_load('store_pay');
+ $refund_setting = $setting['store_pay']['ali_refund'];
+ } else {
+ $setting = uni_setting_load('payment', $_W['uniacid']);
+ $refund_setting = $setting['payment']['ali_refund'];
+ }
+ if ($refund_setting['switch'] != 1) {
+ return error(1, '未开启支付宝退款功能!');
+ }
+ if (empty($refund_setting['private_key'])) {
+ return error(1, '缺少支付宝密钥证书!');
+ }
+
+ $refundlog = pdo_get('core_refundlog', array('id' => $refund_id));
+ $uniacid = $is_wish == 1 ? $refundlog['uniacid'] : $_W['uniacid'];
+ $paylog = pdo_get('core_paylog', array('uniacid' => $uniacid, 'uniontid' => $refundlog['uniontid']));
+ $refund_param = array(
+ 'app_id' => $refund_setting['app_id'],
+ 'method' => 'alipay.trade.refund',
+ 'charset' => 'utf-8',
+ 'sign_type' => 'RSA2',
+ 'timestamp' => date('Y-m-d H:i:s'),
+ 'version' => '1.0',
+ 'biz_content' => array(
+ 'out_trade_no' => $refundlog['uniontid'],
+ 'refund_amount' => $refundlog['fee'],
+ 'refund_reason' => $refundlog['reason'],
+ )
+ );
+ $refund_param['biz_content'] = json_encode($refund_param['biz_content']);
+ return $refund_param;
+}
+
+
+function reufnd_wechat_build($refund_id, $is_wish = 0) {
+ global $_W;
+ if ($is_wish == 1) {
+ $setting = setting_load('store_pay');
+ $pay_setting = $setting['store_pay'];
+ $refund_setting = $setting['store_pay']['wechat_refund'];
+ } else {
+ $setting = uni_setting_load('payment', $_W['uniacid']);
+ $pay_setting = $setting['payment'];
+ $refund_setting = $setting['payment']['wechat_refund'];
+ }
+
+ if ($refund_setting['switch'] != 1) {
+ return error(1, '未开启微信退款功能!');
+ }
+ if (empty($refund_setting['key']) || empty($refund_setting['cert'])) {
+ return error(1, '缺少微信证书!');
+ }
+
+ $refundlog = pdo_get('core_refundlog', array('id' => $refund_id));
+ $uniacid = $is_wish == 1 ? $refundlog['uniacid'] : $_W['uniacid'];
+ $paylog = pdo_get('core_paylog', array('uniacid' => $uniacid, 'uniontid' => $refundlog['uniontid']));
+ $account = uni_fetch($uniacid);
+ $refund_param = array(
+ 'appid' => $is_wish == 1 ? $pay_setting['wechat']['appid'] : $account['key'],
+ 'mch_id' => $pay_setting['wechat']['mchid'],
+ 'out_trade_no' => $refundlog['uniontid'],
+ 'out_refund_no' => $refundlog['refund_uniontid'],
+ 'total_fee' => $paylog['card_fee'] * 100,
+ 'refund_fee' => $refundlog['fee'] * 100,
+ 'nonce_str' => random(8),
+ 'refund_desc' => $refundlog['reason']
+ );
+
+ if ($pay_setting['wechat']['switch'] == PAYMENT_WECHAT_TYPE_SERVICE) {
+ $refund_param['sub_mch_id'] = $pay_setting['wechat']['sub_mch_id'];
+ $refund_param['sub_appid'] = $account['key'];
+ $proxy_account = uni_fetch($pay_setting['wechat']['service']);
+ $refund_param['appid'] = $proxy_account['key'];
+ $refund_param['mch_id'] = $proxy_account['setting']['payment']['wechat_facilitator']['mchid'];
+ }
+ $cert = authcode($refund_setting['cert'], 'DECODE');
+ $key = authcode($refund_setting['key'], 'DECODE');
+
+ $cert_file = $is_wish == 1 ? 'store_wechat_refund_all.pem' : $_W['uniacid'] . '_wechat_refund_all.pem';
+ file_put_contents(ATTACHMENT_ROOT . $cert_file, $cert . $key);
+ return $refund_param;
+}
\ No newline at end of file
diff --git a/framework/model/reply.mod.php b/framework/model/reply.mod.php
new file mode 100644
index 0000000..9dfc673
--- /dev/null
+++ b/framework/model/reply.mod.php
@@ -0,0 +1,223 @@
+ 0) {
+ $start = ($pindex - 1) * $psize;
+ $sql .= " LIMIT {$start},{$psize}";
+ $total = pdo_fetchcolumn('SELECT COUNT(*) FROM ' . tablename('rule') . $where, $params);
+ }
+ return pdo_fetchall($sql, $params);
+}
+
+
+function reply_single($id) {
+ $id = intval($id);
+ $result = table('rule')->getById($id);
+ if (empty($result)) {
+ return $result;
+ }
+ $result['keywords'] = table('rule_keyword')->whereRid($id)->getall();
+ return $result;
+}
+
+
+function reply_keywords_search($condition = '', $params = array(), $pindex = 0, $psize = 10, &$total = 0) {
+ global $_W;
+ if (!empty($condition)) {
+ $where = " WHERE {$condition} ";
+ }
+ $sql = 'SELECT * FROM ' . tablename('rule_keyword') . $where . ' ORDER BY displayorder DESC, `type` ASC, id DESC';
+ if ($pindex > 0) {
+ $start = ($pindex - 1) * $psize;
+ $sql .= " LIMIT {$start},{$psize}";
+ $total = pdo_fetchcolumn('SELECT COUNT(*) FROM ' . tablename('rule_keyword') . $where, $params);
+ }
+ $result = pdo_fetchall($sql, $params);
+ if (!empty($result)) {
+ $rule_setting_select = table('uni_account_modules')->getByUniacidAndModule('userapi', $_W['uniacid']);
+ foreach ($result as $key => $val) {
+ if ($val['module'] == 'userapi' && empty($val['uniacid'])) {
+ if (empty($rule_setting_select['settings'][$val['rid']])) {
+ unset($result[$key]);
+ continue;
+ }
+ }
+
+ $containtypes = pdo_get('rule', array('id' => $val['rid']), array('containtype'));
+ if (!empty($containtypes)) {
+ $containtype = explode(',', $containtypes['containtype']);
+ $containtype = array_filter($containtype);
+ } else {
+ $containtype = array();
+ }
+ $result[$key]['reply_type'] = $containtype;
+ }
+ } else {
+ $result = array();
+ }
+ return $result;
+}
+
+
+function reply_content_search($rid = 0) {
+ $result = array();
+ $rid = intval($rid);
+ if (empty($rid)) {
+ return $result;
+ }
+
+ $modules = array('basic', 'images', 'news', 'music', 'voice', 'video');
+ $params = array(':rid' => $rid);
+ foreach ($modules as $key => $module) {
+ $result[$module] = pdo_fetchcolumn('SELECT COUNT(*) FROM ' . tablename($module.'_reply') . ' WHERE `rid` = :rid', $params);
+ $result['sum'] += $result[$module];
+ }
+ return $result;
+}
+
+
+function reply_predefined_service() {
+ $predefined_service = array(
+ 'weather.php' => array(
+ 'title' => '城市天气',
+ 'description' => '"城市名+天气", 如: "北京天气"',
+ 'keywords' => array(
+ array('3', '^.+天气$')
+ )
+ ),
+ 'baike.php' => array(
+ 'title' => '百度百科',
+ 'description' => '"百科+查询内容" 或 "定义+查询内容", 如: "百科姚明", "定义自行车"',
+ 'keywords' => array(
+ array('3', '^百科.+$'),
+ array('3', '^定义.+$'),
+ )
+ ),
+ 'translate.php' => array(
+ 'title' => '即时翻译',
+ 'description' => '"@查询内容(中文或英文)"',
+ 'keywords' => array(
+ array('3', '^@.+$'),
+ )
+ ),
+ 'calendar.php' => array(
+ 'title' => '今日老黄历',
+ 'description' => '"日历", "万年历", "黄历"或"几号"',
+ 'keywords' => array(
+ array('1', '日历'),
+ array('1', '万年历'),
+ array('1', '黄历'),
+ array('1', '几号'),
+ )
+ ),
+ 'news.php' => array(
+ 'title' => '看新闻',
+ 'description' => '"新闻"',
+ 'keywords' => array(
+ array('1', '新闻'),
+ )
+ ),
+ 'express.php' => array(
+ 'title' => '快递查询',
+ 'description' => '"快递+单号", 如: "申通1200041125"',
+ 'keywords' => array(
+ array('3', '^(申通|圆通|中通|汇通|韵达|顺丰|EMS) *[a-z0-9]{1,}$')
+ )
+ ),
+ );
+ return $predefined_service;
+}
+
+
+function reply_getall_common_service() {
+ global $_W;
+ $rule_setting_select = table('uni_account_modules')->getByUniacidAndModule('userapi', $_W['uniacid']);
+ $rule_setting_select = (array)$rule_setting_select['settings'];
+ $exists_rule = table('rule')->where(array('uniacid' => 0, 'module' => 'userapi', 'status' => 1))->getall();
+ $service_list = array();
+ $rule_ids = array();
+ $api_url = array();
+ if (!empty($exists_rule)) {
+ foreach ($exists_rule as $rule_detail) {
+ $rule_ids[] = $rule_detail['id'];
+ $service_list[$rule_detail['id']] = $rule_detail;
+ }
+
+ $all_description = table('userapi_reply')->where('rid IN', $rule_ids)->getall();
+ if (!empty($all_description)) {
+ foreach ($all_description as $description) {
+ $service_list[$description['rid']]['description'] = $description['description'];
+ $service_list[$description['rid']]['switch'] = isset($rule_setting_select[$description['rid']]) && $rule_setting_select[$description['rid']] ? 'checked' : '';
+ $api_url[] = $description['apiurl'];
+ }
+ }
+ }
+
+ $all_service = reply_predefined_service();
+ $all_url = array_keys($all_service);
+ $diff_url = array_diff($all_url, $api_url);
+ if (!empty($diff_url)) {
+ foreach ($diff_url as $url) {
+ $userapi_reply_info = table('userapi_reply')->getByApiurl($url);
+ $service_list[$userapi_reply_info['rid']]['url'] = $userapi_reply_info['apiurl'];
+ $service_list[$userapi_reply_info['rid']]['rid'] = $userapi_reply_info['rid'];
+ $service_list[$userapi_reply_info['rid']]['id'] = $userapi_reply_info['id'];
+ $service_list[$userapi_reply_info['rid']]['name'] = $all_service[$url]['title'];
+ $service_list[$userapi_reply_info['rid']]['description'] = $all_service[$url]['description'];
+ $service_list[$userapi_reply_info['rid']]['switch'] = isset($rule_setting_select[$userapi_reply_info['rid']]) && $rule_setting_select[$userapi_reply_info['rid']] ? 'checked' : '';
+ }
+ }
+ return $service_list;
+}
+
+
+function reply_insert_without_service($file) {
+ $all_service = reply_predefined_service();
+ $all_url = array_keys($all_service);
+ if (!in_array($file, $all_url)) {
+ return false;
+ }
+ $userapi_reply_info = table('userapi_reply')->getByApiurl($file);
+ if (!empty($userapi_reply_info) && !empty($userapi_reply_info['rid'])) {
+ return $userapi_reply_info['rid'];
+ }
+
+ $rule_info = array('uniacid' => 0, 'name' => $all_service[$file]['title'], 'module' => 'userapi', 'displayorder' => 255, 'status' => 1);
+ table('rule')->fill($rule_info)->save();
+
+ $rule_id = pdo_insertid();
+ $rule_keyword_info = array('rid' => $rule_id, 'uniacid' => 0, 'module' => 'userapi', 'displayorder' => $rule_info['displayorder'], 'status' => $rule_info['status']);
+ if (!empty($all_service[$file]['keywords'])) {
+ foreach ($all_service[$file]['keywords'] as $keyword_info) {
+ $rule_keyword_info['content'] = $keyword_info[1];
+ $rule_keyword_info['type'] = $keyword_info[0];
+ table('rule_keyword')->fill($rule_keyword_info)->save();
+ }
+ }
+
+ $userapi_reply = array('rid' => $rule_id, 'description' => htmlspecialchars($all_service[$file]['description']), 'apiurl' => $file);
+ table('userapi_reply')->fill($userapi_reply)->save();
+ return $rule_id;
+}
+
+function reply_check_uni_default_keyword($uniacid = 0) {
+ global $_W;
+ $uniacid = empty($uniacid) ? $_W['uniacid'] : $uniacid;
+
+ $default = uni_setting_load('default', $uniacid);
+ if (!empty($default['default'])) {
+ $rule = table('rule_keyword')->getByUniacidAndContent($uniacid, $default['default']);
+ if (empty($rule)) {
+ uni_setting_save('default', '');
+ cache_delete(cache_system_key('unisetting', array('uniacid' => $uniacid)));
+ }
+ }
+ return true;
+}
\ No newline at end of file
diff --git a/framework/model/setting.mod.php b/framework/model/setting.mod.php
new file mode 100644
index 0000000..662ebf4
--- /dev/null
+++ b/framework/model/setting.mod.php
@@ -0,0 +1,45 @@
+ $value) {
+ $record[] = "('$key', '" . iserializer($value) . "')";
+ }
+ if ($record) {
+ $return = pdo_query("REPLACE INTO " . tablename('core_settings') . " (`key`, `value`) VALUES " . implode(',', $record));
+ }
+ } else {
+ $return = pdo_insert('core_settings', array('key' => $key, 'value' => iserializer($data)), TRUE);
+ }
+ $cachekey = cache_system_key('setting');
+ cache_write($cachekey, '');
+ return $return;
+}
+
+function setting_load($key = '')
+{
+ global $_W;
+
+ $cachekey = cache_system_key('setting');
+ $settings = cache_load($cachekey);
+ if (empty($settings)) {
+ $settings = pdo_getall('core_settings', array(), array(), 'key');
+ if (is_array($settings)) {
+ foreach ($settings as $k => &$v) {
+ $settings[$k] = iunserializer($v['value']);
+ }
+ }
+ cache_write($cachekey, $settings);
+ }
+ $_W['setting'] = array_merge($settings, (array)$_W['setting']);
+ if (!empty($key)) {
+ return array($key => $settings[$key]);
+ } else {
+ return $settings;
+ }
+}
diff --git a/framework/model/switch.mod.php b/framework/model/switch.mod.php
new file mode 100644
index 0000000..e3e5d82
--- /dev/null
+++ b/framework/model/switch.mod.php
@@ -0,0 +1,66 @@
+getByType('account_display');
+ return !empty($last_use_account) ? $last_use_account['uniacid'] : 0;
+}
+
+function switch_get_module_display() {
+ return table('users_lastuse')->getByType('module_display');
+}
+
+function switch_get_user_common_module($module_name) {
+ return table('users_lastuse')->getByType('module_common_' . $module_name);
+}
+
+function switch_getall_lastuse_by_module($module_name) {
+ return table('users_lastuse')->searchWithModulename($module_name)->getall();
+}
+
+function switch_save_uniacid($uniacid) {
+ global $_W;
+ isetcookie('__uniacid', $uniacid, 7 * 86400);
+ return true;
+}
+
+function switch_save_account_display($uniacid) {
+ switch_save_uniacid($uniacid);
+ return switch_save($uniacid, '', 'account_display');
+}
+
+function switch_save_module_display($uniacid, $module_name) {
+ global $_W;
+ load()->model('visit');
+ visit_system_update(array('modulename' => $module_name, 'uid' => $_W['uid'], 'uniacid' => $uniacid));
+
+ return switch_save($uniacid, $module_name, 'module_display');
+}
+
+function switch_save_module($uniacid, $module_name) {
+ return switch_save($uniacid, $module_name, 'module_display_' . $module_name);
+}
+
+function switch_save_user_common_module($uniacid, $module_name) {
+ return switch_save($uniacid, $module_name, 'module_common_' . $module_name);
+}
+
+function switch_save($uniacid, $module_name, $type) {
+ global $_W;
+ if (empty($uniacid) || empty($type)) {
+ return false;
+ }
+ $users_lastuse_table = table('users_lastuse');
+ $if_exists = $users_lastuse_table->getByType($type);
+ $fill_data = array('uniacid' => $uniacid, 'modulename' => $module_name);
+ if ($if_exists) {
+ $users_lastuse_table->where('id', $if_exists['id'])->fill($fill_data)->save();
+ } else {
+ $fill_data['uid'] = $_W['uid'];
+ $fill_data['type'] = $type;
+ $users_lastuse_table->fill($fill_data)->save();
+ }
+ return true;
+}
\ No newline at end of file
diff --git a/framework/model/system.mod.php b/framework/model/system.mod.php
new file mode 100644
index 0000000..3df4d46
--- /dev/null
+++ b/framework/model/system.mod.php
@@ -0,0 +1,177 @@
+ $_W['uniacid'])));
+ if (empty($system_menu)) {
+ cache_build_frame_menu();
+ $system_menu = cache_load(cache_system_key('system_frame', array('uniacid' => $_W['uniacid'])));
+ }
+ if ($role == ACCOUNT_MANAGE_NAME_OPERATOR) {
+ unset($system_menu['appmarket']);
+ unset($system_menu['advertisement']);
+ unset($system_menu['system']);
+ }
+ return $system_menu;
+}
+
+function system_check_statcode($statcode)
+{
+ $allowed_stats = array(
+ 'baidu' => array(
+ 'enabled' => true,
+ 'reg' => '/(http[s]?\:)?\/\/hm\.baidu\.com\/hm\.js\?/'
+ ),
+
+ 'qq' => array(
+ 'enabled' => true,
+ 'reg' => '/(http[s]?\:)?\/\/tajs\.qq\.com/'
+ ),
+ );
+ foreach ($allowed_stats as $key => $item) {
+ $preg = preg_match($item['reg'], $statcode);
+ if (!$preg && !$item['enabled']) {
+ continue;
+ } else {
+ return htmlspecialchars_decode($statcode);
+ }
+ return safe_gpc_html(htmlspecialchars_decode($statcode));
+ }
+}
+
+function system_check_items()
+{
+ return array(
+ 'mbstring' => array(
+ 'operate' => 'system_check_php_ext',
+ 'description' => 'mbstring 扩展',
+ 'error_message' => '不支持库',
+ 'solution' => '安装 mbstring 扩展',
+ 'handle' => 'http://s.w7.cc/wo/problem/46'
+ ),
+ 'mcrypt' => array(
+ 'operate' => 'system_check_php_ext',
+ 'description' => 'mcrypt 扩展',
+ 'error_message' => '不支持库',
+ 'solution' => '安装 mcrypt 扩展',
+ 'handle' => 'http://s.w7.cc/wo/problem/46'
+ ),
+ 'openssl' => array(
+ 'operate' => 'system_check_php_ext',
+ 'description' => 'openssl 扩展',
+ 'error_message' => '不支持库',
+ 'solution' => '安装 openssl 扩展',
+ 'handle' => 'http://s.w7.cc/wo/problem/46'
+ ),
+ 'max_allowed_packet' => array(
+ 'operate' => 'system_check_mysql_params',
+ 'description' => 'mysql max_allowed_packet 值',
+ 'error_message' => 'max_allowed_packet 小于 20M',
+ 'solution' => '修改 mysql max_allowed_packet 值',
+ 'handle' => 'https://bbs.w7.cc/thread-33415-1-1.html'
+ ),
+ 'always_populate_raw_post_data' => array(
+ 'operate' => 'system_check_php_raw_post_data',
+ 'description' => 'php always_populate_raw_post_data 配置',
+ 'error_message' => '配置有误',
+ 'solution' => '修改 php always_populate_raw_post_data 配置为 -1',
+ 'handle' => 'https://s.w7.cc/wo/problem/134'
+ ),
+ );
+}
+
+function system_check_php_ext($extension)
+{
+ return extension_loaded($extension) ? true : false;
+}
+
+function system_check_mysql_params($param)
+{
+ $check_result = pdo_fetchall("SHOW GLOBAL VARIABLES LIKE '{$param}'");
+ return $check_result[0]['Value'] < 1024 * 1024 * 20 ? false : true;
+}
+
+function system_check_php_raw_post_data()
+{
+ if (version_compare(PHP_VERSION, '7.0.0') == -1 && version_compare(PHP_VERSION, '5.6.0') >= 0) {
+ return @ini_get('always_populate_raw_post_data') == '-1';
+ }
+ return true;
+}
+
+function system_setting_items()
+{
+ return array(
+ 'bind',
+ 'develop_status',
+ 'icp',
+ 'policeicp',
+ 'login_type',
+ 'log_status',
+ 'mobile_status',
+ 'reason',
+ 'autosignout',
+ 'status',
+ 'welcome_link',
+ 'login_verify_status',
+ 'address',
+ 'blogo',
+ 'baidumap',
+ 'background_img',
+ 'company',
+ 'companyprofile',
+ 'description',
+ 'email',
+ 'footerleft',
+ 'footerright',
+ 'flogo',
+ 'icon',
+ 'keywords',
+ 'leftmenufixed',
+ 'notice',
+ 'oauth_bind',
+ 'phone',
+ 'person',
+ 'qq',
+ 'statcode',
+ 'slides',
+ 'showhomepage',
+ 'sitename',
+ 'template',
+ 'login_template',
+ 'url',
+ 'verifycode',
+ 'slide_logo',
+ );
+}
+
+function system_star_menu()
+{
+ global $_W;
+ $result = array(
+ 'platform' => array(
+ 'title' => '所有平台',
+ 'icon' => 'wi wi-platform',
+ 'apiurl' => url('account/display/list', array('type' => ACCOUNT_TYPE_SIGN)),
+ 'one_page' => 0,
+ 'hide_sort' => 0,
+ ),
+ );
+ $account_all = table('account')->searchAccountList();
+ $result['platform']['num'] = max(0, count($account_all));
+ if ($result['platform']['num'] == 0) {
+ unset($result['platform']['num']);
+ }
+
+ return $result;
+}
\ No newline at end of file
diff --git a/framework/model/user.mod.php b/framework/model/user.mod.php
new file mode 100644
index 0000000..8746167
--- /dev/null
+++ b/framework/model/user.mod.php
@@ -0,0 +1,1303 @@
+classs('oauth2/oauth2client');
+ $support_login_types = Oauth2CLient::supportThirdLoginType();
+ if (!in_array($source, $support_login_types)) {
+ $check_pass = safe_check_password(safe_gpc_string($user['password']));
+ if (is_error($check_pass)) {
+ return $check_pass;
+ }
+ }
+
+ $user['salt'] = random(8);
+ $user['password'] = user_hash($user['password'], $user['salt']);
+ $user['joinip'] = $_W['clientip'];
+ $user['joindate'] = TIMESTAMP;
+ $user['lastip'] = $_W['clientip'];
+ $user['lastvisit'] = TIMESTAMP;
+ if (!empty($user['owner_uid'])) {
+ $vice_founder_info = user_single($user['owner_uid']);
+ if (empty($vice_founder_info) || !user_is_vice_founder($vice_founder_info['uid'])) {
+ $user['owner_uid'] = 0;
+ }
+ }
+ if (empty($user['status'])) {
+ $user['status'] = 2;
+ }
+ if (empty($user['type'])) {
+ $user['type'] = USER_TYPE_COMMON;
+ }
+
+ $result = pdo_insert('users', $user);
+ if (!empty($result)) {
+ $user['uid'] = pdo_insertid();
+ }
+
+ if (!empty($user['uid']) && !empty($user['owner_uid'])) {
+ $founder_user_add = table('users_founder_own_users')->addOwnUser($user['uid'], $user['owner_uid']);
+ }
+ return intval($user['uid']);
+}
+
+
+function user_check($user)
+{
+ if (empty($user) || !is_array($user)) {
+ return false;
+ }
+ $where = ' WHERE 1 ';
+ $params = array();
+ if (!empty($user['uid'])) {
+ $where .= ' AND `uid`=:uid';
+ $params[':uid'] = intval($user['uid']);
+ }
+ if (!empty($user['username'])) {
+ $where .= ' AND `username`=:username';
+ $params[':username'] = $user['username'];
+ }
+ if (!empty($user['status'])) {
+ $where .= " AND `status`=:status";
+ $params[':status'] = intval($user['status']);
+ }
+ if (empty($params)) {
+ return false;
+ }
+ $sql = 'SELECT `password`,`salt` FROM ' . tablename('users') . "$where LIMIT 1";
+ $record = pdo_fetch($sql, $params);
+ if (empty($record) || empty($record['password']) || empty($record['salt'])) {
+ return false;
+ }
+ if (!empty($user['password'])) {
+ $password = user_hash($user['password'], $record['salt']);
+ return $password == $record['password'];
+ }
+ return true;
+}
+
+
+function user_is_founder($uid, $only_main_founder = false)
+{
+ global $_W;
+ $founders = explode(',', $_W['config']['setting']['founder']);
+ if (in_array($uid, $founders)) {
+ return true;
+ }
+
+ if (empty($only_main_founder)) {
+ $founder_groupid = pdo_getcolumn('users', array('uid' => $uid), 'founder_groupid');
+ if ($founder_groupid == ACCOUNT_MANAGE_GROUP_VICE_FOUNDER) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+function user_is_vice_founder($uid = 0)
+{
+ global $_W;
+ $uid = intval($uid);
+ if (empty($uid)) {
+ $user_info = $_W['user'];
+ } else {
+ $user_info = table('users')->getById($uid);
+ }
+ if ($user_info['founder_groupid'] == ACCOUNT_MANAGE_GROUP_VICE_FOUNDER) {
+ return true;
+ }
+ return false;
+}
+
+
+function user_delete($uid, $is_recycle = false)
+{
+ load()->model('cache');
+ if (!empty($is_recycle)) {
+ pdo_update('users', array('status' => USER_STATUS_BAN), array('uid' => $uid));
+ return true;
+ }
+
+ $user_accounts = table('uni_account_users')->getOwnedAccountsByUid($uid);
+ if (!empty($user_accounts)) {
+ foreach ($user_accounts as $uniacid => $account) {
+ cache_build_account_modules($uniacid);
+ }
+ }
+ $user_info = table('users')->getById($uid);
+ if ($user_info['founder_groupid'] == ACCOUNT_MANAGE_GROUP_VICE_FOUNDER) {
+ pdo_update('users', array('owner_uid' => ACCOUNT_NO_OWNER_UID), array('owner_uid' => $uid));
+ pdo_update('users_group', array('owner_uid' => ACCOUNT_NO_OWNER_UID), array('owner_uid' => $uid));
+ pdo_update('uni_group', array('owner_uid' => ACCOUNT_NO_OWNER_UID), array('owner_uid' => $uid));
+ pdo_delete('users_founder_own_users', array('founder_uid' => $uid));
+ pdo_delete('users_founder_own_users_groups', array('founder_uid' => $uid));
+ pdo_delete('users_founder_own_uni_groups', array('founder_uid' => $uid));
+ pdo_delete('users_founder_own_create_groups', array('founder_uid' => $uid));
+ }
+ pdo_delete('users', array('uid' => $uid));
+ pdo_delete('uni_account_users', array('uid' => $uid));
+ pdo_delete('users_profile', array('uid' => $uid));
+ pdo_delete('users_bind', array('uid' => $uid));
+ pdo_delete('users_extra_group', array('uid' => $uid));
+ pdo_delete('users_extra_limit', array('uid' => $uid));
+ pdo_delete('users_extra_modules', array('uid' => $uid));
+ pdo_delete('users_extra_templates', array('uid' => $uid));
+ pdo_delete('users_founder_own_users', array('uid' => $uid));
+ return true;
+}
+
+
+function user_single($user_or_uid)
+{
+ $user = $user_or_uid;
+ if (empty($user)) {
+ return false;
+ }
+ if (is_numeric($user)) {
+ $user = array('uid' => $user);
+ }
+ if (!is_array($user)) {
+ return false;
+ }
+ $where = ' WHERE 1 ';
+ $params = array();
+ if (!empty($user['uid'])) {
+ $where .= ' AND u.`uid`=:uid';
+ $params[':uid'] = intval($user['uid']);
+ }
+ if (!empty($user['username'])) {
+ $where .= ' AND u.`username`=:username';
+ $params[':username'] = $user['username'];
+
+ $user_exists = user_check($user);
+ $is_mobile = preg_match(REGULAR_MOBILE, $user['username']);
+ if (!$user_exists && !empty($user['username']) && $is_mobile) {
+ $sql = "select b.uid, u.username FROM " . tablename('users_bind') . " AS b LEFT JOIN " . tablename('users') . " AS u ON b.uid = u.uid WHERE b.bind_sign = :bind_sign";
+ $bind_info = pdo_fetch($sql, array('bind_sign' => $user['username']));
+ if (!is_array($bind_info) || empty($bind_info) || empty($bind_info['username'])) {
+ return false;
+ }
+ $params[':username'] = $bind_info['username'];
+ }
+ }
+ if (!empty($user['email'])) {
+ $where .= ' AND u.`email`=:email';
+ $params[':email'] = $user['email'];
+ }
+ if (!empty($user['status'])) {
+ $where .= " AND u.`status`=:status";
+ $params[':status'] = intval($user['status']);
+ }
+ if (empty($params)) {
+ return false;
+ }
+ $sql = 'SELECT u.*, p.avatar FROM ' . tablename('users') . ' AS u LEFT JOIN ' . tablename('users_profile') . ' AS p ON u.uid = p.uid ' . $where . ' LIMIT 1';
+
+ $record = pdo_fetch($sql, $params);
+ if (empty($record)) {
+ return false;
+ }
+ if (!empty($user['password'])) {
+ $password = user_hash($user['password'], $record['salt']);
+ if ($password != $record['password']) {
+ return false;
+ }
+ }
+
+ $record['hash'] = md5($record['password'] . $record['salt']);
+ unset($record['password'], $record['salt']);
+ $record['name'] = $record['username'];
+ $record['clerk_id'] = $user['uid'];
+ $record['store_id'] = 0;
+ $record['clerk_type'] = '2';
+
+ $third_info = pdo_getall('users_bind', array('uid' => $record['uid']), array(), 'third_type');
+ if (!empty($third_info) && is_array($third_info)) {
+ $record['qq_openid'] = $third_info[USER_REGISTER_TYPE_QQ]['bind_sign'];
+ $record['wechat_openid'] = $third_info[USER_REGISTER_TYPE_WECHAT]['bind_sign'];
+ $record['mobile'] = $third_info[USER_REGISTER_TYPE_MOBILE]['bind_sign'];
+ }
+ $record['notice_setting'] = iunserializer($record['notice_setting']);
+ return $record;
+}
+
+
+function user_related_update($uid, $user)
+{
+ $uid = intval($uid);
+ if (empty($uid) || !is_array($user)) {
+ return false;
+ }
+
+ if (isset($user['groupid'])) {
+ $record['groupid'] = $user['groupid'];
+ $user_info = table('users')->getById($uid);
+ if ($user_info['founder_groupid'] == ACCOUNT_MANAGE_GROUP_VICE_FOUNDER || $user['founder_groupid'] == ACCOUNT_MANAGE_GROUP_VICE_FOUNDER) {
+ $group_info = user_founder_group_detail_info($user['groupid']);
+ } else {
+ $group_info = user_group_detail_info($user['groupid']);
+ }
+ if (!empty($group_info)) {
+ $group_info['timelimit'] = intval($group_info['timelimit']);
+ if ($group_info['timelimit'] > 0) {
+ $extra_limit_table = table('users_extra_limit');
+ $extraLimit = $extra_limit_table->getExtraLimitByUid($user_info['uid']);
+ $time_limit = $group_info['timelimit'] + $extraLimit['timelimit'];
+ $user_end_time = strtotime($time_limit . ' days', max($user_info['joindate'], $user_info['starttime']));
+ if (user_is_vice_founder() && !empty($_W['user']['endtime'])) {
+ $user_end_time = min($user_end_time, $_W['user']['endtime']);
+ }
+ } else {
+ $user_end_time = USER_ENDTIME_GROUP_UNLIMIT_TYPE;
+ }
+ $change_status = $user_end_time;
+ pdo_update('users', array('endtime' => $user_end_time), array('uid' => $uid));
+ }
+ }
+ if (isset($user['endtime']) || !empty($change_status)) {
+ $expire_notice = setting_load('user_expire');
+ if (!empty($expire_notice['user_expire']['status'])) {
+ $user_info = empty($user_info) ? table('users')->getById($user['uid']) : $user_info;
+ if ($user_info['endtime'] != $record['endtime']) {
+ pdo_update('users_profile', array('send_expire_status' => 0), array('uid' => intval($user_info['uid'])));
+ }
+ }
+ }
+
+ return true;
+}
+
+
+function user_hash($passwordinput, $salt)
+{
+ global $_W;
+ $passwordinput = "{$passwordinput}-{$salt}-{$_W['config']['setting']['authkey']}";
+ return sha1($passwordinput);
+}
+
+
+function user_password_hash($password, $uid)
+{
+ if (empty($password) || intval($uid) <= 0) {
+ return '';
+ }
+ $user_info = table('users')->getById($uid);
+ if (empty($user_info)) {
+ return '';
+ }
+ return md5($password . $user_info['salt']);
+}
+
+
+function user_password($passwordinput, $uid)
+{
+ if (empty($passwordinput) || intval($uid) <= 0) {
+ return '';
+ }
+ $user_info = table('users')->getById($uid);
+ if (empty($user_info)) {
+ return '';
+ }
+ return user_hash($passwordinput, $user_info['salt']);
+}
+
+
+function user_level()
+{
+ static $level = array(
+ '-3' => '锁定用户',
+ '-2' => '禁止访问',
+ '-1' => '禁止发言',
+ '0' => '普通会员',
+ '1' => '管理员',
+ );
+ return $level;
+}
+
+
+function user_group()
+{
+ global $_W;
+ $users_group_table = table('users_group');
+ if (user_is_vice_founder()) {
+ $users_group_table->getOwnUsersGroupsList($_W['uid']);
+ }
+ return $users_group_table->getUsersGroupList();
+}
+
+
+function user_founder_group()
+{
+ $groups = pdo_getall('users_founder_group', array(), '*', 'id', 'id ASC');
+ return $groups;
+}
+
+
+function user_group_detail_info($groupid = 0)
+{
+ $group_info = array();
+
+ $groupid = is_array($groupid) ? 0 : intval($groupid);
+ if (empty($groupid)) {
+ return $group_info;
+ }
+ $group_info = pdo_get('users_group', array('id' => $groupid));
+ if (empty($group_info)) {
+ return $group_info;
+ }
+
+ $group_info['package'] = (array)iunserializer($group_info['package']);
+ if (!empty($group_info['package']) && !in_array(-1, $group_info['package'])) {
+ $group_info['package_detail'] = uni_groups($group_info['package']);
+
+ $group_info['user_group_modules_all'] = array();
+ if (!empty($group_info['package_detail'])) {
+ foreach ($group_info['package_detail'] as $package_detail) {
+ if (!empty($package_detail['modules_all'])) {
+ foreach ($package_detail['modules_all'] as $mdoule_key => $module_val) {
+ $group_info['user_group_modules_all'][$mdoule_key] = $module_val;
+ }
+ }
+ }
+ }
+ } else {
+ $group_info['modules'] = empty($group_info['package']) ? '' : 'all';
+ $group_info['templates'] = empty($group_info['package']) ? '' : 'all';
+ }
+
+ return $group_info;
+}
+
+
+function user_founder_group_detail_info($groupid = 0)
+{
+ $group_info = array();
+
+ $groupid = is_array($groupid) ? 0 : intval($groupid);
+ if (empty($groupid)) {
+ return $group_info;
+ }
+ $group_info = pdo_get('users_founder_group', array('id' => $groupid));
+ if (empty($group_info)) {
+ return $group_info;
+ }
+
+ $group_info['package'] = (array)iunserializer($group_info['package']);
+ if (!empty($group_info['package'])) {
+ $group_info['package_detail'] = uni_groups($group_info['package']);
+ }
+ return $group_info;
+}
+
+
+function user_account_detail_info($uid)
+{
+ $account_lists = $app_user_info = $wxapp_user_info = $webapp_user_info = array();
+ $uid = intval($uid);
+ if (empty($uid)) {
+ return $account_lists;
+ }
+
+ $account_users_info = table('account')->userOwnedAccount($uid);
+ $account_type_signs = uni_account_type();
+ $accounts = array();
+ if (!empty($account_users_info)) {
+ foreach ($account_users_info as $uniacid => $account) {
+ $type_sign = $account_type_signs[$account['type']]['type_sign'];
+ if (empty($type_sign)) {
+ continue;
+ }
+ $account_info = uni_fetch($uniacid);
+ $account_info['role'] = permission_account_user_role($uid, $uniacid);
+ $accounts[$type_sign][$uniacid] = $account_info;
+ }
+ }
+ return $accounts;
+}
+
+
+function user_modules($uid = 0)
+{
+ global $_W;
+ load()->model('module');
+ if (empty($uid)) {
+ $uid = $_W['uid'];
+ }
+ $support_type = module_support_type();
+ $modules = cache_load(cache_system_key('user_modules', array('uid' => $uid)));
+ if (empty($modules)) {
+ $user_info = user_single(array('uid' => $uid));
+ $extra_modules = table('users_extra_modules')->getExtraModulesByUid($uid);
+
+ $users_extra_group_table = table('users_extra_group');
+ $extra_groups = $users_extra_group_table->getUniGroupsByUid($uid);
+
+ if (empty($uid) || user_is_founder($uid, true)) {
+ $module_list = table('modules')->getNonRecycleModules();
+ $module_list = modules_support_all(array_keys($module_list));
+ } elseif (!empty($user_info) && $user_info['type'] == ACCOUNT_OPERATE_CLERK && $user_info['founder_groupid'] != ACCOUNT_MANAGE_GROUP_VICE_FOUNDER) {
+ $clerk_module = pdo_fetch("SELECT p.type FROM " . tablename('users_permission') . " p LEFT JOIN " . tablename('uni_account_users') . " u ON p.uid = u.uid AND p.uniacid = u.uniacid WHERE u.role = :role AND p.uid = :uid", array(':role' => ACCOUNT_MANAGE_NAME_CLERK, ':uid' => $uid));
+ if (empty($clerk_module)) {
+ return array();
+ }
+ $module_list = array($clerk_module['type'] => $clerk_module['type']);
+ $module_list = modules_support_all(array_keys($module_list));
+ } elseif (!empty($user_info) && empty($user_info['groupid']) && empty($extra_modules) && empty($extra_groups)) {
+ $module_list = pdo_getall('modules', array('issystem' => 1), array('name'), 'name');
+ $module_list = modules_support_all(array_keys($module_list));
+ } else {
+ if ($user_info['founder_groupid'] == ACCOUNT_MANAGE_GROUP_VICE_FOUNDER) {
+ $user_group_info = user_founder_group_detail_info($user_info['groupid']);
+ } else {
+ $user_group_info = user_group_detail_info($user_info['groupid']);
+ }
+ $packageids = $user_group_info['package'];
+ if (!empty($packageids) && in_array('-1', $packageids)) {
+ $module_list = table('modules')->getNonRecycleModules();
+ $module_list = modules_support_all(array_keys($module_list));
+ } else {
+ $module_list = array();
+ $package_group = (array)pdo_getall('uni_group', array('id' => $packageids));
+ $uni_group_add = pdo_get('uni_group', array('uid' => $uid));
+ if (!empty($uni_group_add)) {
+ $package_group[] = $uni_group_add;
+ }
+
+ $users_extra_group_table = table('users_extra_group');
+ $extra_groups = $users_extra_group_table->getUniGroupsByUid($uid);
+ $extra_uni_groups = pdo_getall('uni_group', array('id' => array_keys($extra_groups)));
+ $package_group = array_merge($package_group, $extra_uni_groups);
+ if (!empty($package_group)) {
+ foreach ($package_group as $row) {
+ $row['modules'] = iunserializer($row['modules']);
+ if (empty($row) || empty($row['modules'])) {
+ continue;
+ }
+ foreach ($row['modules'] as $type => $modulenames) {
+ if (!is_array($modulenames) || empty($modulenames)) {
+ continue;
+ }
+ foreach ($modulenames as $name) {
+ switch ($type) {
+ case 'modules':
+ $module_list[$name][] = MODULE_SUPPORT_ACCOUNT_NAME;
+ break;
+ case 'account':
+ $module_list[$name][] = MODULE_SUPPORT_ACCOUNT_NAME;
+ break;
+ case 'wxapp':
+ $module_list[$name][] = MODULE_SUPPORT_WXAPP_NAME;
+ break;
+ case 'webapp':
+ $module_list[$name][] = MODULE_SUPPORT_WEBAPP_NAME;
+ break;
+ case 'phoneapp':
+ $module_list[$name][] = MODULE_SUPPORT_PHONEAPP_NAME;
+ break;
+ case 'aliapp':
+ $module_list[$name][] = MODULE_SUPPORT_ALIAPP_NAME;
+ break;
+ case 'baiduapp':
+ $module_list[$name][] = MODULE_SUPPORT_BAIDUAPP_NAME;
+ break;
+ case 'toutiaoapp':
+ $module_list[$name][] = MODULE_SUPPORT_TOUTIAOAPP_NAME;
+ break;
+ case 'welcome':
+ $module_list[$name][] = MODULE_SUPPORT_SYSTEMWELCOME_NAME;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!empty($extra_modules)) {
+ foreach ($extra_modules as $extra_module_key => $extra_module_val) {
+ if (!empty($module_list[$extra_module_val['module_name']]) && $module_list[$extra_module_val['module_name']] == 'all') {
+ continue;
+ }
+ $module_list[$extra_module_val['module_name']][] = $extra_module_val['support'];
+ }
+ }
+
+ $modules = array();
+ if (!empty($module_list)) {
+ $have_plugin_module = array();
+ $plugin_list = pdo_getall('modules_plugin', array('name' => array_keys($module_list)), array());
+ if (!empty($plugin_list)) {
+ foreach ($plugin_list as $plugin) {
+ $have_plugin_module[$plugin['main_module']][$plugin['name']] = $module_list[$plugin['name']];
+ unset($module_list[$plugin['name']]);
+ }
+ }
+ if (!empty($module_list)) {
+ foreach ($module_list as $module => $support) {
+ $modules[$module] = $support;
+ if (!empty($have_plugin_module[$module])) {
+ foreach ($have_plugin_module[$module] as $plugin => $plugin_support) {
+ $modules[$plugin] = $plugin_support;
+ }
+ }
+ }
+ }
+ }
+ cache_write(cache_system_key('user_modules', array('uid' => $uid)), $modules);
+ }
+
+ $module_list = array();
+ if (!empty($modules)) {
+ $modulenames = array_keys($modules);
+ $all_modules = table('modules')->searchWithName($modulenames)->getAll('name');
+ $plugin_data = table('modules_plugin')->getAllByNameOrMainModule($modulenames);
+ $all_recycle_info = table('modules_recycle')->searchWithNameType($modulenames, MODULE_RECYCLE_INSTALL_DISABLED)->getall('name');
+
+ foreach ($all_modules as $k => $value) {
+ $all_modules[$k]['logo'] = tomedia($all_modules[$k]['logo']);
+ $all_modules[$k]['subscribes'] = (array)iunserializer($all_modules[$k]['subscribes']);
+ $all_modules[$k]['handles'] = (array)iunserializer($all_modules[$k]['handles']);
+ $all_modules[$k]['isdisplay'] = 1;
+ $all_modules[$k]['main_module'] = '';
+ $all_modules[$k]['plugin_list'] = array();
+ }
+ foreach ($plugin_data as $value) {
+ $all_modules[$value['main_module']]['plugin_list'][] = $value['name'];
+ $all_modules[$value['name']]['main_module'] = $value['main_module'];
+ $all_modules[$value['name']]['main_module_logo'] = $all_modules[$value['main_module']]['logo'];
+ $all_modules[$value['name']]['main_module_title'] = $all_modules[$value['main_module']]['title'];
+ }
+
+ foreach ($modules as $modulename => $support) {
+ if (empty($all_modules[$modulename]) || (!empty($_W['account']) && is_array($support) && !in_array($_W['account']->typeSign . '_support', $support))) {
+ continue;
+ }
+ $module_info = $all_modules[$modulename];
+ foreach ($support_type as $support_name => $value) {
+ if (!empty($all_recycle_info[$modulename])) {
+ if ($all_recycle_info[$modulename][$support_name] > 0 && $module_info[$support_name] == $value['support']) {
+ $module_info[$support_name] = $value['not_support'];
+ }
+ }
+ if ($support !== 'all' && !empty($support)) {
+ if ($module_info[$support_name] == $value['support'] && !in_array($support_name, $support)) {
+ $module_info[$support_name] = $value['not_support'];
+ }
+ }
+ }
+
+ $is_continue = true;
+ foreach ($support_type as $support_name => $value) {
+ if ($module_info[$support_name] == $value['support']) {
+ $is_continue = false;
+ }
+ }
+ if ($is_continue) {
+ continue;
+ }
+ $module_list[$modulename] = $module_info;
+ }
+ }
+ return $module_list;
+}
+
+function modules_support_all($modulenames)
+{
+ if (empty($modulenames)) {
+ return array();
+ }
+ $data = array();
+ foreach ($modulenames as $name) {
+ $data[$name] = 'all';
+ }
+ return $data;
+}
+
+
+function user_login_forward($forward = '')
+{
+ global $_W;
+ load()->model('module');
+ $login_forward = trim($forward);
+
+ if (!empty($forward)) {
+ return $login_forward;
+ }
+
+ return $url = './home.php';
+
+ if ($_W['isadmin']) {
+ return url('home/welcome/system', array('page' => 'home'));
+ } else {
+ $user_end_time = user_end_time($_W['uid']);
+ if (!empty($user_end_time) && strtotime($user_end_time) < TIMESTAMP) {
+ return url('user/profile');
+ }
+ }
+
+ $login_forward = user_after_login_link();
+ return $login_forward;
+}
+
+function user_invite_register_url($uid = 0)
+{
+ global $_W;
+ if (empty($uid)) {
+ $uid = $_W['uid'];
+ }
+ return $_W['siteroot'] . 'web/index.php?c=user&a=register&owner_uid=' . $uid;
+}
+
+
+function user_save_create_group($account_group_info)
+{
+ global $_W;
+ $account_group_table = table('users_create_group');
+
+ $group_name = trim($account_group_info['group_name']);
+ $id = $account_group_info['id'];
+
+ if (empty($group_name)) {
+ return error(-1, '账户权限组不能为空');
+ }
+
+ $account_group_table->searchWithGroupName($group_name);
+
+ if (!empty($id)) {
+ $account_group_table->searchWithoutId($id);
+ }
+
+ $account_group_exist = $account_group_table->getCreateGroupInfo();
+
+ if (!empty($account_group_exist)) {
+ return error(-1, '账户权限组已经存在!');
+ }
+
+ if (user_is_vice_founder()) {
+ $premission_check_result = permission_check_vice_founder_limit($account_group_info);
+ if (is_error($premission_check_result)) {
+ return $premission_check_result;
+ }
+ }
+
+ if (empty($id)) {
+ pdo_insert('users_create_group', $account_group_info);
+ $create_group_id = pdo_insertid();
+ if (user_is_vice_founder()) {
+ $own_create_group_table = table('users_founder_own_create_groups');
+ $own_create_group_table->addOwnCreateGroup($_W['uid'], $create_group_id);
+ }
+ } else {
+ pdo_update('users_create_group', $account_group_info, array('id' => $account_group_info['id']));
+ }
+ return error(0, '添加成功!');
+}
+
+
+function user_save_group($group_info)
+{
+ global $_W;
+ $group_table = table('users_group');
+ $name = trim($group_info['name']);
+ if (empty($name)) {
+ return error(-1, '用户权限组名不能为空');
+ }
+
+ $group_table->searchWithName($name);
+ if (!empty($group_info['id'])) {
+ $group_table->searchWithNoId($group_info['id']);
+ }
+ $name_exist = $group_table->getUsersGroupList();
+
+ if (!empty($name_exist)) {
+ return error(-1, '用户权限组名已存在!');
+ }
+ if (user_is_vice_founder()) {
+ $permission_check_result = permission_check_vice_founder_limit($group_info);
+ if (is_error($permission_check_result)) {
+ return $permission_check_result;
+ }
+ }
+
+ if (!empty($group_info['package'])) {
+ foreach ($group_info['package'] as $value) {
+ $package[] = intval($value);
+ }
+ }
+ $group_info['package'] = iserializer($package);
+ if (empty($group_info['id'])) {
+ pdo_insert('users_group', $group_info);
+ $users_group_id = pdo_insertid();
+ if (user_is_vice_founder()) {
+ $table = table('users_founder_own_users_groups');
+ $table->addOwnUsersGroup($_W['uid'], $users_group_id);
+ }
+ } else {
+ $old_group = $group_table->getById($group_info['id']);
+ if (empty($old_group)) {
+ return error(-1, '参数有误');
+ }
+ $result = pdo_update('users_group', $group_info, array('id' => $group_info['id']));
+ if (!empty($result) && $old_group['timelimit'] != $group_info['timelimit']) {
+ $all_group_users = table('users')
+ ->where('founder_groupid', ACCOUNT_MANAGE_GROUP_GENERAL)
+ ->where('groupid', $old_group['id'])
+ ->getall();
+ if (!empty($all_group_users)) {
+ foreach ($all_group_users as $user) {
+ if ($group_info['timelimit'] > 0) {
+ $endtime = strtotime($group_info['timelimit'] . ' days', max($user['joindate'], $user['starttime']));
+ if (user_is_vice_founder() && !empty($_W['user']['endtime'])) {
+ $endtime = min($endtime, $_W['user']['endtime']);
+ }
+ } else {
+ $endtime = 0;
+ }
+ $data['endtime'] = $endtime;
+ pdo_update('users', $data, array('uid' => $user['uid']));
+ user_related_update($user['uid'], $data);
+ }
+ }
+ }
+ }
+
+ return error(0, '添加成功');
+}
+
+
+function user_save_founder_group($group_info)
+{
+ $name = trim($group_info['name']);
+ if (empty($name)) {
+ return error(-1, '用户权限组名不能为空');
+ }
+
+ if (!empty($group_info['id'])) {
+ $name_exist = pdo_get('users_founder_group', array('id <>' => $group_info['id'], 'name' => $name));
+ } else {
+ $name_exist = pdo_get('users_founder_group', array('name' => $name));
+ }
+
+ if (!empty($name_exist)) {
+ return error(-1, '用户权限组名已存在!');
+ }
+
+ if (!empty($group_info['package'])) {
+ foreach ($group_info['package'] as $value) {
+ $package[] = intval($value);
+ }
+ }
+ $group_info['package'] = iserializer($package);
+
+ if (empty($group_info['id'])) {
+ pdo_insert('users_founder_group', $group_info);
+ } else {
+ $old_group = table('users_founder_group')->getById($group_info['id']);
+ if (empty($old_group)) {
+ return error(-1, '参数有误');
+ }
+ $result = pdo_update('users_founder_group', $group_info, array('id' => $group_info['id']));
+ if (!empty($result) && $old_group['timelimit'] != $group_info['timelimit']) {
+ $all_group_users = table('users')
+ ->where('founder_groupid', ACCOUNT_MANAGE_GROUP_VICE_FOUNDER)
+ ->where('groupid', $old_group['id'])
+ ->getall();
+ if (!empty($all_group_users)) {
+ foreach ($all_group_users as $user) {
+ if ($group_info['timelimit'] > 0) {
+ $endtime = strtotime($group_info['timelimit'] . ' days', max($user['joindate'], $user['starttime']));
+ } else {
+ $endtime = 0;
+ }
+ $data['endtime'] = $endtime;
+ pdo_update('users', $data, array('uid' => $user['uid']));
+ user_related_update($user['uid'], $data);
+ }
+ }
+ }
+ }
+
+ return error(0, '添加成功');
+}
+
+
+function user_group_format($lists)
+{
+ if (empty($lists)) {
+ return $lists;
+ }
+ $all_package = array();
+ foreach ($lists as $key => $group) {
+ if (empty($group['package'])) {
+ continue;
+ }
+ $package = iunserializer($group['package']);
+ if (!is_array($package)) {
+ continue;
+ }
+ $all_package = array_merge($all_package, $package);
+ }
+ $group_package = uni_groups($all_package);
+
+ foreach ($lists as $key => $group) {
+ $package = iunserializer($group['package']);
+ $lists[$key]['package'] = $package;
+ $group['package'] = array();
+ if (is_array($package)) {
+ foreach ($package as $packageid) {
+ $group['package'][$packageid] = $group_package[$packageid];
+ }
+ }
+ if (empty($package)) {
+ $lists[$key]['module_nums'] = 0;
+ $lists[$key]['wxapp_nums'] = 0;
+ $lists[$key]['webapp_nums'] = 0;
+ $lists[$key]['phoneapp_nums'] = 0;
+ continue;
+ }
+ if (is_array($package) && in_array(-1, $package)) {
+ $lists[$key]['module_nums'] = -1;
+ $lists[$key]['wxapp_nums'] = -1;
+ $lists[$key]['webapp_nums'] = -1;
+ $lists[$key]['phoneapp_nums'] = -1;
+ continue;
+ }
+ $names = array();
+ $modules = array(
+ 'modules' => array(),
+ 'wxapp' => array(),
+ 'webapp' => array(),
+ 'phoneapp' => array(),
+ );
+ if (!empty($group['package'])) {
+ foreach ($group['package'] as $package) {
+ $names[] = $package['name'];
+ $package['modules'] = !empty($package['modules']) && is_array($package['modules']) ? array_keys($package['modules']) : array();
+ $package['wxapp'] = !empty($package['wxapp']) && is_array($package['wxapp']) ? array_keys($package['wxapp']) : array();
+ $package['webapp'] = !empty($package['webapp']) && is_array($package['webapp']) ? array_keys($package['webapp']) : array();
+ $package['phoneapp'] = !empty($package['phoneapp']) && is_array($package['phoneapp']) ? array_keys($package['phoneapp']) : array();
+ $modules['modules'] = array_unique(array_merge($modules['modules'], $package['modules']));
+ $modules['wxapp'] = array_unique(array_merge($modules['wxapp'], $package['wxapp']));
+ $modules['webapp'] = array_unique(array_merge($modules['webapp'], $package['webapp']));
+ $modules['phoneapp'] = array_unique(array_merge($modules['phoneapp'], $package['phoneapp']));
+ }
+ $lists[$key]['module_nums'] = count($modules['modules']);
+ $lists[$key]['wxapp_nums'] = count($modules['wxapp']);
+ $lists[$key]['webapp_nums'] = count($modules['webapp']);
+ $lists[$key]['phoneapp_nums'] = count($modules['phoneapp']);
+ }
+ $lists[$key]['packages'] = implode(',', $names);
+ }
+ return $lists;
+}
+
+
+function user_end_time($uid)
+{
+ $user = table('users')->getById($uid);
+ if ($user['endtime'] == USER_ENDTIME_GROUP_EMPTY_TYPE || $user['endtime'] == USER_ENDTIME_GROUP_UNLIMIT_TYPE) {
+ $user['end'] = 0;
+ } elseif ($user['endtime'] == USER_ENDTIME_GROUP_DELETE_TYPE) {
+ $user['end'] = date('Y-m-d', $user['joindate']);
+ } else {
+ $user['end'] = date('Y-m-d', $user['endtime']);
+ }
+ return $user['end'];
+}
+
+
+function user_list_format($users, $founder_list = true)
+{
+ if (empty($users)) {
+ return array();
+ }
+ foreach ($users as &$user) {
+ $user['avatar'] = !empty($user['avatar']) ? $user['avatar'] : './resource/images/nopic-user.png';
+ $user['joindate'] = date('Y-m-d', $user['joindate']);
+ if ($user['endtime'] == USER_ENDTIME_GROUP_EMPTY_TYPE || $user['endtime'] == USER_ENDTIME_GROUP_UNLIMIT_TYPE) {
+ $user['endtime'] = '永久有效';
+ } else {
+ $user['endtime'] = $user['endtime'] <= TIMESTAMP ? '服务已到期' : date('Y-m-d', intval($user['endtime']));
+ }
+
+ $user['module_num'] = array();
+ if ($founder_list) {
+ $user['account_nums'] = permission_user_account_num($user['uid']);
+ }
+ $user['groupname'] = '';
+ }
+ return $users;
+}
+
+function user_info_check($user)
+{
+ if (!preg_match(REGULAR_USERNAME, $user['username'])) {
+ return error(-1, '必须输入用户名,格式为 3-30 位字符,可以包括汉字、字母(不区分大小写)、数字、下划线和句点。');
+ }
+ if (user_check(array('username' => $user['username']))) {
+ return error(-2, '非常抱歉,此用户名已经被注册,你需要更换注册名称!');
+ }
+ if (istrlen($user['password']) < 8) {
+ return error(-3, '必须输入密码,且密码长度不得低于8位。');
+ } else {
+ $check_pass = safe_check_password(safe_gpc_string($user['password']));
+ if (is_error($check_pass)) {
+ return $check_pass;
+ }
+ }
+ if (trim($user['password']) !== trim($user['repassword'])) {
+ return error(-4, '两次密码不一致!');
+ }
+ return error(0, '');
+}
+
+
+function user_info_save($user, $is_founder_group = false)
+{
+ global $_W;
+ $check_result = user_info_check($user);
+ if (is_error($check_result)) {
+ return $check_result;
+ }
+
+ $timelimit = 0;
+ $timeadd = 0;
+ if ($timelimit > 0) {
+ $timeadd = strtotime($timelimit . ' days');
+ }
+ if (user_is_vice_founder() && !empty($_W['user']['endtime'])) {
+ $timeadd = !empty($timeadd) ? min($timeadd, $_W['user']['endtime']) : $_W['user']['endtime'];
+ }
+ if (empty($timeadd)) {
+ $user['endtime'] = max(0, $user['endtime']);
+ } else {
+ $user['endtime'] = empty($user['endtime']) ? $timeadd : min($timeadd, $user['endtime']);
+ }
+ unset($user['vice_founder_name']);
+ unset($user['repassword']);
+ $user_add_id = user_register($user, 'admin');
+ if (empty($user_add_id)) {
+ return error(-1, '增加失败,请稍候重试或联系网站管理员解决!');
+ }
+ return array('uid' => $user_add_id);
+}
+
+
+function user_detail_formate($profile)
+{
+ if (!empty($profile)) {
+ $profile['reside'] = array(
+ 'province' => $profile['resideprovince'],
+ 'city' => $profile['residecity'],
+ 'district' => $profile['residedist']
+ );
+ $profile['birth'] = array(
+ 'year' => $profile['birthyear'],
+ 'month' => $profile['birthmonth'],
+ 'day' => $profile['birthday'],
+ );
+ $profile['avatar'] = tomedia($profile['avatar']);
+ $profile['resides'] = $profile['resideprovince'] . $profile['residecity'] . $profile['residedist'];
+ $profile['births'] = ($profile['birthyear'] ? $profile['birthyear'] : '--') . '年' . ($profile['birthmonth'] ? $profile['birthmonth'] : '--') . '月' . ($profile['birthday'] ? $profile['birthday'] : '--') . '日';
+ }
+ return $profile;
+}
+
+
+function user_support_urls()
+{
+ global $_W;
+ load()->classs('oauth2/oauth2client');
+ $types = OAuth2Client::supportLoginType();
+ $login_urls = array();
+ foreach ($types as $type) {
+ if (!empty($_W['setting']['thirdlogin'][$type]['authstate'])) {
+ $login_urls[$type] = OAuth2Client::create($type, $_W['setting']['thirdlogin'][$type]['appid'], $_W['setting']['thirdlogin'][$type]['appsecret'])->showLoginUrl();
+ }
+ }
+ if (empty($login_urls)) {
+ $login_urls['system'] = true;
+ }
+ return $login_urls;
+}
+
+
+function user_borrow_oauth_account_list()
+{
+ global $_W;
+ $user_have_accounts = uni_user_accounts($_W['uid']);
+ $oauth_accounts = array();
+ $jsoauth_accounts = array();
+ if (!empty($user_have_accounts)) {
+ foreach ($user_have_accounts as $account) {
+ if (!empty($account['key']) && (!empty($account['secret']) || $account['type'] == ACCOUNT_TYPE_OFFCIAL_AUTH)) {
+ if (in_array($account['level'], array(ACCOUNT_SERVICE_VERIFY))) {
+ $oauth_accounts[$account['acid']] = $account['name'];
+ }
+ if (in_array($account['level'], array(ACCOUNT_SUBSCRIPTION_VERIFY, ACCOUNT_SERVICE_VERIFY))) {
+ $jsoauth_accounts[$account['acid']] = $account['name'];
+ }
+ }
+ }
+ }
+ return array(
+ 'oauth_accounts' => $oauth_accounts,
+ 'jsoauth_accounts' => $jsoauth_accounts
+ );
+}
+
+
+function user_founder_templates($founder_groupid)
+{
+ $group_detail_info = user_founder_group_detail_info($founder_groupid);
+
+ if (empty($group_detail_info) || empty($group_detail_info['package'])) {
+ return array();
+ }
+
+ if (in_array(-1, $group_detail_info['package'])) {
+ $template_list = table('modules')->getAllTemplates();
+ return $template_list;
+ }
+
+ $template_list = array();
+ foreach ($group_detail_info['package'] as $uni_group) {
+ if (!empty($group_detail_info['package_detail'][$uni_group]['templates'])) {
+ $template_list = array_merge($template_list, $group_detail_info['package_detail'][$uni_group]['templates']);
+ }
+ }
+ return $template_list;
+}
+
+
+function user_is_bind()
+{
+ global $_W;
+ if ($_W['isfounder']) {
+ return true;
+ }
+ $setting_bind = empty($_W['setting']['copyright']['bind']) ? '' : $_W['setting']['copyright']['bind'];
+ if (!empty($_W['user']['type']) && $_W['user']['type'] == USER_TYPE_CLERK) {
+ $setting_bind = empty($_W['setting']['copyright']['clerk']['bind']) ? '' : $_W['setting']['copyright']['clerk']['bind'];
+ }
+ if (empty($setting_bind)) {
+ return true;
+ }
+
+ load()->classs('oauth2/oauth2client');
+ $type_info = OAuth2Client::supportBindTypeInfo($setting_bind);
+ if (empty($type_info)) {
+ return true;
+ }
+ return OAuth2Client::create($setting_bind)->isbind();
+}
+
+
+function user_check_mobile($mobile)
+{
+ if (empty($mobile)) {
+ return error(-1, '手机号不能为空');
+ }
+ if (!preg_match(REGULAR_MOBILE, $mobile)) {
+ return error(-1, '手机号格式不正确');
+ }
+
+ $find_mobile = table('users_profile')->getByMobile($mobile);
+ if (empty($find_mobile)) {
+ return error(-1, '手机号不存在');
+ }
+ return $find_mobile;
+}
+
+
+function user_change_welcome_status($uid, $welcome_status)
+{
+ if (empty($uid)) {
+ return true;
+ }
+ $user_table = table('users');
+ $user_table->fillWelcomeStatus($welcome_status)->whereUid($uid)->save();
+ return true;
+}
+
+
+function user_after_login_link()
+{
+ global $_W;
+ $url = '';
+ $type = WELCOME_DISPLAY_TYPE;
+ if (!empty($_W['user']['welcome_link'])) {
+ $type = $_W['user']['welcome_link'];
+ }
+
+ switch ($type) {
+ case WELCOME_DISPLAY_TYPE:
+ $url = './home.php';
+ break;
+ case PLATFORM_DISPLAY_TYPE:
+ case MODULE_DISPLAY_TYPE:
+ default:
+ $last_operate = table('users_operate_history')->where('uid', $_W['uid'])->orderby('createtime', 'DESC')->get();
+ if (USERS_OPERATE_TYPE_ACCOUNT == $last_operate['type']) {
+ $url = url('account/display/platform');
+ } elseif (USERS_OPERATE_TYPE_MODULE == $last_operate['type']) {
+ $url = url('account/display/switch', array('module_name' => $last_operate['module_name'], 'uniacid' => $last_operate['uniacid'], 'switch_uniacid' => 1));
+ }
+ break;
+ }
+ if (empty($url)) {
+ $url = './home.php';
+ }
+ return $url;
+}
+
+function user_available_extra_fields()
+{
+ $default_field = array('realname', 'births', 'qq', 'mobile', 'address', 'resides');
+ $fields = table('core_profile_fields')->getall();
+ $extra_fields = array();
+ if (!empty($fields) && is_array($fields)) {
+ foreach ($fields as $field_info) {
+ if ($field_info['available'] == 1 && $field_info['showinregister'] == 1 && !in_array($field_info['field'], $default_field)) {
+ $extra_fields[] = $field_info;
+ }
+ }
+ }
+ return $extra_fields;
+}
+
+function user_lastuse_module_default_account()
+{
+ return table('users_lastuse')->getDefaultModulesAccount();
+}
+
+function user_role_title($role = '')
+{
+ $data = array(
+ ACCOUNT_MANAGE_NAME_FOUNDER => '创始人',
+ ACCOUNT_MANAGE_NAME_VICE_FOUNDER => '副创始人',
+ ACCOUNT_MANAGE_NAME_OWNER => '主管理员',
+ ACCOUNT_MANAGE_NAME_MANAGER => '管理员',
+ ACCOUNT_MANAGE_NAME_OPERATOR => '操作员',
+ ACCOUNT_MANAGE_NAME_CLERK => '店员',
+ );
+ if (!empty($role)) {
+ return empty($data[$role]) ? '' : $data[$role];
+ }
+ return $data;
+}
+
+
+function user_save_operate_history($type, $value)
+{
+ global $_W;
+ $vaild_type = array(USERS_OPERATE_TYPE_ACCOUNT, USERS_OPERATE_TYPE_MODULE);
+ if (!in_array($type, $vaild_type)) {
+ return false;
+ }
+ $data = array('uid' => $_W['uid'], 'type' => $type);
+ if (USERS_OPERATE_TYPE_ACCOUNT == $type) {
+ $data['uniacid'] = $value;
+ } elseif (USERS_OPERATE_TYPE_MODULE == $type) {
+ $data['module_name'] = $value;
+ $data['uniacid'] = $_W['uniacid'];
+ }
+ table('users_operate_history')->deleteByUidTypeOperate($data);
+ $data['createtime'] = TIMESTAMP;
+ $result = table('users_operate_history')->fill($data)->save();
+ if ($result) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function user_load_operate_history($limit_num = 40)
+{
+ global $_W;
+ $users_operate_history_table = table('users_operate_history');
+ $users_operate_history_table->searchWithLimit($limit_num);
+ $result = $users_operate_history_table->getALlByUid($_W['uid']);
+ return $result;
+}
+
+function user_save_operate_star($type, $uniacid, $module_name)
+{
+ global $_W;
+ if (!in_array($type, array(USERS_OPERATE_TYPE_ACCOUNT, USERS_OPERATE_TYPE_MODULE)) || empty($uniacid)) {
+ return error(-1, '参数不合法!');
+ }
+ if (USERS_OPERATE_TYPE_MODULE == $type) {
+ if (!empty($module_name) && !module_exist_in_account($module_name, $uniacid)) {
+ return error(-1, '平台账号无该模块权限,请更新缓存后重试!');
+ }
+ }
+ $data = array('uid' => $_W['uid'], 'uniacid' => $uniacid, 'module_name' => $module_name, 'type' => $type);
+ if (USERS_OPERATE_TYPE_ACCOUNT == $type) {
+ unset($data['module_name']);
+ }
+ $if_exists = table('users_operate_star')->where($data)->get();
+ if ($if_exists) {
+ $result = table('users_operate_star')->where($data)->delete();
+ } else {
+ $data['createtime'] = TIMESTAMP;
+ $maxrank = table('users_operate_star')->getMaxRank();
+ $data['rank'] = intval($maxrank) + 1;
+ $result = table('users_operate_star')->fill($data)->save();
+ }
+ if ($result) {
+ return error(0, '');
+ } else {
+ return error(-1, '设置失败!');
+ }
+}
+
+function user_load_operate_star($limit_num = 100)
+{
+ global $_W;
+ $users_operate_star_table = table('users_operate_star');
+ $users_operate_star_table->searchWithLimit($limit_num);
+ $result = $users_operate_star_table->getAllByUid($_W['uid']);
+ return $result;
+}
+
+function user_account_delete($uniacid)
+{
+ if (empty($uniacid)) {
+ return false;
+ }
+ $mc_oauth_fans = pdo_getall('mc_oauth_fans', array('uniacid' => $uniacid), array('id', 'oauth_openid'));
+ if (!empty($mc_oauth_fans)) {
+ $ids = $openids = $uids = array();
+ foreach ($mc_oauth_fans as $key => $oauth_openid) {
+ $ids[] = $oauth_openid['id'];
+ if (empty($oauth_openid['oauth_openid'])) {
+ continue;
+ }
+ $openids[] = $oauth_openid['oauth_openid'];
+ }
+ if (!empty($ids)) {
+ pdo_delete('mc_oauth_fans', array('id' => $ids, 'uniacid' => $uniacid));
+ }
+ if (!empty($openids)) {
+ $mapping_fans = pdo_getall('mc_mapping_fans', array('uniacid' => $uniacid, 'openid' => $openids), array('uid'));
+ $uids = array_filter(array_column($mapping_fans, 'uid'));
+ pdo_delete('mc_mapping_fans', array('uniacid' => $uniacid, 'openid' => $openids));
+ }
+ if (!empty($uids)) {
+ pdo_delete('mc_members', array('uniacid' => $uniacid, 'uid' => $uids));
+ }
+ }
+ return true;
+}
\ No newline at end of file
diff --git a/framework/model/utility.mod.php b/framework/model/utility.mod.php
new file mode 100644
index 0000000..864d3b2
--- /dev/null
+++ b/framework/model/utility.mod.php
@@ -0,0 +1,64 @@
+where(array(
+ 'uniacid' => intval($uniacid),
+ 'receiver' => $receiver,
+ 'verifycode' => $code,
+ 'createtime >' => (TIMESTAMP - 1800)
+ ))->get();
+
+ return !empty($data);
+}
+
+
+function utility_image_rename($image_source_url, $image_destination_url) {
+ global $_W;
+ load()->func('file');
+ $image_source_url = str_replace(array("\0","%00","\r"),'',$image_source_url);
+ if (empty($image_source_url) || !parse_path($image_source_url)) {
+ return false;
+ }
+ if (!strexists($image_source_url, $_W['siteroot']) || $_W['setting']['remote']['type'] > 0) {
+ $img_local_path = file_remote_attach_fetch($image_source_url);
+ if (is_error($img_local_path)) {
+ return false;
+ }
+ $img_source_path = ATTACHMENT_ROOT . $img_local_path;
+ } else {
+ $img_local_path = substr($image_source_url, strlen($_W['siteroot']));
+ $img_path_params = explode('/', $img_local_path);
+ if ($img_path_params[0] != 'attachment') {
+ return false;
+ }
+ $img_source_path = IA_ROOT . '/' . $img_local_path;
+ }
+ if (!file_is_image($img_source_path)) {
+ return false;
+ }
+ $result = copy($img_source_path, $image_destination_url);
+ return $result;
+}
+
+
+function utility_smscode_verify($uniacid, $receiver, $verifycode = '') {
+ $table = table('uni_verifycode');
+ $verify_info = $table->getByReceiverVerifycode($uniacid, $receiver, $verifycode);
+
+ if (empty($verify_info)) {
+ $table->updateFailedCount($receiver);
+ return error(-1, '短信验证码不正确');
+ } else if ($verify_info['createtime'] + 120 < TIMESTAMP) {
+ return error(-2, '短信验证码已过期,请重新获取');
+ } else {
+ return error(0, '短信验证码正确');
+ }
+
+}
\ No newline at end of file
diff --git a/framework/table/Account/Account.php b/framework/table/Account/Account.php
new file mode 100644
index 0000000..fb491ff
--- /dev/null
+++ b/framework/table/Account/Account.php
@@ -0,0 +1,295 @@
+ '0',
+ 'hash' => '',
+ 'type' => '1',
+ 'isconnect' => '',
+ 'isdeleted' => '0',
+ 'endtime' => '0',
+ 'send_account_expire_status' => 0,
+ 'send_api_expire_status' => 0
+ );
+
+ public function getByUniacid($uniacid) {
+ return $this->where('uniacid', $uniacid)->get();
+ }
+
+ public function getUniAccountByAcid($acid) {
+ return $this->query
+ ->from($this->tableName, 'a')
+ ->leftjoin('uni_account', 'u')
+ ->on('a.uniacid', 'u.uniacid')
+ ->where('a.acid' , intval($acid))
+ ->get();
+ }
+
+ public function getUniAccountByUniacid($uniacid) {
+ return $this->query
+ ->from($this->tableName, 'a')
+ ->leftjoin('uni_account', 'u')
+ ->on('a.uniacid', 'u.uniacid')
+ ->where('a.uniacid' , intval($uniacid))
+ ->get();
+ }
+
+ public function getUserAccountInfo($uid, $uniacid, $account_type) {
+ $type_info = uni_account_type($account_type);
+ return $this->query->from('uni_account', 'a')
+ ->leftjoin($type_info['table_name'], 'w')
+ ->on(array('w.uniacid' => 'a.uniacid'))
+ ->leftjoin('uni_account_users', 'au')
+ ->on(array('a.uniacid' => 'au.uniacid'))
+ ->where(array('a.uniacid' => $uniacid))
+ ->where(array('au.uid' => $uid))
+ ->orderby('a.uniacid', 'asc')
+ ->getall('uniacid');
+ }
+
+
+ public function searchAccount($expire_type, $fields, $isdeleted = 1, $uid = 0) {
+ global $_W;
+ $uid = empty($uid) ? $_W['uid'] : $uid;
+ $this->query->from('uni_account', 'a')
+ ->select($fields)
+ ->leftjoin('account', 'b')
+ ->on(array('a.uniacid' => 'b.uniacid', 'a.default_acid' => 'b.acid'))
+ ->where('b.isdeleted !=', $isdeleted)
+ ->where('a.default_acid !=', '0')
+ ->where('b.type <>', array(9, 10))
+ ->leftjoin('uni_account_users', 'c')
+ ->on(array('a.uniacid' => 'c.uniacid'))
+ ->leftjoin('users', 'u')
+ ->on(array('u.uid' => 'c.uid'));
+
+ if (!user_is_founder($uid, true)) {
+ if (user_is_vice_founder($uid)) {
+ $users_uids = table('users_founder_own_users')->getFounderOwnUsersList($uid);
+ $users_uids = array_keys($users_uids);
+ $users_uids[] = $uid;
+ $this->query->where('c.uid', $users_uids)->where('c.role', array('clerk', 'operator', 'manager', 'owner', 'vice_founder'));
+ } else {
+ $this->query->where('c.uid', $uid)->where('c.role <>', 'clerk');
+ }
+ }
+ if ($expire_type == 'expire') {
+ $this->searchWithExprie();
+ } elseif ($expire_type == 'unexpire') {
+ $this->searchWithUnExprie();
+ }
+ return $this;
+ }
+
+ public function searchWithRole($role) {
+ global $_W;
+ return $this->query->where('c.role', $role)->where('c.uid', $_W['uid']);
+ }
+ public function searchWithExprie() {
+ $this->query->where(array(
+ 'b.endtime <' => TIMESTAMP,
+ 'b.endtime >' => USER_ENDTIME_GROUP_UNLIMIT_TYPE
+ ));
+ return $this;
+ }
+
+ public function searchWithUnExprie() {
+ $this->query->where(function ($query) {
+ $query->where(array('b.endtime' => 0))
+ ->whereor(array('b.endtime' => USER_ENDTIME_GROUP_UNLIMIT_TYPE))
+ ->whereor(array('b.endtime >' => TIMESTAMP));
+ });
+ return $this;
+ }
+
+ public function searchAccountList($expire = false, $isdeleted = 1, $fields = 'a.uniacid', $uid = 0) {
+ $this->searchAccount($expire, $fields, $isdeleted, $uid);
+ $this->query->groupby('a.uniacid');
+ $list = $this->query->getall('uniacid');
+ return $list;
+ }
+
+ public function searchAccounTotal($expire = false) {
+ $this->searchAccount($expire, 'count(*) as total, b.type');
+ $this->query->groupby('b.type');
+ $list = $this->query->getall();
+ return $list;
+ }
+
+ public function searchWithKeyword($title) {
+ global $_W;
+ if (empty($title)) {
+ return $this;
+ }
+ if ($title == 'admin' && $_W['isadmin']) {
+ $this->query->where('ISNULL(c.uid)', true);
+ } else {
+ if ($_W['isfounder']){
+ $user = table('uni_account_users')
+ ->searchWithUsers()
+ ->where('a.role', 'owner')
+ ->where('b.username', $title);
+ if (user_is_vice_founder($_W['uid'])) {
+ $uids = table('users_founder_own_users')->where('founder_uid', $_W['uid'])->getall('uid');
+ if (!empty($uid)) {
+ $user->where('a.uid', array_keys($uids));
+ }
+ }
+ $user = $user->get();
+ }
+ !empty($user) && user_is_founder($user['uid'], true) ? $user = array() : $user;
+ !empty($user) ? $this->query->where('CONCAT(a.name,u.username) LIKE', "%{$title}%")->where('c.role', 'owner') : $this->query->where('a.name LIKE', "%{$title}%");
+ }
+ return $this;
+ }
+
+ public function searchWithTitle($title) {
+ $this->query->where('a.name', $title);
+ return $this;
+ }
+
+ public function searchWithType($types = array()) {
+ $this->query->where(array('b.type' => $types));
+ return $this;
+ }
+
+ public function searchWithLetter($letter) {
+ if (!empty($letter) && strlen($letter) == 1) {
+ $this->query->where('a.title_initial', $letter);
+ }
+ return $this;
+ }
+
+ public function accountRankOrder() {
+ global $_W;
+ if (!$_W['isadmin']) {
+ $this->query->orderby('c.rank', 'desc');
+ } else {
+ $this->query->orderby('a.rank', 'desc');
+ }
+ return $this;
+ }
+
+ public function accountUniacidOrder($order = 'desc') {
+ $order = !empty($order) ? $order : 'desc';
+ $this->query->orderby('a.uniacid', $order);
+ return $this;
+ }
+
+ public function accountEndtimeOrder($order) {
+ $order = $order == 'endtime_asc' ? 'asc' : 'desc';
+ return $this->query->orderby('b.endtime', $order)
+ ->where('b.endtime >', 2);
+ }
+
+ public function accountInitialsOrder($order = 'asc') {
+ $order = !empty($order) ? $order : 'asc';
+ $this->query->orderby('a.title_initial', $order);
+ return $this;
+ }
+
+ public function searchWithViceFounder($vice_founder_id) {
+ $this->query
+ ->leftjoin('uni_account_users', 'c')
+ ->on(array('a.uniacid' => 'c.uniacid'))
+ ->where('c.role', 'vice_founder')
+ ->where('c.uid', $vice_founder_id);
+ return $this;
+ }
+
+
+
+ public function accountGroupModules($uniacid, $type = '') {
+ $packageids = $this->query->from('uni_account_group')->where('uniacid', $uniacid)->select('groupid')->getall('groupid');
+ $packageids = empty($packageids) ? array() : array_keys($packageids);
+ if (in_array('-1', $packageids)) {
+ $modules = $this->query->from('modules')->select('name')->getall('name');
+ return array_keys($modules);
+ }
+ $uni_modules = array();
+
+ $uni_groups = $this->query->from('uni_group')->where('id', $packageids)->getall();
+ $uni_account_extra_modules = table('uni_account_extra_modules')->where('uniacid', $uniacid)->getall();
+ $acount_modules = array_merge($uni_groups, $uni_account_extra_modules);
+ if (!empty($acount_modules)) {
+ if (empty($type)) {
+ $account = table('account')->getByUniacid($uniacid);
+ $type = $account['type'];
+ }
+ foreach ($acount_modules as $group) {
+ $group_module = (array)iunserializer($group['modules']);
+ if (empty($group_module)) {
+ continue;
+ }
+ switch ($type) {
+ case ACCOUNT_TYPE_OFFCIAL_NORMAL:
+ case ACCOUNT_TYPE_OFFCIAL_AUTH:
+ $uni_modules = is_array($group_module['modules']) ? array_merge($group_module['modules'], $uni_modules) : $uni_modules;
+ break;
+ case ACCOUNT_TYPE_APP_NORMAL:
+ case ACCOUNT_TYPE_APP_AUTH:
+ case ACCOUNT_TYPE_WXAPP_WORK:
+ $uni_modules = is_array($group_module['wxapp']) ? array_merge($group_module['wxapp'], $uni_modules) : $uni_modules;
+ break;
+ case ACCOUNT_TYPE_WEBAPP_NORMAL:
+ $uni_modules = is_array($group_module['webapp']) ? array_merge($group_module['webapp'], $uni_modules) : $uni_modules;
+ break;
+ case ACCOUNT_TYPE_PHONEAPP_NORMAL:
+ $uni_modules = is_array($group_module['phoneapp']) ? array_merge($group_module['phoneapp'], $uni_modules) : $uni_modules;
+ break;
+ case ACCOUNT_TYPE_ALIAPP_NORMAL:
+ $uni_modules = is_array($group_module['aliapp']) ? array_merge($group_module['aliapp'], $uni_modules) : $uni_modules;
+ break;
+ }
+ }
+ $uni_modules = array_unique($uni_modules);
+ }
+ return $uni_modules;
+ }
+
+
+ public function userOwnedAccount($uid = 0) {
+ global $_W;
+ $uid = intval($uid) > 0 ? intval($uid) : $_W['uid'];
+ if (!user_is_founder($uid, true)) {
+ $uniacid_list = table('uni_account_users')->getUsableAccountsByUid($uid);
+ if (empty($uniacid_list)) {
+ return array();
+ }
+ $this->query->where('u.uniacid', array_keys($uniacid_list));
+ }
+ return $this->query->from('uni_account', 'u')
+ ->leftjoin('account', 'a')
+ ->on(array('u.default_acid' => 'a.acid'))
+ ->where('a.isdeleted', 0)
+ ->orderby('a.uniacid', 'DESC')
+ ->getall('uniacid');
+ }
+
+ public function searchWithuniAccountUsers() {
+ return $this->query->from('account', 'a')
+ ->leftjoin('uni_account_users', 'b')
+ ->on(array('b.uniacid' => 'a.uniacid'));
+ }
+
+ public function searchWithUniAccount() {
+ return $this->query->from($this->tableName, 'a')
+ ->leftjoin('uni_account', 'b')
+ ->on('b.uniacid', 'a.uniacid');
+ }
+
+}
\ No newline at end of file
diff --git a/framework/table/Account/Wechats.php b/framework/table/Account/Wechats.php
new file mode 100644
index 0000000..dba26ff
--- /dev/null
+++ b/framework/table/Account/Wechats.php
@@ -0,0 +1,68 @@
+ '',
+ 'token' => '',
+ 'encodingaeskey' => '',
+ 'auth_refresh_token' => '',
+ 'level' => '0',
+ 'name' => '',
+ 'account' => '',
+ 'original' => '',
+ 'signature' => '',
+ 'country' => '',
+ 'province' => '',
+ 'city' => '',
+ 'username' => '',
+ 'password' => '',
+ 'lastupdate' => '0',
+ 'key' => '',
+ 'secret' => '',
+ 'styleid' => '1',
+ 'subscribeurl' => '',
+ 'createtime' => '',
+ );
+ public function getAccount($uniacid) {
+ return $this->query->where('uniacid', $uniacid)->get();
+ }
+ public function searchWithAccount() {
+ return $this->query->from($this->tableName, 't')
+ ->leftjoin('account', 'a')
+ ->on(array('t.uniacid' => 'a.uniacid'));
+ }
+
+ public function searchWithsearchWithAccountAndUniAccountUsers() {
+ return $this->query->from($this->tableName, 't')
+ ->leftjoin('account', 'a')
+ ->on(array('t.uniacid' => 'a.uniacid'))
+ ->leftjoin('uni_account_users', 'u')
+ ->on(array('u.uniacid' => 't.uniacid'));
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Basic/Reply.php b/framework/table/Basic/Reply.php
new file mode 100644
index 0000000..ea2dd51
--- /dev/null
+++ b/framework/table/Basic/Reply.php
@@ -0,0 +1,19 @@
+ '',
+ 'content' => ''
+ );
+}
\ No newline at end of file
diff --git a/framework/table/Core/Attachment.php b/framework/table/Core/Attachment.php
new file mode 100644
index 0000000..2796f6c
--- /dev/null
+++ b/framework/table/Core/Attachment.php
@@ -0,0 +1,66 @@
+ '',
+ 'uid' => '',
+ 'filename' => '',
+ 'attachment' => '',
+ 'type' => '',
+ 'createtime' => '',
+ 'module_upload_dir' => '',
+ 'group_id' => '0',
+ 'displayorder' => '',
+ );
+
+ public function deleteById($id) {
+ return $this->where('id', $id)->delete();
+ }
+
+ public function searchWithUniacid($uniacid) {
+ return $this->query->where('uniacid', $uniacid);
+ }
+
+ public function searchWithUid($uid) {
+ return $this->query->where('uid', $uid);
+ }
+
+ public function searchWithUploadDir($module_upload_dir) {
+ return $this->query->where(array('module_upload_dir' => $module_upload_dir));
+ }
+
+ public function searchWithType($type) {
+ return $this->query->where(array('type' => $type));
+ }
+
+ public function searchWithGroupId($groupid) {
+ return $this->query->where(array('group_id =' => $groupid));
+ }
+
+ public function searchWithTime($start_time, $end_time) {
+ return $this->query->where(array('createtime >=' => $start_time))->where(array('createtime <=' => $end_time));
+ }
+
+ public function SearchWithUserAndUniAccount() {
+ return $this->query->from($this->tableName, 'a')
+ ->leftjoin('users', 'b')
+ ->on('b.uid', 'a.uid')
+ ->leftjoin('uni_account', 'c')
+ ->on('a.uniacid','c.uniacid');
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Core/AttachmentGroup.php b/framework/table/Core/AttachmentGroup.php
new file mode 100644
index 0000000..1bb98a0
--- /dev/null
+++ b/framework/table/Core/AttachmentGroup.php
@@ -0,0 +1,32 @@
+ '0',
+ 'name' => '',
+ 'uniacid' => '0',
+ 'uid' => '0',
+ 'type' => '0',
+ );
+
+ public function searchWithUniacidOrUid($uniacid, $uid) {
+ if (empty($uniacid)) {
+ $this->query->where('uniacid', 0)->where('uid', $uid);
+ } else {
+ $this->query->where('uniacid', $uniacid);
+ }
+ return $this;
+ }
+
+}
\ No newline at end of file
diff --git a/framework/table/Core/ProfileFields.php b/framework/table/Core/ProfileFields.php
new file mode 100644
index 0000000..41c414f
--- /dev/null
+++ b/framework/table/Core/ProfileFields.php
@@ -0,0 +1,43 @@
+ '',
+ 'available' => 1,
+ 'title' => '',
+ 'description' => '',
+ 'displayorder' => 0,
+ 'required' => 0,
+ 'unchangeable' => 0,
+ 'showinregister' => 0,
+ 'field_length' => 0,
+ );
+
+ public function searchWithKeyword($keyword) {
+ $this->query->where('title LIKE', "%{$keyword}%");
+ return $this;
+ }
+
+ public function getFieldsList() {
+ return $this->query->orderby('displayorder', 'DESC')->getall();
+ }
+
+ public function getAvailableAndShowableFields() {
+ return $this->query->where('available', 1)->where('showinregister', 1)->orderby('displayorder', 'desc')->getall('field');
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Core/Settings.php b/framework/table/Core/Settings.php
new file mode 100644
index 0000000..43b7afd
--- /dev/null
+++ b/framework/table/Core/Settings.php
@@ -0,0 +1,16 @@
+ '',
+ 'value' => '',
+ );
+}
\ No newline at end of file
diff --git a/framework/table/Images/Reply.php b/framework/table/Images/Reply.php
new file mode 100644
index 0000000..9699e94
--- /dev/null
+++ b/framework/table/Images/Reply.php
@@ -0,0 +1,25 @@
+ '',
+ 'title' => '',
+ 'description' => '',
+ 'mediaid' => '',
+ 'createtime' => ''
+ );
+}
\ No newline at end of file
diff --git a/framework/table/Mc/CreditsRecord.php b/framework/table/Mc/CreditsRecord.php
new file mode 100644
index 0000000..e87da96
--- /dev/null
+++ b/framework/table/Mc/CreditsRecord.php
@@ -0,0 +1,57 @@
+ '0',
+ 'clerk_type' => '1',
+ 'createtime' => '',
+ 'credittype' => '',
+ 'module' => '',
+ 'num' => '0.00',
+ 'operator' => '',
+ 'real_uniacid' => '',
+ 'remark' => '',
+ 'store_id' => '0',
+ 'uid' => '',
+ 'uniacid' => '',
+ );
+
+ public function getCreditsRecordListByUidAndCredittype($uid, $credittype) {
+ return $this->query->from('mc_credits_record', 'r')
+ ->select('r.*, u.username as username')
+ ->leftjoin('users', 'u')
+ ->on(array('r.operator' => 'u.uid'))
+ ->where('r.uid', $uid)
+ ->where('r.credittype', $credittype)
+ ->orderby('r.id', 'desc')
+ ->getall();
+ }
+
+ public function searchWithUsers() {
+ return $this->query->from($this->tableName, 'r')
+ ->leftjoin('users', 'u')
+ ->on(array('r.operator' => 'u.uid'));
+ }
+
+ public function searchWithUniacid($uniacid) {
+ return $this->query->where('uniacid', $uniacid);
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Mc/FansTag.php b/framework/table/Mc/FansTag.php
new file mode 100644
index 0000000..040636e
--- /dev/null
+++ b/framework/table/Mc/FansTag.php
@@ -0,0 +1,58 @@
+ '',
+ 'fanid' => '',
+ 'openid' => '',
+ 'subscribe' => '0',
+ 'nickname' => '',
+ 'sex' => '0',
+ 'language' => '',
+ 'city' => '',
+ 'province' => '',
+ 'country' => '',
+ 'headimgurl' => '',
+ 'subscribe_time' => '',
+ 'unionid' => '',
+ 'remark' => '',
+ 'groupid' => '',
+ 'tagid_list' => '',
+ 'subscribe_scene' => '',
+ 'qr_scene' => '',
+ 'qr_scene_str' => '',
+
+ );
+
+ public function getByOpenid($openid) {
+ $result = $this->query->where('openid', $openid)->get();
+ return $result;
+ }
+
+}
\ No newline at end of file
diff --git a/framework/table/Mc/Groups.php b/framework/table/Mc/Groups.php
new file mode 100644
index 0000000..b81bb89
--- /dev/null
+++ b/framework/table/Mc/Groups.php
@@ -0,0 +1,20 @@
+ 0,
+ 'title' => '',
+ 'credit' => 0,
+ 'isdefault' => 0
+ );
+}
\ No newline at end of file
diff --git a/framework/table/Mc/MappingFans.php b/framework/table/Mc/MappingFans.php
new file mode 100644
index 0000000..4a6cfd1
--- /dev/null
+++ b/framework/table/Mc/MappingFans.php
@@ -0,0 +1,52 @@
+ '',
+ 'uniacid' => '0',
+ 'uid' => '0',
+ 'openid' => '',
+ 'nickname' => '',
+ 'groupid' => '',
+ 'salt' => '',
+ 'follow' => '1',
+ 'followtime' => '',
+ 'unfollowtime' => '',
+ 'tag' => '',
+ 'updatetime' => '0',
+ 'unionid' => '',
+ 'user_from' => '',
+ );
+
+ public function searchWithUniacid($uniacid) {
+ return $this->query->where('uniacid', $uniacid);
+ }
+
+ public function searchWithOpenid($openid) {
+ return $this->query->where('openid', $openid);
+ }
+
+ public function searchWithUnionid($unionid) {
+ return $this->query->where('unionid', $unionid);
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Mc/Members.php b/framework/table/Mc/Members.php
new file mode 100644
index 0000000..2453eb4
--- /dev/null
+++ b/framework/table/Mc/Members.php
@@ -0,0 +1,160 @@
+ '',
+ 'affectivestatus' => '',
+ 'alipay' => '',
+ 'avatar' => '',
+ 'bio' => '',
+ 'birthday' => '0',
+ 'birthmonth' => '0',
+ 'birthyear' => '0',
+ 'bloodtype' => '',
+ 'company' => '',
+ 'constellation' => '',
+ 'createtime' => '',
+ 'credit1' => '0.00',
+ 'credit2' => '0.00',
+ 'credit3' => '',
+ 'credit4' => '0.00',
+ 'credit5' => '0.00',
+ 'credit6' => '0.00',
+ 'education' => '',
+ 'email' => '',
+ 'gender' => '0',
+ 'grade' => '',
+ 'graduateschool' => '',
+ 'groupid' => '0',
+ 'height' => '',
+ 'idcard' => '',
+ 'interest' => '',
+ 'lookingfor' => '',
+ 'mobile' => '',
+ 'msn' => '',
+ 'nationality' => '',
+ 'nickname' => '',
+ 'occupation' => '',
+ 'password' => '',
+ 'pay_password' => '',
+ 'position' => '',
+ 'qq' => '',
+ 'realname' => '',
+ 'residecity' => '',
+ 'residedist' => '',
+ 'resideprovince' => '',
+ 'revenue' => '',
+ 'salt' => '',
+ 'site' => '',
+ 'studentid' => '',
+ 'taobao' => '',
+ 'telephone' => '',
+ 'uniacid' => '',
+ 'user_from' => '',
+ 'vip' => '0',
+ 'weight' => '',
+ 'zipcode' => '',
+ 'zodiac' => '',
+ );
+
+ public function searchWithUniacid($uniacid) {
+ return $this->query->where('uniacid', $uniacid);
+ }
+
+ public function searchWithEmail($email) {
+ return $this->query->where('email', $email);
+ }
+
+ public function searchWithMobile($mobile) {
+ return $this->query->where('mobile', $mobile);
+ }
+
+ public function searchWithoutUid($uid) {
+ return $this->query->where('uid <>', $uid);
+ }
+
+ public function searchCreditsRecordUid($uid) {
+ $this->query->where('r.uid', $uid);
+ return $this;
+ }
+
+ public function searchCreditsRecordType($type) {
+ $this->query->where('r.credittype', $type);
+ return $this;
+ }
+
+ public function searchWithMobileOrEmail($mobile_or_email) {
+ $this->query->where('mobile', $mobile_or_email)->whereor('email', $mobile_or_email);
+ return $this;
+ }
+ public function searchWithMappingFans() {
+ return $this->query->from('mc_members', 'a')
+ ->leftjoin('mc_mapping_fans', 'b')
+ ->on(array('a.uid' => 'b.uid'));
+ }
+
+ public function searchWithAccount() {
+ return $this->query->from('mc_members', 'm')
+ ->leftjoin('account', 'a')
+ ->on(array('m.uniacid' => 'a.uniacid'));
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Mc/OauthFans.php b/framework/table/Mc/OauthFans.php
new file mode 100644
index 0000000..2f53bc8
--- /dev/null
+++ b/framework/table/Mc/OauthFans.php
@@ -0,0 +1,28 @@
+ '',
+ 'uniacid' => '',
+ 'uid' => '',
+ 'openid' => '',
+ );
+
+ public function searchWithoAuthopenid($oauth_openid) {
+ return $this->query->where('oauth_openid', $oauth_openid);
+ }
+
+ public function searchWithUniacid($uniacid) {
+ return $this->query->where('uniacid', $uniacid);
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Modules/Modules.php b/framework/table/Modules/Modules.php
new file mode 100644
index 0000000..66b6768
--- /dev/null
+++ b/framework/table/Modules/Modules.php
@@ -0,0 +1,197 @@
+ '',
+ 'type' => '',
+ 'title' => '',
+ 'title_initial' => '',
+ 'version' => '',
+ 'ability' => '',
+ 'description' => '',
+ 'author' => '',
+ 'url' => '',
+ 'settings' => '0',
+ 'subscribes' => '',
+ 'handles' => '',
+ 'isrulefields' => '0',
+ 'issystem' => '0',
+ 'target' => '0',
+ 'iscard' => '0',
+ 'permissions' => '',
+ 'wxapp_support' => '1',
+ 'account_support' => '1',
+ 'welcome_support' => '1',
+ 'webapp_support' => '1',
+ 'oauth_type' => '1',
+ 'phoneapp_support' => '1',
+ 'xzapp_support' => '1',
+ 'aliapp_support' => '1',
+ 'logo' => '',
+ 'baiduapp_support' => '1',
+ 'toutiaoapp_support' => '1',
+ 'cloud_record' => 0,
+ 'sectinos' => 0,
+ 'application_type' => 1,
+ );
+
+ public function bindings() {
+ return $this->hasMany('modules_bindings', 'module', 'name');
+ }
+
+ public function getByName($module_name) {
+ $result = $this->query->where('name', $module_name)->get();
+ if (!empty($result['subscribes'])) {
+ $result['subscribes'] = iunserializer($result['subscribes']);
+ }
+ if (!empty($result['handles'])) {
+ $result['handles'] = iunserializer($result['handles']);
+ }
+ return $result;
+ }
+ protected function templatesMidToId($result) {
+ if (empty($result) || !is_array($result)) {
+ return array();
+ }
+ foreach ($result as $key => $template) {
+ $result[$key] = $this->templateMidToId($template);
+ }
+ return $result;
+ }
+ protected function templateMidToId($result) {
+ global $_W;
+ if (empty($result) || !is_array($result)) {
+ return array();
+ }
+ $result['id'] = $result['mid'];
+ if (file_exists('../app/themes/'.$result['name'].'/preview.jpg')) {
+ $result['logo'] = $_W['siteroot'].'app/themes/'.$result['name'].'/preview.jpg';
+ } else {
+ $result['logo'] = $_W['siteroot'].'web/resource/images/nopic-203.png';
+ }
+ return $result;
+ }
+ public function searchTemplateWithName($module_name) {
+ return $this->query->where('name', $module_name);
+ }
+ public function getAllTemplates($keyfields = '') {
+ $fields = array('mid', 'name', 'version', 'title', 'description', 'type', 'sections');
+ $result = $this->query->select($fields)->where(array('application_type' => APPLICATION_TYPE_TEMPLATES, 'account_support' => MODULE_SUPPORT_ACCOUNT))->orderby('mid', 'DESC')->getall($keyfields);
+ return $this->templatesMidToId($result);
+ }
+
+ public function getTemplateByName($module_name) {
+ $result = $this->query->select($this->templateFields)->where('name', $module_name)->where('application_type', APPLICATION_TYPE_TEMPLATES)->get();
+ return $this->templateMidToId($result);
+ }
+ public function getTemplateByNames($module_names, $keyfields = '') {
+ $result = $this->query->select($this->templateFields)->where('name', $module_names)->where('application_type', APPLICATION_TYPE_TEMPLATES)->getall($keyfields);
+ return $this->templatesMidToId($result);
+ }
+
+ public function getTemplateById($id) {
+ $result = $this->query->select($this->templateFields)->where('mid', $id)->where('application_type', APPLICATION_TYPE_TEMPLATES)->get();
+ return $this->templateMidToId($result);
+ }
+
+ public function getAllTemplateByIds($ids, $keyfields = '') {
+ $result = $this->query->select($this->templateFields)->where('mid', $ids)->where('application_type', APPLICATION_TYPE_TEMPLATES)->orderby('mid', 'DESC')->getall($keyfields);
+ return $this->templatesMidToId($result);
+ }
+
+ public function getByNameList($modulename_list, $get_system = false) {
+ $this->query->whereor('name', $modulename_list)->orderby('mid', 'desc');
+ if (!empty($get_system)) {
+ $this->whereor('issystem', 1);
+ }
+ return $this->query->getall('name');
+ }
+
+ public function deleteByName($module_name) {
+ return $this->query->where('name', $module_name)->delete();
+ }
+
+ public function getByHasSubscribes() {
+ return $this->query->select('name', 'subscribes')->where('subscribes !=', '')->getall();
+ }
+
+ public function getSupportWxappList() {
+ return $this->query->where('wxapp_support', MODULE_SUPPORT_WXAPP)->getall('mid');
+ }
+
+ public function searchWithType($type, $method = '=') {
+ if ($method == '=') {
+ $this->query->where('type', $type);
+ } else {
+ $this->query->where('type <>', $type);
+ }
+ return $this;
+ }
+
+ public function getNonRecycleModules() {
+ load()->model('module');
+ $modules = $this->where('issystem' , 0)->orderby('mid', 'DESC')->getall('name');
+ if (empty($modules)) {
+ return array();
+ }
+ foreach ($modules as &$module) {
+ $module_info = module_fetch($module['name']);
+ if (empty($module_info)) {
+ unset($module);
+ }
+ if (!empty($module_info['recycle_info'])) {
+ foreach (module_support_type() as $support => $value) {
+ if ($module_info['recycle_info'][$support] > 0 && $module_info[$support] == $value['support']) {
+ $module[$support] = $value['not_support'];
+ }
+ }
+ }
+ }
+ return $modules;
+ }
+
+ public function getInstalled() {
+ load()->model('module');
+ $fields = array_keys(module_support_type());
+ $fields = array_merge(array('name', 'version', 'cloud_record'), $fields);
+ return $this->query->select($fields)->where(array('issystem' => '0'))->getall('name');
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Uni/Account.php b/framework/table/Uni/Account.php
new file mode 100644
index 0000000..e5e3737
--- /dev/null
+++ b/framework/table/Uni/Account.php
@@ -0,0 +1,37 @@
+ '0',
+ 'default_acid' => '0',
+ 'name' => '',
+ 'description' => '',
+ 'rank' => '0',
+ 'createtime' => '',
+ 'title_initial' => '',
+ 'create_uid' => '0',
+ 'logo' => '',
+ 'qrcode' => ''
+ );
+ public function searchWithAccount() {
+ return $this->query->from($this->tableName, 'a')
+ ->leftjoin('account', 'b')
+ ->on('a.uniacid', 'b.uniacid');
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Uni/AccountMenus.php b/framework/table/Uni/AccountMenus.php
new file mode 100644
index 0000000..1b3bbb2
--- /dev/null
+++ b/framework/table/Uni/AccountMenus.php
@@ -0,0 +1,59 @@
+ '0',
+ 'menuid' => '0',
+ 'type' => '1',
+ 'title' => '',
+ 'sex' => '0',
+ 'group_id' => '-1',
+ 'client_platform_type' => '0',
+ 'area' => '',
+ 'data' => '',
+ 'status' => '0',
+ 'createtime' => '0',
+ 'isdeleted' => '0',
+ );
+
+ public function searchWithTypeAndUniacid($type = '', $uniacid = 0) {
+ if (!empty($type)) {
+ $this->where('type', $type);
+ }
+ if ($uniacid > 0) {
+ $this->where('uniacid', intval($uniacid));
+ }
+ return $this;
+ }
+
+ public function getByType($type = '') {
+ global $_W;
+ return $this->searchWithTypeAndUniacid($type, $_W['uniacid'])->get();
+ }
+
+ public function getAllByType($type = '') {
+ global $_W;
+ return $this->searchWithTypeAndUniacid($type, $_W['uniacid'])->getall('id');
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Uni/AccountModules.php b/framework/table/Uni/AccountModules.php
new file mode 100644
index 0000000..55cebbf
--- /dev/null
+++ b/framework/table/Uni/AccountModules.php
@@ -0,0 +1,32 @@
+ '',
+ 'module' => '',
+ 'enabled' => 0,
+ 'shortcut' => 0,
+ 'displayorder' => 0,
+ 'settings' => '',
+ );
+
+ public function getByUniacidAndModule($module_name, $uniacid) {
+ $result = $this->query->where('module', $module_name)->where('uniacid', $uniacid)->get();
+ if (!empty($result)) {
+ $result['settings'] = iunserializer($result['settings']);
+ }
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Uni/AccountUsers.php b/framework/table/Uni/AccountUsers.php
new file mode 100644
index 0000000..40ba8de
--- /dev/null
+++ b/framework/table/Uni/AccountUsers.php
@@ -0,0 +1,68 @@
+ '',
+ 'uid' => '',
+ 'role' => '',
+ 'rank' => '0',
+ 'createtime' => '',
+ );
+
+ public function searchWithUserRole($role) {
+ return $this->query->where('role', $role);
+ }
+
+ public function getUsableAccountsByUid($uid) {
+ return $this->query->where('uid', $uid)->where('role !=', ACCOUNT_MANAGE_NAME_CLERK)->getall('uniacid');
+ }
+
+ public function getOwnedAccountsByUid($uid) {
+ return $this->query->where('uid', $uid)->where('role', ACCOUNT_MANAGE_NAME_OWNER)->getall('uniacid');
+ }
+
+ public function searchWithRole($role) {
+ return $this->query->where('u.role', $role);
+ }
+
+ public function getCommonUserOwnAccountUniacids($uid) {
+ return $this->query
+ ->from('uni_account_users', 'u')
+ ->select('u.uniacid, a.type')
+ ->innerjoin('account', 'a')
+ ->on(array('u.uniacid' => 'a.uniacid'))
+ ->where('u.uid', $uid)
+ ->getall('uniacid');
+ }
+
+ public function getAllUserRole($uid) {
+ return $this->query->where('uid', $uid)->getall('role');
+ }
+
+ public function getUserRoleByUniacid($uid, $uniacid) {
+ $info = $this->query->where(array('uid' => $uid, 'uniacid' => $uniacid))->get();
+ return $info['role'];
+ }
+
+ public function getUidByUniacidAndRole($uniacid, $role) {
+ $data = $this->where('uniacid', $uniacid)->where('role', $role)->get();
+ return empty($data['uid']) ? 0 : $data['uid'];
+ }
+
+ public function searchWithUsers() {
+ return $this->query->from($this->tableName, 'a')
+ ->leftjoin('users', 'b')
+ ->on('a.uid', 'b.uid');
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Uni/Modules.php b/framework/table/Uni/Modules.php
new file mode 100644
index 0000000..273f536
--- /dev/null
+++ b/framework/table/Uni/Modules.php
@@ -0,0 +1,85 @@
+ '',
+ 'module_name' => '',
+ );
+
+ public function getAllByModuleName($module_name) {
+ return $this->query->select('uniacid')->where('module_name', $module_name)->getall('uniacid');
+ }
+ public function getallByUniacid($uniacid) {
+ return $this->query->where('uniacid', $uniacid)->getall();
+ }
+
+ public function searchLikeModuleTitle($module_title) {
+ return $this->query->where('m.title LIKE', "%{$module_title}%");
+ }
+
+ public function searchWithModuleLetter($module_letter) {
+ return $this->query->where('m.title_initial', $module_letter);
+ }
+
+ public function searchWithModuleName($module_name) {
+ $this->query->where('u.module_name', $module_name);
+ }
+
+ public function searchGroupbyModuleName() {
+ return $this->query->groupby('u.module_name');
+ }
+
+ public function getModulesByUid($uid, $uniacid = 0) {
+ global $_W;
+ if (empty($uid)) {
+ $uid = $_W['uid'];
+ }
+
+ if (!empty($uniacid)) {
+ $this->where('u.uniacid', $uniacid);
+ } else {
+ $this->where('u.uniacid <>', 0);
+ }
+
+ $select_fields = "
+ u.uniacid,
+ u.module_name
+ ";
+
+ if (!user_is_founder($uid) && $_W['highest_role'] != ACCOUNT_MANAGE_NAME_CLERK || user_is_vice_founder($uid)) {
+ $select_fields .= ", uau.role";
+ $this->where('uau.uid', $uid);
+ $this->query->from('uni_account_users', 'uau')
+ ->leftjoin('uni_modules', 'u')
+ ->on(array('uau.uniacid' => 'u.uniacid'));
+ } elseif ($_W['highest_role'] == ACCOUNT_MANAGE_NAME_CLERK) {
+ $select_fields .= ", up.uniacid as permission_uniacid";
+ $this->where('up.uid', $uid);
+ $this->query->from('users_permission', 'up')
+ ->leftjoin('uni_modules', 'u')
+ ->on(array('up.type' => 'u.module_name', 'up.uniacid' => 'u.uniacid'));
+ } else {
+ $this->query->from('uni_modules', 'u');
+ }
+
+ $modules = $this->query
+ ->select($select_fields)
+ ->getall();
+
+ $total = $this->getLastQueryTotal();
+ return array('modules' => $modules, 'total' => $total);
+ }
+
+ public function deleteUniModules($module_name, $uniacid) {
+ $this->query->where('module_name', $module_name)->where('uniacid', $uniacid)->delete();
+ }
+
+}
\ No newline at end of file
diff --git a/framework/table/Uni/Settings.php b/framework/table/Uni/Settings.php
new file mode 100644
index 0000000..0d85135
--- /dev/null
+++ b/framework/table/Uni/Settings.php
@@ -0,0 +1,80 @@
+ 0,
+ 'passport' => '',
+ 'oauth' => '',
+ 'jsauth_acid' => 0,
+ 'notify' => '',
+ 'creditnames' => '',
+ 'creditbehaviors' => '',
+ 'welcome' => '',
+ 'default' => '',
+ 'default_message' => '',
+ 'shortcuts' => '',
+ 'payment' => '',
+ 'stat' => '',
+ 'default_site' => 0,
+ 'sync' => '',
+ 'recharge' => '',
+ 'tplnotice' => '',
+ 'grouplevel' => 1,
+ 'mcplugin' => '',
+ 'exchange_enable' => 0,
+ 'coupon_type' => 1,
+ 'statistics' => '',
+ 'bind_domain' => '',
+ 'comment_status' => 0,
+ 'reply_setting' => 0,
+ 'default_module' => '',
+ 'attachment_limit' => 0,
+ 'attachment_size' => '',
+ 'sync_member' => 0,
+ 'remote' => ''
+ );
+ public function searchWirhUniAccountAndAccount(){
+ return $this->query->from($this->tableName, 'a')
+ ->leftjoin('uni_account', 'b')
+ ->on('a.uniacid', 'b.uniacid')
+ ->leftjoin('account', 'c')
+ ->on('a.uniacid', 'c.uniacid');
+ }
+
+}
\ No newline at end of file
diff --git a/framework/table/Users/Bind.php b/framework/table/Users/Bind.php
new file mode 100644
index 0000000..98419a3
--- /dev/null
+++ b/framework/table/Users/Bind.php
@@ -0,0 +1,38 @@
+ '',
+ 'bind_sign' => '',
+ 'third_type' => '0',
+ 'third_nickname' => '',
+ );
+
+ public function getByTypeAndUid($type, $uid) {
+ return $this->query->where('third_type', $type)->where('uid', $uid)->get();
+ }
+
+ public function getByTypeAndBindsign($type, $bind_sign) {
+ return $this->query->where('third_type', $type)->where('bind_sign', $bind_sign)->get();
+ }
+
+ public function getAllByUid($uid) {
+ return $this->query->where('uid', $uid)->getall('bind_sign');
+ }
+
+ public function searchWithUsers() {
+ return $this->query->from($this->tableName, 'b')
+ ->leftjoin('users', 'u')
+ ->on(array('b.uid' => 'u.uid'));
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Users/Permission.php b/framework/table/Users/Permission.php
new file mode 100644
index 0000000..81fd91f
--- /dev/null
+++ b/framework/table/Users/Permission.php
@@ -0,0 +1,98 @@
+ '',
+ 'uid' => '',
+ 'type' => '',
+ 'permission' => '',
+ 'url' => '',
+ );
+
+ public $notModuleTypes = array(
+ PERMISSION_ACCOUNT,
+ PERMISSION_WXAPP,
+ PERMISSION_WEBAPP,
+ PERMISSION_PHONEAPP,
+ PERMISSION_ALIAPP,
+ PERMISSION_BAIDUAPP,
+ PERMISSION_TOUTIAOAPP,
+ PERMISSION_SYSTEM,
+ PERMISSION_MODULES
+ );
+
+ public function getUserPermissionByType($uid, $uniacid, $type = '') {
+ $this->query->where('uid', $uid)->where('uniacid', $uniacid);
+ if (!empty($type)) {
+ $this->query->where('type', $type);
+ }
+ $result = $this->query->get();
+ if (!empty($result['permission'])) {
+ $result['permission'] = explode('|', $result['permission']);
+ }
+ return $result;
+ }
+
+ public function getAllUserPermission($uid, $uniacid) {
+ return $this->query->where('uid', $uid)
+ ->where('uniacid', $uniacid)->getall('type');
+ }
+ public function getAllUserModulePermission($uid, $uniacid = 0) {
+ if (!empty($uniacid)) {
+ $this->query->where('uniacid', $uniacid);
+ }
+ return $this->query->where('uid', $uid)
+ ->where('type !=', array(PERMISSION_ACCOUNT, PERMISSION_WXAPP, PERMISSION_WEBAPP, PERMISSION_PHONEAPP, PERMISSION_ALIAPP, PERMISSION_BAIDUAPP, PERMISSION_TOUTIAOAPP, PERMISSION_SYSTEM))->getall('type');
+ }
+
+ public function getClerkPermission($module) {
+ global $_W;
+ return $this->query->from('users_permission', 'p')->leftjoin('uni_account_users', 'u')->on(array('u.uid' => 'p.uid', 'u.uniacid' => 'p.uniacid'))->where('u.role', 'clerk')->where('p.type', $module)->where('u.uniacid', $_W['uniacid'])->getall('uid');
+ }
+
+ public function getClerkPermissionList($uniacid = 0, $uid = 0, $username = '') {
+ $this->query->from('users_permission', 'p')
+ ->select('p.*')
+ ->leftjoin('uni_account_users', 'u')
+ ->on(array('u.uid' => 'p.uid', 'u.uniacid' => 'p.uniacid'))
+ ->where('u.role', 'clerk');
+
+ if (!empty($uniacid)) {
+ $this->query->where('u.uniacid', $uniacid);
+ }
+ if (!empty($uid)) {
+ $this->query->where('u.uid', $uid);
+ }
+ if (!empty($username)) {
+ $this->query->leftjoin('users', 's')
+ ->on(array('s.uid' => 'p.uid'))
+ ->where('s.username like', "%$username%");
+ }
+ if (empty($module)) {
+ $this->query->where('p.type !=', $this->notModuleTypes);
+ } else {
+ $this->query->where('p.type', $module);
+ }
+ return $this->query->getall();
+ }
+
+ public function searchWithUniAccountUsers() {
+ return $this->query->from($this->tableName, 'p')
+ ->leftjoin('uni_account_users', 'u')
+ ->on(array(
+ 'p.uid' => 'u.uid',
+ 'p.uniacid' => 'u.uniacid'
+ ));
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Users/Profile.php b/framework/table/Users/Profile.php
new file mode 100644
index 0000000..810598c
--- /dev/null
+++ b/framework/table/Users/Profile.php
@@ -0,0 +1,116 @@
+ '',
+ 'createtime' => '',
+ 'edittime' => '',
+ 'realname' => '',
+ 'nickname' => '',
+ 'avatar' => '',
+ 'qq' => '',
+ 'mobile' => '',
+ 'fakeid' => '',
+ 'vip' => '0',
+ 'gender' => '0',
+ 'birthyear' => '0',
+ 'birthmonth' => '0',
+ 'birthday' => '0',
+ 'constellation' => '',
+ 'zodiac' => '',
+ 'telephone' => '',
+ 'idcard' => '',
+ 'studentid' => '',
+ 'grade' => '',
+ 'address' => '',
+ 'zipcode' => '',
+ 'nationality' => '',
+ 'resideprovince' => '',
+ 'residecity' => '',
+ 'residedist' => '',
+ 'graduateschool' => '',
+ 'company' => '',
+ 'education' => '',
+ 'occupation' => '',
+ 'position' => '',
+ 'revenue' => '',
+ 'affectivestatus' => '',
+ 'lookingfor' => '',
+ 'bloodtype' => '',
+ 'height' => '',
+ 'weight' => '',
+ 'alipay' => '',
+ 'msn' => '',
+ 'email' => '',
+ 'taobao' => '',
+ 'site' => '',
+ 'bio' => '',
+ 'interest' => '',
+ 'workerid' => '',
+ 'send_expire_status' => '0',
+ 'is_send_mobile_status' => '',
+ 'location' => '',
+ );
+
+ public function getByUid($uid) {
+ return $this->query->where('uid', $uid)->get();
+ }
+
+ public function getByMobile($mobile) {
+ return $this->query->where('mobile', $mobile)->get();
+ }
+}
\ No newline at end of file
diff --git a/framework/table/Users/Users.php b/framework/table/Users/Users.php
new file mode 100644
index 0000000..2f25ef8
--- /dev/null
+++ b/framework/table/Users/Users.php
@@ -0,0 +1,174 @@
+ '0',
+ 'groupid' => '0',
+ 'username' => '',
+ 'password' => '',
+ 'salt' => '',
+ 'type' => '1',
+ 'status' => '2',
+ 'joindate' => '0',
+ 'joinip' => '',
+ 'lastvisit' => '0',
+ 'lastip' => '',
+ 'remark' => '',
+ 'starttime' => '0',
+ 'endtime' => '0',
+ 'founder_groupid' => '0',
+ 'register_type' => '0',
+ 'openid' => '0',
+ 'welcome_link' => '',
+ 'notice_setting' => '',
+ );
+
+ public function getNoticeSettingByUid($uid) {
+ $notice_setting = iunserializer($this->where('uid', $uid)->getcolumn('notice_setting'));
+ if (!is_array($notice_setting)) {
+ $notice_setting = array();
+ }
+ return $notice_setting;
+ }
+
+ public function getUsersList($join_profile = true) {
+ $this->query->from('users', 'u');
+
+ $select = 'u.uid, u.owner_uid, u.groupid, u.username, u.type, u.status, u.joindate, u.joinip, u.lastvisit,
+ u.lastip, u.remark, u.starttime, u.endtime, u.founder_groupid,u.register_type, u.openid, u.welcome_link';
+
+ if ($join_profile) {
+ $select .= ',p.avatar as avatar, p.mobile as mobile, p.uid as puid, p.mobile as mobile';
+ $this->query->leftjoin('users_profile', 'p')->on(array('u.uid' => 'p.uid'));
+ }
+ return $this->query->select($select)->orderby('u.uid', 'DESC')->getall('uid');
+ }
+
+ public function searchFounderOwnUsers($founder_uid) {
+ $this->query
+ ->innerjoin('users_founder_own_users', 'f')
+ ->on(array('u.uid' => 'f.uid'))
+ ->where('f.founder_uid', $founder_uid);
+ return $this;
+ }
+
+ public function searchWithViceFounder() {
+ global $_W;
+ if (user_is_vice_founder()) {
+ $this->query->where('u.owner_uid', $_W['uid']);
+ }
+ return $this;
+ }
+
+ public function searchWithStatus($status) {
+ $this->query->where('u.status', $status);
+ return $this;
+ }
+
+ public function searchWithType($type) {
+ $this->query->where('u.type', $type);
+ return $this;
+ }
+
+ public function searchWithFounder($founder_groupids) {
+ $this->query->where('u.founder_groupid', $founder_groupids);
+ return $this;
+ }
+
+ public function searchWithoutFounder()
+ {
+ return $this->query->where('u.founder_groupid !=', ACCOUNT_MANAGE_GROUP_FOUNDER);
+ }
+
+ public function searchWithTimelimitStatus($status) {
+ if ($status == 1) {
+ $this->where(function ($query) {
+ $query->where('u.endtime', 0)
+ ->whereor('u.endtime', USER_ENDTIME_GROUP_UNLIMIT_TYPE)
+ ->whereor('u.endtime >', TIMESTAMP);
+ });
+ } elseif ($status == 2) {
+ $this->where(function ($query) {
+ $query->where('u.endtime >', USER_ENDTIME_GROUP_UNLIMIT_TYPE)
+ ->where('u.endtime <=', TIMESTAMP)
+ ->whereor('u.endtime', USER_ENDTIME_GROUP_DELETE_TYPE);
+ });
+
+ }
+ return $this;
+ }
+
+ public function searchWithEndtime($day) {
+ $this->query->where('u.endtime >', USER_ENDTIME_GROUP_UNLIMIT_TYPE)->where('u.endtime <', TIMESTAMP + 86400 * $day);
+ return $this;
+ }
+
+ public function searchWithMobile() {
+ $this->query->where('p.mobile !=', '');
+ return $this;
+ }
+
+ public function searchWithGroupId($group_id) {
+ $this->query->where('u.groupid', $group_id);
+ return $this;
+ }
+
+ public function searchWithSendStatus() {
+ $this->query->where('p.send_expire_status', 0);
+ return $this;
+ }
+
+ public function searchWithNameOrMobile($search, $join_profile = true, $uid_in = array()) {
+ if ($join_profile) {
+ $this->query->where(function ($query) use ($search) {
+ $query->where('u.username LIKE', "%{$search}%")->whereor('p.mobile LIKE', "%{$search}%");
+ });
+ } else {
+ $this->query->where('u.username LIKE', "%{$search}%")->whereor('u.uid', $uid_in);
+ }
+ return $this;
+ }
+
+ public function searchWithOwnerUid($owner_uid) {
+ $this->query->where('u.owner_uid', $owner_uid);
+ return $this;
+ }
+
+ public function userOrderBy($field = 'uid', $order = 'desc') {
+ $field = !empty($field) ? $field : 'joindate';
+ $order = !empty($order) ? $order : 'desc';
+ $this->query->orderby($field, $order);
+ return $this;
+ }
+
+ public function searchWithUsersProfile() {
+ return $this->query->from($this->tableName, 'u')
+ ->leftjoin('users_profile', 'p')
+ ->on(array('u.uid' => 'p.uid'));
+ }
+}
\ No newline at end of file
diff --git a/framework/version.inc.php b/framework/version.inc.php
new file mode 100644
index 0000000..d6b7187
--- /dev/null
+++ b/framework/version.inc.php
@@ -0,0 +1,6 @@
+