begin of thinksaas 3.68

Signed-off-by: kevin <kevin@lmve.net>
This commit is contained in:
2023-06-22 13:33:25 +08:00
commit 963ec1b2ea
2746 changed files with 331806 additions and 0 deletions
+227
View File
@@ -0,0 +1,227 @@
<?php
//生成图像缩略图和生成验证码
class Image {
//生成图像验证码
static public function buildImageVerify($width = 48, $height = 22, $randval = NULL, $verifyName = 'verify') {
if (!isset($_SESSION)) {
session_start();
//如果没有开启,session,则开启session
}
$randval = empty($randval) ? ("" . rand(1000, 9999)) : $randval;
$_SESSION[$verifyName] = $randval;
$length = 4;
$width = ($length * 10 + 10) > $width ? $length * 10 + 10 : $width;
$im = imagecreate($width, $height);
$r = array(225, 255, 255, 223);
$g = array(225, 236, 237, 255);
$b = array(225, 236, 166, 125);
$key = mt_rand(0, 3);
$backColor = imagecolorallocate($im, $r[$key], $g[$key], $b[$key]);
//背景色(随机)
$borderColor = imagecolorallocate($im, 100, 100, 100);
//边框色
$pointColor = imagecolorallocate($im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
//点颜色
@imagefilledrectangle($im, 0, 0, $width - 1, $height - 1, $backColor);
@imagerectangle($im, 0, 0, $width - 1, $height - 1, $borderColor);
$stringColor = imagecolorallocate($im, mt_rand(0, 200), mt_rand(0, 120), mt_rand(0, 120));
// 干扰
for ($i = 0; $i < 10; $i++) {
$fontcolor = imagecolorallocate($im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imagearc($im, mt_rand(-10, $width), mt_rand(-10, $height), mt_rand(30, 300), mt_rand(20, 200), 55, 44, $fontcolor);
}
for ($i = 0; $i < 25; $i++) {
$fontcolor = imagecolorallocate($im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imagesetpixel($im, mt_rand(0, $width), mt_rand(0, $height), $pointColor);
}
for ($i = 0; $i < $length; $i++) {
imagestring($im, 5, $i * 10 + 5, mt_rand(1, 8), $randval[$i], $stringColor);
}
self::output($im, 'png');
}
//生成缩略图
static public function thumb($image, $thumbname, $domain = 'public', $maxWidth = 200, $maxHeight = 50, $interlace = true) {
// 获取原图信息
$info = self::getImageInfo($image);
if ($info !== false) {
$srcWidth = $info['width'];
$srcHeight = $info['height'];
$type = strtolower($info['type']);
$interlace = $interlace ? 1 : 0;
unset($info);
$scale = min($maxWidth / $srcWidth, $maxHeight / $srcHeight);
// 计算缩放比例
if ($scale >= 1) {// 超过原图大小不再缩略
$width = $srcWidth;
$height = $srcHeight;
} else {// 缩略图尺寸
$width = (int)($srcWidth * $scale);
$height = (int)($srcHeight * $scale);
}
// 载入原图
$createFun = 'ImageCreateFrom' . ($type == 'jpg' ? 'jpeg' : $type);
$srcImg = $createFun($image);
//创建缩略图
if ($type != 'gif' && function_exists('imagecreatetruecolor')) {
$thumbImg = imagecreatetruecolor($width, $height);
} else {
$thumbImg = imagecreate($width, $height);
}
// 复制图片
if (function_exists("ImageCopyResampled")) {
imagecopyresampled($thumbImg, $srcImg, 0, 0, 0, 0, $width, $height, $srcWidth, $srcHeight);
} else {
imagecopyresized($thumbImg, $srcImg, 0, 0, 0, 0, $width, $height, $srcWidth, $srcHeight);
}
if ('gif' == $type || 'png' == $type) {
$background_color = imagecolorallocate($thumbImg, 0, 255, 0);
// 指派一个绿色
imagecolortransparent($thumbImg, $background_color);
// 设置为透明色,若注释掉该行则输出绿色的图
}
// 对jpeg图形设置隔行扫描
if ('jpg' == $type || 'jpeg' == $type) {
imageinterlace($thumbImg, $interlace);
}
$dir = dirname($thumbname);
if (!is_dir($dir)) {
@mkdir($dir, 0777, true);
}
// 生成图片
$imageFun = 'image' . ($type == 'jpg' ? 'jpeg' : $type);
$imageFun($thumbImg, $thumbname);
imagedestroy($thumbImg);
imagedestroy($srcImg);
return $thumbname;
}
return false;
}
/**
* 图片水印
* @$image 原图
* @$water 水印图片
* @$$waterPos 水印位置(0-9) 0为随机,其他代表上中下9个部分位置
*/
static public function water($image, $water, $waterPos = 9) {
//检查图片是否存在
if (!file_exists($image) || !file_exists($water))
return false;
//读取原图像文件
$imageInfo = self::getImageInfo($image);
$image_w = $imageInfo['width'];
//取得水印图片的宽
$image_h = $imageInfo['height'];
//取得水印图片的高
$imageFun = "imagecreatefrom" . $imageInfo['type'];
$image_im = $imageFun($image);
//读取水印文件
$waterInfo = self::getImageInfo($water);
$w = $water_w = $waterInfo['width'];
//取得水印图片的宽
$h = $water_h = $waterInfo['height'];
//取得水印图片的高
$waterFun = "imagecreatefrom" . $waterInfo['type'];
$water_im = $waterFun($water);
switch ($waterPos) {
case 0 :
//随机
$posX = rand(0, ($image_w - $w));
$posY = rand(0, ($image_h - $h));
break;
case 1 :
//1为顶端居左
$posX = 0;
$posY = 0;
break;
case 2 :
//2为顶端居中
$posX = ($image_w - $w) / 2;
$posY = 0;
break;
case 3 :
//3为顶端居右
$posX = $image_w - $w;
$posY = 0;
break;
case 4 :
//4为中部居左
$posX = 0;
$posY = ($image_h - $h) / 2;
break;
case 5 :
//5为中部居中
$posX = ($image_w - $w) / 2;
$posY = ($image_h - $h) / 2;
break;
case 6 :
//6为中部居右
$posX = $image_w - $w;
$posY = ($image_h - $h) / 2;
break;
case 7 :
//7为底端居左
$posX = 0;
$posY = $image_h - $h;
break;
case 8 :
//8为底端居中
$posX = ($image_w - $w) / 2;
$posY = $image_h - $h;
break;
case 9 :
//9为底端居右
$posX = $image_w - $w;
$posY = $image_h - $h;
break;
default :
//随机
$posX = rand(0, ($image_w - $w));
$posY = rand(0, ($image_h - $h));
break;
}
//设定图像的混色模式
imagealphablending($image_im, true);
imagecopy($image_im, $water_im, $posX, $posY, 0, 0, $water_w, $water_h);
//拷贝水印到目标文件
//生成水印后的图片
$bulitImg = "image" . $imageInfo['type'];
$bulitImg($image_im, $image);
//释放内存
$waterInfo = $imageInfo = null;
imagedestroy($image_im);
}
static protected function getImageInfo($img) {
$imageInfo = getimagesize($img);
if ($imageInfo !== false) {
$imageType = strtolower(substr(image_type_to_extension($imageInfo[2]), 1));
$imageSize = filesize($img);
$info = array("width" => $imageInfo[0], "height" => $imageInfo[1], "type" => $imageType, "size" => $imageSize, "mime" => $imageInfo['mime']);
return $info;
} else {
return false;
}
}
static protected function output($im, $type = 'png', $filename = '') {
header("Content-type: image/" . $type);
$ImageFun = 'image' . $type;
if (empty($filename)) {
$ImageFun($im);
} else {
$ImageFun($im, $filename);
}
imagedestroy($im);
exit ;
}
}
?>
+21
View File
@@ -0,0 +1,21 @@
<?php
/*
* ThinkSAAS APP入口
* @copyright (c) 2010-3000 ThinkSAAS All Rights Reserved
* @code by QiuJun
* @Email:thinksaas@qq.com
*/
defined('IN_TS') or die('Access Denied.');
if (is_file('app/' . $TS_URL['app'] . '/action/' . $TS_URL['ac'] . '.php')) {
//开始执行APP action
if (is_file('app/' . $TS_URL['app'] . '/action/common.php'))
include 'app/' . $TS_URL['app'] . '/action/common.php';
include 'app/' . $TS_URL['app'] . '/action/' . $TS_URL['ac'] . '.php';
} else {
ts404();
}
+127
View File
@@ -0,0 +1,127 @@
<?php
defined('IN_TS') or die('Access Denied.');
//加密解密函数
class crypt{
protected $key = ""; //公钥
private function keyED($txt,$encrypt_key) {
$encrypt_key = md5($encrypt_key);
$ctr=0;
$tmp = "";
for ($i=0;$i<strlen($txt);$i++) {
if ($ctr==strlen($encrypt_key)){
$ctr=0;
}
$tmp.= substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1);
$ctr++;
}
return $tmp;
}
public function encrypt($txt,$key="") {
if(empty($key)){
$key=$this->key;
}
srand((double)microtime()*1000000);
$encrypt_key = md5(rand(0,32000));
$ctr=0;
$tmp = "";
for ($i=0;$i<strlen($txt);$i++) {
if ($ctr==strlen($encrypt_key)){
$ctr=0;
}
$tmp.= substr($encrypt_key,$ctr,1) .
(substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1));
$ctr++;
}
return $this->SetToHexString($this->keyED($tmp,$key));
}
public function decrypt($txt,$key="") {
if(empty($key)){
$key=$this->key;
}
$txt = $this->UnsetFromHexString($txt);
$txt = $this->keyED($txt,$key);
$tmp = "";
for ($i=0;$i<strlen($txt);$i++) {
$md5 = substr($txt,$i,1);
$i++;
$tmp.= (substr($txt,$i,1) ^ $md5);
}
return $tmp;
}
public function setKey($key) {
if(empty($key)){
return null;
}
$this->key=$key;
}
public function getKey() {
return $this->key;
}
//////////////////////////此处一下转16进制
public function SingleDecToHex($dec)
{
$tmp="";
$dec=$dec%16;
if($dec<10)
return $tmp.$dec;
$arr=array("a","b","c","d","e","f");
return $tmp.$arr[$dec-10];
}
public function SingleHexToDec($hex)
{
$v=ord($hex);
if(47<$v&&$v<58)
return $v-48;
if(96<$v&&$v<103)
return $v-87;
}
public function SetToHexString($str)
{
if(!$str)return false;
$tmp="";
for($i=0;$i<strlen($str);$i++)
{
$ord=ord($str[$i]);
$tmp.=$this->SingleDecToHex(($ord-$ord%16)/16);
$tmp.=$this->SingleDecToHex($ord%16);
}
return $tmp;
}
public function UnsetFromHexString($str)
{
if(!$str)return false;
$tmp="";
for($i=0;$i<strlen($str);$i+=2)
{
$tmp.=chr($this->SingleHexToDec(substr($str,$i,1))*16+$this->SingleHexToDec(substr($str,$i+1,1)));
}
return $tmp;
}
/*
echo SetToHexString("hello,大家好123");
echo "<hr>";
echo UnsetFromHexString(SetToHexString("hello,大家好123"));
*/
}
/*
$crypt= new crypt();
$enc_text = $crypt->encrypt('123456','wwwthinksaascn2012');
$dec_text = $crypt->decrypt($enc_text,'wwwthinksaascn2012');
*/
+4
View File
@@ -0,0 +1,4 @@
<?php
defined('IN_TS') or die('Access Denied.');
//全站通用调用数据
+95
View File
@@ -0,0 +1,95 @@
<?php
//环境配置文件
return array(
//redis配置
'redis'=>array(
'tcp'=>'tcp://127.0.0.1:6379',
'host'=>'127.0.0.1',
'port'=>'6379',
),
//Memcache配置
'memcache' => array(
//'host' => '127.0.0.1',
//'port' => 11211,
),
//是否开启debug,正式环境下请关闭
'debug' => true,
//是否开启显示插件钩子
'hook' => false,
//session存取方式,默认位本地存储,支持redis存储
'session' => '',
//对象-关系映射(数据库操作,查询构造器,模型等。php环境低于7.1切勿开启)
'orm'=>false,
//存储session文件在cache/sessions/目录下,如果IIS环境出现登陆后无法退出请将sessionpath前注释去掉,启用自定义session存储目录
//'sessionpath'=>'sessions',
//是否开启系统日志记录功能,日志存放在根目录下tslogs目录下
'logs' => false,
//是否开启mysql慢sql语句记录功能,日志存放在根目录下tslogs目录下
'slowsqllogs'=>0, //默认为0为不开启,例如:写0.5为执行时间大于0.5秒的,写1为执行时间大于1秒的
//是否支持app二级域名访问,比如小组group支持group.thinksaas.cn域名访问
//不开启请留空数组,开启写域名,比如thinksaas.cn
'subdomain' => array(
//'domain'=>'thinkpaas.com', //域名
//'app'=>array('group','user'), //开启子域的APP
),
//APP独立域名支持
'appdomain' => array(//'photo'=>'www.thinkphotos.com', //www.thinkphotos.com
),
//缓存图片和附件等支持其他域名访问,首先请将需要绑定的域名解析到程序目录
//'fileurl'=>'',
'fileurl' => array(
//'url'=>'cache.thinksaas.cn',
//'dir'=>array('cache','uploadfile','public'),
),
//feed模板数据
'feed'=>array(
'user_register'=>'',
'user_follow'=>'',
'group_create'=>'',
'group_topic_add'=>'',
'group_topic_comment'=>'',
'weibo_add'=>'',
'weibo_comment'=>'',
'article_add'=>'',
'article_comment'=>'',
),
//域名锁定,防止网站被恶意缓存仿站。例如我的网址是http://www.thinksaas.cn/,只要输入www.thinksaas.cn即可
'urllock'=>'',
/* ThinkSAAS软件版权信息
* ThinkSAAS
* 请尊重ThinkSAAS版权信息,如需去除请购买ThinkSAAS商业授权
* 联系QQ:1078700473,微信:thinksaas
*/
'info' => array(
'name' => 'ThinkSAAS',
'url' => 'https://www.thinksaas.cn/',
'email' => 'qiujun@thinksaas.cn',
'qq' => '1078700473',
'weixin' => 'thinksaas',
'copyright' => 'ThinkSAAS',
'copyurl' => 'http://www.thinksaas.cn/',
'year' => '2012',#创立时间2012年
'author' => '邱君',
),
);
+6
View File
@@ -0,0 +1,6 @@
<?php
header('Content-Type: text/html; charset=UTF-8');
echo 'Thank you for using ThinkSAAS';
echo '<br />';
echo '<a style="color:#999" href="https://www.thinksaas.cn">www.thinksaas.cn</a>';
exit;
+218
View File
@@ -0,0 +1,218 @@
<?php
defined ( 'IN_TS' ) or die ( 'Access Denied.' );
class MySql {
public $queryCount = 0;
public $conn;
public $result;
/**
* 执行的SQL语句记录
*/
public $arrSql;
/**
* @param unknown $DB 数据库链接参数
*/
function __construct($DB) {
if (! function_exists ( 'mysqli_connect' )) {
qiMsg ( '服务器PHP不支持MySQLi数据库' );
}
$this->conn = mysqli_connect ( $DB ['host'],$DB ['user'], $DB ['pwd'] ,$DB ['name'],$DB ['port'] );
if(mysqli_connect_errno())qiMsg('数据库链接错误/无法找到数据库 : '. mysqli_connect_error());
$this->query("SET NAMES utf8mb4");
}
/**
* 对特殊字符进行过滤
* @param string $value
* @return string|number
*/
public function escape($value) {
if (is_null ( $value ))
return 'NULL';
if (is_bool ( $value ))
return $value ? 1 : 0;
if (is_int ( $value ))
return ( int ) $value;
if (is_float ( $value ))
return ( float ) $value;
/*
if (get_magic_quotes_gpc ()){
$value = stripslashes ( $value );
}
*/
return '\'' . mysqli_real_escape_string ($this->conn,$value ) . '\'';
}
/**
* 格式化带limit的SQL语句
* @param unknown $sql
* @param unknown $limit
* @return string
*/
public function setlimit($sql, $limit) {
return $sql . " LIMIT {$limit}";
}
/**
* 发送查询语句
*
* @param string $sql
* @return
*/
function query($sql) {
$start_time = microtime(true);
$this->result = mysqli_query ( $this->conn,$sql );
$end_time = microtime(true);
$total_time = $end_time-$start_time;
$this->queryCount ++;
$run_time = number_format($total_time, 6);
//记录慢sql
if($GLOBALS['TS_CF']['slowsqllogs'] && $run_time>$GLOBALS['TS_CF']['slowsqllogs']){
$log = "TIME:" . date ( 'Y-m-d :H:i:s' ) . "\n";
$log .= "SQL:" . $sql . "\n";
$log .= "RUN_TIME:" . $run_time . "\n";
$log .= "REQUEST_URI:" . $_SERVER['REQUEST_URI'] . "\n";
$log .= "--------------------------------------\n";
logging ( date ( 'Ymd' ) . '-mysqli-slow.txt', $log );
}
// 记录SQL错误日志并继续执行
if (! $this->result) {
$log = "TIME:" . date ( 'Y-m-d :H:i:s' ) . "\n";
$log .= "SQL:" . $sql . "\n";
$log .= "ERROR:" . mysqli_error ($this->conn) . "\n";
$log .= "REQUEST_URI:" . $_SERVER['REQUEST_URI'] . "\n";
$log .= "--------------------------------------\n";
logging ( date ( 'Ymd' ) . '-mysqli-error.txt', $log );
}
// 记录SQL日志
if ($GLOBALS['TS_CF'] ['logs']) {
$log = "TIME:" . date ( 'Y-m-d :H:i:s' ) . "\n";
$log .= "SQL:" . $sql . "\n";
$log .= "--------------------------------------\n";
logging ( date ( 'Ymd' ) . '-mysqli.txt', $log );
}
return $this->result;
}
/**
* @param string $sql
* @param number $max
* @return multitype:
*/
function fetch_all_assoc($sql, $max = 0) {
$query = $this->query ( $sql );
while ( $list_item = mysqli_fetch_assoc ( $query ) ) {
$current_index ++;
if ($current_index > $max && $max != 0) {
break;
}
$all_array [] = $list_item;
}
return $all_array;
}
function once_fetch_assoc($sql) {
$list = $this->query ( $sql );
$list_array = mysqli_fetch_assoc ( $list );
return $list_array;
}
/**
* 获取行的数目
* @param unknown $sql
* @return number
*/
function once_num_rows($sql) {
$query = $this->query ( $sql );
return mysqli_num_rows ( $query );
}
/**
* 获得结果集中字段的数目
* @param $query
* @return number
*/
function num_fields($query) {
return mysqli_num_fields ( $query );
}
/**
* 取得上一步INSERT产生的ID
* @return number
*/
function insert_id() {
return mysqli_insert_id ( $this->conn );
}
/**
* 数组添加
* @param unknown $arrData
* @param unknown $table
* @param string $where
* @return number
*/
function insertArr($arrData, $table, $where = '') {
$Item = array ();
foreach ( $arrData as $key => $data ) {
$Item [] = "$key='$data'";
}
$intStr = implode ( ',', $Item );
$sql = "insert into $table SET $intStr $where";
// echo $sql;
$this->query ( "insert into $table SET $intStr $where" );
return mysqli_insert_id ( $this->conn );
}
/**
* 数组更新(Update)
* @param unknown $arrData
* @param unknown $table
* @param string $where
* @return boolean
*/
function updateArr($arrData, $table, $where = '') {
$Item = array ();
foreach ( $arrData as $key => $date ) {
$Item [] = "$key='$date'";
}
$upStr = implode ( ',', $Item );
$this->query ( "UPDATE $table SET $upStr $where" );
return true;
}
/**
* 获取mysql错误
* @return string
*/
function geterror() {
return mysqli_error ($this->conn);
}
/**
* Get number of affected rows in previous MySQL operation
* @return number
*/
function affected_rows() {
return mysqli_affected_rows($this->conn);
}
/**
* 获取数据库版本信息
*/
function getMysqlVersion() {
return mysqli_get_server_info ($this->conn);
}
public function __destruct() {
return mysqli_close ( $this->conn );
}
}
File diff suppressed because it is too large Load Diff
+224
View File
@@ -0,0 +1,224 @@
<?php
defined ( 'IN_TS' ) or die ( 'Access Denied.' );
class MySql {
public $queryCount = 0;
public $conn;
public $result;
/**
* 执行的SQL语句记录
*/
public $arrSql;
/**
* @param unknown $DB 数据库链接参数
*/
function __construct($DB) {
if (! function_exists ( 'mysqli_connect' )) {
qiMsg ( '服务器PHP不支持MySQLi数据库' );
}
$this->conn = mysqli_connect ( $DB ['host'],$DB ['user'], $DB ['pwd'] ,$DB ['name'],$DB ['port'] );
if(mysqli_connect_errno())qiMsg('数据库链接错误/无法找到数据库 : '. mysqli_connect_error());
$this->query("SET NAMES utf8mb4");
}
/**
* 对特殊字符进行过滤
* @param unknown $value
* @return string|number
*/
public function escape($value) {
if (is_null ( $value ))
return 'NULL';
if (is_bool ( $value ))
return $value ? 1 : 0;
if (is_int ( $value ))
return ( int ) $value;
if (is_float ( $value ))
return ( float ) $value;
/*
if (get_magic_quotes_gpc ()){
$value = stripslashes ( $value );
}
*/
return '\'' . mysqli_real_escape_string ($this->conn,$value ) . '\'';
}
/**
* 格式化带limit的SQL语句
* @param unknown $sql
* @param unknown $limit
* @return string
*/
public function setlimit($sql, $limit) {
return $sql . " LIMIT {$limit}";
}
/**
* 发送查询语句
* @param unknown $sql
* @return resource
*/
function query($sql) {
$start_time = microtime(true);
$this->result = mysqli_query ( $this->conn,$sql );
$end_time = microtime(true);
$total_time = $end_time-$start_time;
$this->queryCount ++;
$run_time = number_format($total_time, 6);
//记录慢sql
if($GLOBALS['TS_CF']['slowsqllogs'] && $run_time>$GLOBALS['TS_CF']['slowsqllogs']){
$log = "TIME:" . date ( 'Y-m-d :H:i:s' ) . "\n";
$log .= "SQL:" . $sql . "\n";
$log .= "RUN_TIME:" . $run_time . "\n";
$log .= "REQUEST_URI:" . $_SERVER['REQUEST_URI'] . "\n";
$log .= "--------------------------------------\n";
logging ( date ( 'Ymd' ) . '-mysqli-slow.txt', $log );
}
// 记录SQL错误日志并继续执行
if (! $this->result) {
$log = "TIME:" . date ( 'Y-m-d :H:i:s' ) . "\n";
$log .= "SQL:" . $sql . "\n";
$log .= "ERROR:" . mysqli_error ($this->conn) . "\n";
$log .= "REQUEST_URI:" . $_SERVER['REQUEST_URI'] . "\n";
$log .= "--------------------------------------\n";
logging ( date ( 'Ymd' ) . '-mysqli-error.txt', $log );
}
// 记录SQL日志
if ($GLOBALS['TS_CF'] ['logs']) {
$log = "TIME:" . date ( 'Y-m-d :H:i:s' ) . "\n";
$log .= "SQL:" . $sql . "\n";
$log .= "--------------------------------------\n";
logging ( date ( 'Ymd' ) . '-mysqli.txt', $log );
}
return $this->result;
}
/**
* @param unknown $sql
* @param number $max
* @return multitype:
*/
function fetch_all_assoc($sql, $max = 0) {
$query = $this->query ( $sql );
while ( $list_item = mysqli_fetch_assoc ( $query ) ) {
$current_index ++;
if ($current_index > $max && $max != 0) {
break;
}
$all_array [] = $list_item;
}
return $all_array;
}
function once_fetch_assoc($sql) {
$list = $this->query ( $sql );
$list_array = mysqli_fetch_assoc ( $list );
return $list_array;
}
/**
* 获取行的数目
* @param unknown $sql
* @return number
*/
function once_num_rows($sql) {
$query = $this->query ( $sql );
return mysqli_num_rows ( $query );
}
/**
* 获得结果集中字段的数目
* @param unknown $query
* @return number
*/
function num_fields($query) {
return mysqli_num_fields ( $query );
}
/**
* 取得上一步INSERT产生的ID
* @return number
*/
function insert_id() {
return mysqli_insert_id ( $this->conn );
}
/**
* 数组添加
* @param unknown $arrData
* @param unknown $table
* @param string $where
* @return number
*/
function insertArr($arrData, $table, $where = '') {
$Item = array ();
foreach ( $arrData as $key => $data ) {
$Item [] = "$key='$data'";
}
$intStr = implode ( ',', $Item );
$sql = "insert into $table SET $intStr $where";
// echo $sql;
$this->query ( "insert into $table SET $intStr $where" );
return mysqli_insert_id ( $this->conn );
}
/**
* 数组更新(Update)
* @param unknown $arrData
* @param unknown $table
* @param string $where
* @return boolean
*/
function updateArr($arrData, $table, $where = '') {
$Item = array ();
foreach ( $arrData as $key => $date ) {
$Item [] = "$key='$date'";
}
$upStr = implode ( ',', $Item );
$this->query ( "UPDATE $table SET $upStr $where" );
return true;
}
/**
* 获取mysql错误
* @return string
*/
function geterror() {
return mysqli_error ($this->conn);
}
/**
* Get number of affected rows in previous MySQL operation
* @return number
*/
function affected_rows() {
return mysqli_affected_rows($this->conn);
}
/**
* 获取数据库版本信息
*/
function getMysqlVersion() {
return mysqli_get_server_info ($this->conn);
}
public function __destruct() {
return mysqli_close ( $this->conn );
}
}
+362
View File
@@ -0,0 +1,362 @@
<?php
/**
* @copyright (c) ThinkSAAS All Rights Reserved
* @code by QiuJun
* @Email:thinksaas@qq.com
* @site:www.thinksaas.cn
*/
defined('IN_TS') or die('Access Denied.');
//杜绝非本站域名的使用
if($TS_CF['urllock'] && $_SERVER['SERVER_NAME']!=$TS_CF['urllock']){
echo '404 page';exit;
}
//加载基础函数
include 'tsFunction.php';
//安装专用变量
$install = isset($_GET['install']) ? $_GET['install'] : 'index';
//安装配置文件,数据库配置判断
if (!is_file('data/config.inc.php')) {
include 'install/index.php';
exit;
}
//开始计算程序执行时间
$time_start = getmicrotime();
//处理fileurl
if ($TS_CF['fileurl']['url']) {
if ($_SERVER['HTTP_HOST'] === $TS_CF['fileurl']['url']) {
echo '404 page';
exit;
}
}
//启动Memcache
if ($TS_CF['memcache'] && extension_loaded('memcache')) {
$TS_MC = Memcache::connect($TS_CF['memcache']['host'], $TS_CF['memcache']['port']);
}
//开始处理url路由,支持APP二级域名
if ($TS_CF['subdomain']) {
ini_set("session.cookie_domain", '.' . $TS_CF['subdomain']['domain']);
//APP独立域名支持
if (array_search($_SERVER['HTTP_HOST'], $TS_CF['appdomain'])) {
reurlsubdomain();
} else {
$arrHost = explode('.', $_SERVER['HTTP_HOST']);
if ($arrHost[0] == 'www') {
reurl();
} else {
reurlsubdomain();
}
}
} else {
reurl();
}
$_GET = tsgpc($_GET);
$_POST = tsgpc($_POST);
$_COOKIE = tsgpc($_COOKIE);
//$_FILES = tsgpc ( $_FILES );
//系统Url参数变量
$TS_URL = array(
'app'=>isset($_GET['app']) ? tsUrlCheck($_GET['app']) : 'home',//APP专用
'ac'=>isset($_GET['ac']) ? tsUrlCheck($_GET['ac']) : 'index',//Action专用
'mg'=>isset($_GET['mg']) ? tsUrlCheck($_GET['mg']) : '',//Admin管理专用
'my'=>isset($_GET['my']) ? tsUrlCheck($_GET['my']) : 'index',//我的社区专用
'api'=>isset($_GET['api']) ? tsUrlCheck($_GET['api']) : '',//Api专用
'ts'=>isset($_GET['ts']) ? tsUrlCheck($_GET['ts']) : '',//ThinkSAAS专用
'plugin'=>isset($_GET['plugin']) ? tsUrlCheck($_GET['plugin']) : '',//plugin专用
'in'=>isset($_GET['in']) ? tsUrlCheck($_GET['in']) : '',//plugin专用
'tp'=>isset($_GET['tp']) ? tsUrlCheck($_GET['tp']) : '1',//tp 内容分页
'page'=>isset($_GET['page']) ? tsUrlCheck($_GET['page']) : '1',//page 列表分页
'js'=>isset($_GET['js']) ? tsUrlCheck($_GET['js']) : '1',//输出json数据 接口专用
'userkey'=>isset($_REQUEST['userkey']) ? tsUrlCheck($_REQUEST['userkey']) : '',//加密用户ID,专为客户端使用
);
//下面是过渡,直到把所有的参数都改完
$app = $TS_URL['app'];
$ac = $TS_URL['ac'];
$ts = $TS_URL['ts'];
$mg = $TS_URL['mg'];
$my = $TS_URL['my'];
$api = $TS_URL['api'];
$plugin = $TS_URL['plugin'];
$in = $TS_URL['in'];
$tp = $TS_URL['tp'];
$page = $TS_URL['page'];
$js = $TS_URL['js'];
$userkey = $TS_URL['userkey'];
//APP二级域名支持,同时继续支持url原生写法
if ($TS_CF['subdomain'] && $TS_URL['app'] == 'home') {
//APP独立域名支持
$TS_URL['app'] = array_search($_SERVER['HTTP_HOST'], $TS_CF['appdomain']);
if ($TS_URL['app'] == '') {
//二级域名支持
$arrHost = explode('.', $_SERVER['HTTP_HOST']);
$TS_URL['app'] = $arrHost['0'];
if ($TS_URL['app'] == 'www') {
$TS_URL['app'] = 'home';
}
}
}
//数据库配置文件
include 'data/config.inc.php';
//加载APP配置文件
include 'app/' . $TS_URL['app'] . '/config.php';
//连接数据库
include 'mysqli.php';
$db = new MySql($TS_DB);
//加载APP数据库操作类并建立对象
include 'thinksaas/tsApp.php';
//MySQL数据库缓存
include 'thinksaas/tsMySqlCache.php';
$tsMySqlCache = new tsMySqlCache($db);
//加载网站配置文件
$TS_SITE = fileRead('data/system_options.php');
if ($TS_SITE == '') {
$TS_SITE = $tsMySqlCache -> get('system_options');
}
//加载皮肤
$tstheme = isset($_COOKIE['tsTheme']) ? tsUrlCheck($_COOKIE['tsTheme']) : $TS_SITE['site_theme'];
//加载APP导航
$TS_SITE['appnav'] = fileRead('data/system_appnav.php');
if ($TS_SITE['appnav'] == '') {
$TS_SITE['appnav'] = $tsMySqlCache -> get('system_appnav');
}
//加载我的社区导航
$TS_SITE['mynav'] = fileRead('data/system_mynav.php');
if ($TS_SITE['mynav'] == '') {
$TS_SITE['mynav'] = $tsMySqlCache -> get('system_mynav');
}
//加载APP配置
if (is_file('data/' . $TS_URL['app'] . '_options.php')) {
$TS_APP = fileRead('data/' . $TS_URL['app'] . '_options.php');
if ($TS_APP == '') {
$TS_APP = $tsMySqlCache -> get($TS_URL['app'] . '_options');
}
if ($TS_APP['isenable'] == '1' && $TS_URL['ac'] != 'admin') {
tsNotice($TS_URL['app'] . "应用关闭,请开启后访问!");
}
}
//加密用户操作
if (!isset($_SESSION['token'])) {
$_SESSION['token'] = sha1(uniqid(mt_rand(), TRUE));
}
if ($_REQUEST['token'] && $TS_SITE['istoken']) {
if (tsFilter($_REQUEST['token']) != $_SESSION['token']) {
tsNotice('非法操作!');
}
}
//定义网站URL
define('SITE_URL', $TS_SITE['site_url']);
//设置时区
date_default_timezone_set($TS_SITE['timezone']);
//接管SESSION,前台用户基本数据,$TS_USER数组
$TS_USER = isset($_SESSION['tsuser']) ? $_SESSION['tsuser'] : array();
//APP独立用户组权限控制
$route_key = $app.'_'.$ac;
if($mg && $mg!='index') $route_key .= '_'.$mg;
if($api && $api!='index') $route_key .= '_'.$api;
if($ts) $route_key .= '_'.$ts;
$TS_APP['permissions'] = fileRead('data/' . $TS_URL['app'] . '_permissions.php');
if ($TS_APP['permissions'] == '') $TS_APP['permissions'] = $tsMySqlCache -> get($TS_URL['app'] . '_permissions');
$common_ugid = tsIntval($TS_USER['ugid'],0,4);//默认4为游客
if($TS_APP['permissions']){
if($TS_APP['permissions'][$common_ugid]){
if($TS_APP['permissions'][$common_ugid][$route_key]!=null && $TS_APP['permissions'][$common_ugid][$route_key]==0){
tsNotice('权限不够!不允许访问!');
}
}
}
//记录日志
if ($TS_CF['logs']) {
//打印用户日志记录
userlog($_POST, intval($TS_USER['userid']));
userlog($_GET, intval($TS_USER['userid']));
}
//控制前台ADMIN访问权限
if ($TS_URL['ac'] == 'admin' && $TS_USER['isadmin'] != 1 && $TS_URL['app'] != 'system') {
tsHeaderUrl(SITE_URL);
}
//API逻辑单独处理
if($app=='api' || $ac=='api'){
//处理跨域
$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = array(
$TS_SITE['link_url'],
'https://h5.thinksaas.cn',
'https://www.thinksaas.cn',
'http://localhost:8080',
);
if(in_array($origin, $allow_origin)){
header('Access-Control-Allow-Origin:'.$origin);
}
header('Access-Control-Allow-Headers: X-Requested-With');
}else{
//用户自动登录
if (intval($TS_USER['userid']) == 0 && $_COOKIE['ts_email'] && $_COOKIE['ts_autologin']) {
$loginUserData = aac('user') -> find('user_info', array(
'email' => $_COOKIE['ts_email'],
'autologin' => $_COOKIE['ts_autologin']
));
if ($loginUserData) {
if ($loginUserData['ip'] != getIp() && $TS_URL['app'] != 'user' && $TS_URL['ac'] != 'login') {
tsHeaderUrl(tsUrl('user', 'login', array('ts' => 'out')));
}
//用户session信息
$_SESSION['tsuser'] = array(
'userid' => $loginUserData['userid'],
'ugid' => $loginUserData['ugid'],
'username' => $loginUserData['username'],
'email' => $loginUserData['email'],
'face'=>aac('user')->getUserFace($loginUserData),
'isadmin' => $loginUserData['isadmin'],
'signin' => $loginUserData['signin'],
'isverify' => $loginUserData['isverify'],
'isverifyphone' => $loginUserData['isverifyphone'],
'uptime' => $loginUserData['uptime'],
);
$TS_USER = $_SESSION['tsuser'];
}
}
//控制访客权限
if($TS_USER==null && $TS_SITE['visitor'] == 1){
if(!in_array($app,array('pubs','pay')) && !in_array($ac,array('info','home','register','phone','login','forgetpwd','resetpwd','wxlogin','plogin'))){
tsHeaderUrl(tsUrl('pubs','home'));
}
}
//控制后台访问权限
if ($TS_USER['isadmin'] != 1 && $TS_URL['app'] == 'system' && $TS_URL['ac'] != 'login') {
tsHeaderUrl(SITE_URL);
}
//控制插件设置权限
if ($TS_USER['isadmin'] != 1 && $TS_URL['in'] == 'edit') {
tsHeaderUrl(SITE_URL);
}
//判断用户是否需要验证Email,管理员除外
if ($TS_SITE['isverify'] == 1 && tsIntval($TS_USER['userid']) > 0 && $TS_URL['app'] != 'system' && $TS_URL['ac'] != 'admin') {
if (valid_email($TS_USER['email'])==true && tsIntval($TS_USER['isverify']) == 0 && $TS_URL['app'] != 'user' && $TS_USER['isadmin'] != 1) {
tsHeaderUrl(tsUrl('user', 'verify'));
}
}
//判断用户是否需要验证手机号,管理员除外
if ($TS_SITE['isverifyphone'] == 1 && tsIntval($TS_USER['userid']) > 0 && $TS_URL['app'] != 'system' && $TS_URL['ac'] != 'admin') {
if (tsIntval($TS_USER['isverifyphone']) == 0 && $TS_URL['app'] != 'user' && $TS_URL['app'] != 'pubs' && $TS_USER['isadmin'] != 1) {
tsHeaderUrl(tsUrl('user', 'phone',array('ts'=>'verify')));
}
}
//判断用户是否上传头像,管理员除外
if ($TS_SITE['isface'] == 1 && tsIntval($TS_USER['userid']) > 0 && $TS_URL['app'] != 'system' && $TS_URL['ac'] != 'admin' && $TS_URL['app'] != 'pubs') {
if ($TS_USER['face'] == SITE_URL.'public/images/user_large.jpg' && $TS_URL['app'] != 'user' && $TS_USER['isadmin'] != 1) {
tsHeaderUrl(tsUrl('user', 'verify', array('ts' => 'face')));
}
}
$tsHooks = array();
if ($TS_URL['app'] != 'system' && $TS_URL['app'] != 'pubs') {
//加载公用插件
$public_plugins = fileRead('data/pubs_plugins.php');
if ($public_plugins == '') {
$public_plugins = $tsMySqlCache -> get('pubs_plugins');
}
if ($public_plugins && is_array($public_plugins)) {
foreach ($public_plugins as $item) {
if (is_file('plugins/pubs/' . $item . '/' . $item . '.php')) {
include 'plugins/pubs/' . $item . '/' . $item . '.php';
}
}
}
//加载APP插件
$active_plugins = fileRead('data/' . $TS_URL['app'] . '_plugins.php');
if ($active_plugins == '') {
$active_plugins = $tsMySqlCache -> get($TS_URL['app'] . '_plugins');
}
if ($active_plugins && is_array($active_plugins)) {
foreach ($active_plugins as $item) {
if (is_file('plugins/' . $TS_URL['app'] . '/' . $item . '/' . $item . '.php')) {
include 'plugins/' . $TS_URL['app'] . '/' . $item . '/' . $item . '.php';
}
}
}
}
}
//运行统计结束
$time_end = getmicrotime();
$runTime = intval($time_end) - intval($time_start);
$TS_CF['runTime'] = number_format($runTime, 6);
//定义全局变量
global $TS_CF,$TS_SITE,$TS_APP,$TS_USER,$TS_URL,$TS_MC,$db,$tsMySqlCache,$tstheme;
//装载APP应用
if (is_file('app/' . $TS_URL['app'] . '/class.' . $TS_URL['app'] . '.php')) {
include_once 'app/' . $TS_URL['app'] . '/class.' . $TS_URL['app'] . '.php';
$new[$TS_URL['app']] = new $TS_URL['app']($db);
//在执行action之前加载
doAction('beforeAction');
//全站通用数据加载
include 'thinksaas/common.php';
//面向目录和文件的逻辑加载写法
if (is_file('app/' . $TS_URL['app'] . '/action/' . $TS_URL['ac'] . '.php')) {
//开始执行APP action
if (is_file('app/' . $TS_URL['app'] . '/action/common.php'))
include 'app/' . $TS_URL['app'] . '/action/common.php';
include 'app/' . $TS_URL['app'] . '/action/' . $TS_URL['ac'] . '.php';
} else {
ts404();
}
} else {
ts404();
}
+302
View File
@@ -0,0 +1,302 @@
<?php
// ///////////////////////////////////////////////////////////////////////
// ThinkSAAS开源社区, Copyright (C) 2011 - 3000 ThinkSAAS.cn //
// //////////////////////////////////////////////////////////////////////
defined('IN_TS') or die('Access Denied.');
class tsApp {
/**
* 数据驱动程序
*/
public $db;
public function __construct($dbhandle) {
$this->db = $dbhandle;
}
/**
* 在数据表中新增一行数据
* @table 字符,数据表
* @param row 数组形式,数组的键是数据表中的字段名,键对应的值是需要新增的数据。
* @param 数组形式,数组的键是数据表中的字段名,键对应的值是需要新增的数据。 $row
* @return bool
*/
public function create($table, $row) {
if (! is_array ( $row ) || empty ( $row ))
return FALSE;
$sql = '';
if (empty ( $row ))
return FALSE;
foreach ( $row as $key => $value ) {
$cols [] = $key;
$vals [] = $this->escape ( $value );
}
$col = join ( ',', $cols );
$val = join ( ',', $vals );
$sql = "INSERT INTO " . dbprefix . $table . " ({$col}) VALUES ({$val})";
if (FALSE != $this->db->query ( $sql )) { // 获取当前新增的ID
if ($newinserid = $this->db->insert_id ()) {
return $newinserid;
}
}
return FALSE;
}
/**
* 替换数据,根据条件替换存在的记录,如记录不存在,则将条件与替换数据相加并新增一条记录。
*
* @param table 数据表
* @param conditions 数组形式,查找条件,请注意,仅能使用数组作为该条件!
* @param row 数组形式,修改的数据
*/
public function replace($table, $conditions, $row) {
if ($this->find ( $table, $conditions )) {
return $this->update ( $table, $conditions, $row );
} else {
if (! is_array ( $conditions ))
qiMsg ( 'replace方法的条件务必是数组形式!' );
return $this->create ( $table, $row );
}
}
/**
* 修改数据,该函数将根据参数中设置的条件而更新表中数据
*
* @param table 数据表
* @param conditions 数组形式,查找条件,此参数的格式用法与find/findAll的查找条件参数是相同的。
* @param row 数组形式,修改的数据,此参数的格式用法与create的$row是相同的。在符合条件的记录中,将对$row设置的字段的数据进行修改。
*/
public function update($table, $conditions, $row) {
$where = "";
if (empty ( $row ))
return FALSE;
if (is_array ( $conditions )) {
$join = array ();
foreach ( $conditions as $key => $condition ) {
$condition = $this->escape ( $condition );
$join [] = "`{$key}` = {$condition}";
}
$where = "WHERE " . join ( " AND ", $join );
} else {
if (null != $conditions)
$where = "WHERE " . $conditions;
}
foreach ( $row as $key => $value ) {
$value = $this->escape ( $value );
//$vals [] = "`$key` = $value";
$vals [] = "{$key} = {$value}";
}
$values = join ( ", ", $vals );
$sql = "UPDATE " . dbprefix . "{$table} SET {$values} {$where}";
return $this->db->query ( $sql );
}
/**
* 按条件删除记录
*
* @param table
* @param conditions 数组形式,查找条件,此参数的格式用法与find/findAll的查找条件参数是相同的。
*/
public function delete($table, $conditions) {
$where = "";
if (is_array ( $conditions )) {
$join = array ();
foreach ( $conditions as $key => $condition ) {
$condition = $this->escape ( $condition );
$join [] = "`{$key}` = {$condition}";
}
$where = "WHERE " . join ( " AND ", $join ) . "";
} else {
if (null != $conditions)
$where = "WHERE " . $conditions . "";
}
$sql = "DELETE FROM " . dbprefix . "{$table} {$where}";
return $this->db->query ( $sql );
}
/**
* 从数据表中查找一条记录
*
* @param table 数据表
* @param conditions 查找条件,数组array("字段名"=>"查找值")或字符串,请注意在使用字符串时将需要开发者自行使用escape来对输入值进行过滤
* @param fields 返回的字段范围,默认为返回全部字段的值
* @param sort 排序,等同于“ORDER BY ”
*/
public function find($table, $conditions = null, $fields = null, $sort = null) {
if ($record = $this->findAll ( $table, $conditions, $sort, $fields, 1 )) {
return array_pop ( $record );
} else {
return FALSE;
}
}
/**
* 从数据表中查找记录
*
* @param table 数据表
* @param conditions 查找条件,数组array("字段名"=>"查找值")或字符串,请注意在使用字符串时将需要开发者自行使用escape来对输入值进行过滤
* @param sort 排序,等同于“ORDER BY ”
* @param fields 返回的字段范围,默认为返回全部字段的值
* @param limit 返回的结果数量限制,等同于“LIMIT ”,如$limit = " 3, 5",即是从第3条记录(从0开始计算)开始获取,共获取5条记录。如果limit值只有一个数字,则是指代从0条记录开始。
*/
public function findAll($table, $conditions = null, $sort = null, $fields = null, $limit = null) {
$where = "";
$fields = empty ( $fields ) ? "*" : $fields;
if (is_array ( $conditions )) {
$join = array ();
foreach ( $conditions as $key => $condition ) {
$condition = $this->escape ( $condition );
$join [] = "`{$key}` = {$condition}";
}
$where = "WHERE " . join ( " AND ", $join );
} else {
if (null != $conditions)
$where = "WHERE " . $conditions;
}
if (null != $sort) {
$sort = "ORDER BY {$sort}";
} else {
$sort = "";
}
$sql = "SELECT {$fields} FROM " . dbprefix . "{$table} {$where} {$sort}";
if (null != $limit)
$sql = $this->db->setlimit ( $sql, $limit );
return $this->db->fetch_all_assoc ( $sql );
}
/**
* 过滤转义字符
*
* @param value 需要进行过滤的值
*/
public function escape($value) {
return $this->db->escape ( $value );
}
/**
* 计算符合条件的记录数量
*
* @param table 数据表
* @param conditions 查找条件,数组array("字段名"=>"查找值")或字符串,请注意在使用字符串时将需要开发者自行使用escape来对输入值进行过滤
*/
public function findCount($table, $conditions = null) {
$where = "";
if (is_array ( $conditions )) {
$join = array ();
foreach ( $conditions as $key => $condition ) {
$condition = $this->escape ( $condition );
$join [] = "`{$key}` = {$condition}";
}
$where = "WHERE " . join ( " AND ", $join );
} else {
if (null != $conditions)
$where = "WHERE " . $conditions;
}
$sql = "SELECT COUNT(*) AS ts_counter FROM " . dbprefix . "{$table} {$where}";
$result = $this->db->once_fetch_assoc ( $sql );
return $result ['ts_counter'];
}
/**
* 按字段值修改一条记录
*
* @param conditions 数组形式,查找条件,此参数的格式用法与find/findAll的查找条件参数是相同的。
* @param field 字符串,对应数据表中的需要修改的字段名
* @param value 字符串,新值
*/
public function updateField($table, $conditions, $field, $value) {
return $this->update ( $table, $conditions, array (
$field => $value
) );
}
/**
* 执行SQL语句,相等于执行新增,修改,删除等操作。
*
* @param sql 字符串,需要执行的SQL语句
*/
public function doSql($sql){
return $this->db->query($sql);
}
/**
* 在数据表中新增多条记录
* @param table 数据表
* @param rows 数组形式,每项均为create的$row的一个数组
*/
public function createAll($table,$rows)
{
foreach($rows as $row)$this->create($table,$row);
}
/**
* 按字段值查找一条记录
* @param table 数据表
* @param field 字符串,对应数据表中的字段名
* @param value 字符串,对应的值
*/
public function findBy($table,$field, $value)
{
return $this->find($table,array($field=>$value));
}
/**
* 返回最后执行的SQL语句供分析
*/
public function dumpSql()
{
return end( $this->db->arrSql );
}
/**
* 返回上次执行update,create,delete,exec的影响行数
*/
public function affectedRows()
{
return $this->db->affected_rows();
}
/**
* 为设定的字段值增加
* @param table 数据库表
* @param conditions 数组形式,查找条件,此参数的格式用法与find/findAll的查找条件参数是相同的。
* @param field 字符串,需要增加的字段名称,该字段务必是数值类型
* @param optval 增加的值
*/
public function incrField($table,$conditions, $field, $optval = 1)
{
$where = "";
if(is_array($conditions)){
$join = array();
foreach( $conditions as $key => $condition ){
$condition = $this->escape($condition);
$join[] = "{$key} = {$condition}";
}
$where = "WHERE ".join(" AND ",$join);
}else{
if(null != $conditions)$where = "WHERE ".$conditions;
}
$values = "{$field} = {$field} + {$optval}";
$sql = "UPDATE ".dbprefix."{$table} SET {$values} {$where}";
return $this->db->query($sql);
}
/**
* 为设定的字段值减少
* @param table 数据表
* @param conditions 数组形式,查找条件,此参数的格式用法与find/findAll的查找条件参数是相同的。
* @param field 字符串,需要减少的字段名称,该字段务必是数值类型
* @param optval 减少的值
*/
public function decrField($table,$conditions, $field, $optval = 1)
{
return $this->incrField($table,$conditions, $field, - $optval);
}
}
+210
View File
@@ -0,0 +1,210 @@
<?php
defined ( 'IN_TS' ) or die ( 'Access Denied.' );
/**
* tsDbLinker
* 数据库的表间关联程序
*/
class tsDbLinker
{
/**
* 模型对象
*/
private $model_obj = null;
/**
* 预准备的结果
*/
private $prepare_result = null;
/**
* 运行的结果
*/
private $run_result = null;
/**
* 可支持的关联方法
*/
private $methods = array('find','findBy','findAll','run','create','delete','deleteByPk','update');
/**
* 是否启用全部关联
*/
public $enabled = TRUE;
/**
* 函数式使用模型辅助类的输入函数
*/
public function __input(& $obj, $args = null){
$this->model_obj = $obj;
return $this;
}
/**
* 开发者可以通过tsDbLinker()->run($result)对已经返回的数据进行关联findAll查找
* @param result 返回的数据
*/
public function run($result = FALSE){
if( FALSE == $result )return FALSE;
$this->run_result = $result;
return $this->__call('run', null);
}
/**
* 魔术函数,支持多重函数式使用类的方法
*
* 在tsDbLinker类中,__call执行了tsApp继承类的相关操作,以及按关联的描述进行了对关联数据模型类的操作。
*/
public function __call($func_name, $func_args){
if( in_array( $func_name, $this->methods ) && FALSE != $this->enabled ){
if( 'delete' == $func_name || 'deleteByPk' == $func_name )$maprecords = $this->prepare_delete($func_name, $func_args);
if( null != $this->run_result ){
$run_result = $this->run_result;
}elseif( !$run_result = call_user_func_array(array($this->model_obj, $func_name), $func_args) ){
if( 'update' != $func_name )return FALSE;
}
if( null != $this->model_obj->linker && is_array($this->model_obj->linker) ){
foreach( $this->model_obj->linker as $linkey => $thelinker ){
if( !isset($thelinker['map']) )$thelinker['map'] = $linkey;
if( FALSE == $thelinker['enabled'] )continue;
$thelinker['type'] = strtolower($thelinker['type']);
if( 'find' == $func_name || 'findBy' == $func_name ){
$run_result[$thelinker['map']] = $this->do_select( $thelinker, $run_result );
}elseif( 'findAll' == $func_name || 'run' == $func_name ){
foreach( $run_result as $single_key => $single_result )
$run_result[$single_key][$thelinker['map']] = $this->do_select( $thelinker, $single_result );
}elseif( 'create' == $func_name ){
$this->do_create( $thelinker, $run_result, $func_args );
}elseif( 'update' == $func_name ){
$this->do_update( $thelinker, $func_args );
}elseif( 'delete' == $func_name || 'deleteByPk' == $func_name ){
$this->do_delete( $thelinker, $maprecords );
}
}
}
return $run_result;
}elseif(in_array($func_name, $GLOBALS['G_SP']["auto_load_model"])){
return aac($func_name)->__input($this, $func_args);
}else{
return call_user_func_array(array($this->model_obj, $func_name), $func_args);
}
}
/**
* 私有函数,辅助删除数据操作
* @param func_name 需要执行的函数名称
* @param func_args 函数的参数
*/
private function prepare_delete($func_name, $func_args)
{
if('deleteByPk'==$func_name){
return $this->model_obj->findAll(array($this->model_obj->pk=>$func_args[0]));
}else{
return $this->model_obj->findAll($func_args[0]);
}
}
/**
* 私有函数,进行关联删除数据操作
* @param thelinker 关联的描述
* @param maprecords 对应的记录
*/
private function do_delete( $thelinker, $maprecords ){
if( FALSE == $maprecords )return FALSE;
foreach( $maprecords as $singlerecord ){
if(!empty($thelinker['condition'])){
if( is_array($thelinker['condition']) ){
$fcondition = array($thelinker['fkey']=>$singlerecord[$thelinker['mapkey']]) + $thelinker['condition'];
}else{
$fcondition = "{$thelinker['fkey']} = '{$singlerecord[$thelinker['mapkey']]}' AND {$thelinker['condition']}";
}
}else{
$fcondition = array($thelinker['fkey']=>$singlerecord[$thelinker['mapkey']]);
}
$returns = aac($thelinker['fclass'])->delete($fcondition);
}
return $returns;
}
/**
* 私有函数,进行关联更新数据操作
* @param thelinker 关联的描述
* @param func_args 进行操作的参数
*/
private function do_update( $thelinker, $func_args ){
if( !is_array($func_args[1][$thelinker['map']]) )return FALSE;
if( !$maprecords = $this->model_obj->findAll($func_args[0]))return FALSE;
foreach( $maprecords as $singlerecord ){
if(!empty($thelinker['condition'])){
if( is_array($thelinker['condition']) ){
$fcondition = array($thelinker['fkey']=>$singlerecord[$thelinker['mapkey']]) + $thelinker['condition'];
}else{
$fcondition = "{$thelinker['fkey']} = '{$singlerecord[$thelinker['mapkey']]}' AND {$thelinker['condition']}";
}
}else{
$fcondition = array($thelinker['fkey']=>$singlerecord[$thelinker['mapkey']]);
}
$returns = aac($thelinker['fclass'])->update($fcondition, $func_args[1][$thelinker['map']]);
}
return $returns;
}
/**
* 私有函数,进行关联新增数据操作
* @param thelinker 关联的描述
* @param newid 主表新增记录后的关联ID
* @param func_args 进行操作的参数
*/
private function do_create( $thelinker, $newid, $func_args ){
if( !is_array($func_args[0][$thelinker['map']]) )return FALSE;
if('hasone'==$thelinker['type']){
$newrows = $func_args[0][$thelinker['map']];
$newrows[$thelinker['fkey']] = $newid;
return aac($thelinker['fclass'])->create($newrows);
}elseif('hasmany'==$thelinker['type']){
if(array_key_exists(0,$func_args[0][$thelinker['map']])){ // 多个新增
foreach($func_args[0][$thelinker['map']] as $singlerows){
$newrows = $singlerows;
$newrows[$thelinker['fkey']] = $newid;
$returns = aac($thelinker['fclass'])->create($newrows);
}
return $returns;
}else{ // 单个新增
$newrows = $func_args[0][$thelinker['map']];
$newrows[$thelinker['fkey']] = $newid;
return aac($thelinker['fclass'])->create($newrows);
}
}
}
/**
* 私有函数,进行关联查找数据操作
* @param thelinker 关联的描述
* @param run_result 主表执行查找后返回的结果
*/
private function do_select( $thelinker, $run_result ){
if(empty($thelinker['mapkey']))$thelinker['mapkey'] = $this->model_obj->pk;
if( 'manytomany' == $thelinker['type'] ){
$do_func = 'findAll';
$midcondition = array($thelinker['mapkey']=>$run_result[$thelinker['mapkey']]);
if( !$midresult = aac($thelinker['midclass'])->findAll($midcondition,null,$thelinker['fkey']) )return FALSE;
$tmpkeys = array();foreach( $midresult as $val )$tmpkeys[] = "'".$val[$thelinker['fkey']]."'";
if(!empty($thelinker['condition'])){
if( is_array($thelinker['condition']) ){
$fcondition = "{$thelinker['fkey']} in (".join(',',$tmpkeys).")";
foreach( $thelinker['condition'] as $tmpkey => $tmpvalue )$fcondition .= " AND {$tmpkey} = '{$tmpvalue}'";
}else{
$fcondition = "{$thelinker['fkey']} in (".join(',',$tmpkeys).") AND {$thelinker['condition']}";
}
}else{
$fcondition = "{$thelinker['fkey']} in (".join(',',$tmpkeys).")";
}
}else{
$do_func = ( 'hasone' == $thelinker['type'] ) ? 'find' : 'findAll';
if(!empty($thelinker['condition'])){
if( is_array($thelinker['condition']) ){
$fcondition = array($thelinker['fkey']=>$run_result[$thelinker['mapkey']]) + $thelinker['condition'];
}else{
$fcondition = "{$thelinker['fkey']} = '{$run_result[$thelinker['mapkey']]}' AND {$thelinker['condition']}";
}
}else{
$fcondition = array($thelinker['fkey']=>$run_result[$thelinker['mapkey']]);
}
}
if(TRUE == $thelinker['countonly'])$do_func = "findCount";
return aac($thelinker['fclass'])->$do_func($fcondition, $thelinker['sort'], $thelinker['field'], $thelinker['limit'] );
}
}
+85
View File
@@ -0,0 +1,85 @@
<?php
defined ( 'IN_TS' ) or die ( 'Access Denied.' );
class tsFileCache {
private $cache_path; // path for the cache
private $cache_expire; // seconds that the cache expires
// cache constructor, optional expiring time and cache path
public function __construct($exp_time = 3600, $path = "data/") {
$this->cache_expire = $exp_time;
$this->cache_path = $path;
}
// returns the filename for the cache
private function fileName($key) {
return $this->cache_path . md5 ( $key );
}
// creates new cache files with the given data, $key== name of the cache, data the info/values to store
public function put($key, $data) {
$values = serialize ( $data );
$filename = $this->fileName ( $key );
$file = fopen ( $filename, 'w' );
if ($file) { // able to create the file
fwrite ( $file, $values );
fclose ( $file );
} else
return false;
}
// returns cache for the given key
public function get($key) {
$filename = $this->fileName ( $key );
if (! file_exists ( $filename ) || ! is_readable ( $filename )) { // can't read the cache
return false;
}
if (time () < (filemtime ( $filename ) + $this->cache_expire)) { // cache for the key not expired
$file = fopen ( $filename, "r" ); // read data file
if ($file) { // able to open the file
$data = fread ( $file, filesize ( $filename ) );
fclose ( $file );
return unserialize ( $data ); // return the values
} else
return false;
} else
return false; // was expired you need to create new
}
}
/*
使用说明:
1、实例化
$cache = new tsFileCache();
2、设置缓存时间和缓存目录
$cache = new tsFileCache(60, '/any_other_path/');
第一个参数是缓存秒数,第二个参数是缓存路径,根据需要配置。
默认情况下,缓存时间是 3600 秒,缓存目录是 cache/
3、读取缓存
$value = $cache->get('data_key');
4、写入缓存
$value = $cache->put('data_key', 'data_value');
完整实例:
$cache = new tsCache();
//从缓存从读取键值 $key 的数据
$values = $cache->get($key);
//如果没有缓存数据
if ($values == false) {
//insert code here...
//写入键值 $key 的数据
$cache->put($key, $values);
} else {
//insert code here...
}
*/
File diff suppressed because it is too large Load Diff
+52
View File
@@ -0,0 +1,52 @@
<?php
defined ( 'IN_TS' ) or die ( 'Access Denied.' );
/*
* MySQL缓存 默认为ts_cache表
*/
class tsMySqlCache extends tsApp {
public function get($name) {
$strCache = $this->find ( 'cache', array (
'cachename' => $name
), 'cachevalue', 'cacheid DESC' );
if($strCache){
return mb_unserialize(substr($strCache['cachevalue'],10));
}
//if (! $result = array_pop ( $result )) return FALSE;
// if( substr($result, 0, 10) < time() ){$this->del($name);return FALSE;}
//return mb_unserialize ( substr ( $result, 10 ) );
}
public function set($name, $value, $life_time=10) {
$value = (time () + $life_time) . serialize ( $value );
if ($this->findCount ( 'cache', array (
'cachename' => $name
) ) > 0) {
return $this->updateField ( 'cache', array (
'cachename' => $name
), 'cachevalue', $value );
} else {
return $this->create ( 'cache', array (
'cachename' => $name,
'cachevalue' => $value
) );
}
}
public function del($name) {
return $this->delete ( 'cache', array (
'cachename' => $name
) );
}
/**
* 数据库缓存到本地文件
* @return unknown
*/
public function file(){
$arrCache = $this->findAll('cache');
foreach($arrCache as $key=>$item){
fileWrite($item['cachename'].'.php','data',$this->get($item['cachename']));
}
}
}
+139
View File
@@ -0,0 +1,139 @@
<?php
defined ( 'IN_TS' ) or die ( 'Access Denied.' );
class tsTemplate {
var $var_regexp = "\@?\\\$[a-zA-Z_][\\\$\w]*(?:\[[\w\-\.\"\'\[\]\$]+\])*";
var $vtag_regexp = "\<\?php echo (\@?\\\$[a-zA-Z_][\\\$\w]*(?:\[[\w\-\.\"\'\[\]\$]+\])*)\;\?\>";
var $const_regexp = "\{([\w]+)\}";
/**
* 读模板页进行替换后写入到cache页里
*
* @param string $tplfile
* :模板源文件地址
* @param string $objfile
* :模板cache文件地址
* @return string
*/
function complie($tplfile, $objfile) {
$template = "<?php defined('IN_TS') or die('Access Denied.'); ?>";
$template .= file_get_contents ( $tplfile );
$template = $this->parse ( $template );
makedir ( dirname ( $objfile ) );
isWriteFile ( $objfile, $template, $mod = 'w', TRUE );
}
/**
* 解析模板标签
*
* @param string $template
* :模板源文件内容
* @return string
*/
function parse($template) {
// 清除模板中换行
// $template = @preg_replace('/[\n\r\t]/', '', $template);
// BY QIUJUN 2011-10-22 增加tsurl路由模板标签
$template = @preg_replace ( "/\{tsUrl(.*?)\}/s", "{php echo tsurl\\1}", $template );
//BY QIUJUN 2014 增加tsTitle过滤标题输出
$template = @preg_replace ( "/\{tsTitle(.*?)\}/s", "{php echo tsTitle\\1}", $template );
$template = @preg_replace ( "/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template ); // 去除html注释符号<!---->
$template = @preg_replace ( "/\{($this->var_regexp)\}/", "<?php echo \\1;?>", $template ); // 替换带{}的变量
$template = @preg_replace ( "/\{($this->const_regexp)\}/", "<?php echo \\1;?>", $template ); // 替换带{}的常量
$template = @preg_replace ( "/(?<!\<\?php echo |\\\\)$this->var_regexp/", "<?php echo \\0;?>", $template ); // 替换重复的<?php echo
$template = @preg_replace_callback ( "/\{php (.*?)\}/is",function( $m ){
return $this->stripvTag('<?php '.$m[1].'?>');
}, $template ); // 替换php标签
$template = @preg_replace_callback ( "/\{for (.*?)\}/is", function( $m ){
return $this->stripvTag('<?php for('.$m[1].') {?>');
}, $template ); // 替换for标签
$template = @preg_replace_callback ( "/\{elseif\s+(.+?)\}/is", function( $m ){
return $this->stripvTag('<?php } elseif ('.$m[1].') { ?>');
}, $template ); // 替换elseif标签
for($i = 0; $i < 3; $i ++) {
$template = @preg_replace_callback ( "/\{loop\s+$this->vtag_regexp\s+$this->vtag_regexp\s+$this->vtag_regexp\}(.+?)\{\/loop\}/is", function( $m ){
return $this->loopSection($m[1], $m[2], $m[3], $m[4]);
}, $template );
$template = @preg_replace_callback ( "/\{loop\s+$this->vtag_regexp\s+$this->vtag_regexp\}(.+?)\{\/loop\}/is", function( $m ){
return $this->loopSection($m[1], '', $m[2], $m[3]);
}, $template );
}
$template = @preg_replace_callback ( "/\{if\s+(.+?)\}/is", function( $m ){
return $this->stripvTag('<?php if('.$m[1].') { ?>');
}, $template ); // 替换if标签
$template = @preg_replace ( "/\{include\s+(.*?)\}/is", "<?php include \\1; ?>", $template ); // 替换include标签
$template = @preg_replace ( "/\{template\s+(\w+?)\}/is", "<?php include template('\\1'); ?>", $template ); // 替换template标签
$template = @preg_replace_callback ( "/\{block (.*?)\}/is",function( $m ){
return $this->stripBlock($m[1]);
}, $template ); // 替换block标签
$template = @preg_replace ( "/\{else\}/is", "<?php } else { ?>", $template ); // 替换else标签
$template = @preg_replace ( "/\{\/if\}/is", "<?php } ?>", $template ); // 替换/if标签
$template = @preg_replace ( "/\{\/for\}/is", "<?php } ?>", $template ); // 替换/for标签
$template = @preg_replace ( "/$this->const_regexp/", "<?php echo \\1;?>", $template ); // note {else} 也符合常量格式,此处要注意先后顺??
$template = @preg_replace ( "/(\\\$[a-zA-Z_]\w+\[)([a-zA-Z_]\w+)\]/i", "\\1'\\2']", $template ); // 将二维数组替换成带单引号的标准模式
/* $template = "<?php if(!defined('IN_TS')) exit('Access Denied');?>\r\n$template"; */
$template = "$template";
return $template;
}
/**
* 正则表达式匹配替换
*
* @param string $s
*
* @return string
*/
function stripvTag($s) {
return @preg_replace ( "/$this->vtag_regexp/is", "\\1", str_replace ( "\\\"", '"', $s ) );
}
function stripTagQuotes($expr) {
$expr = @preg_replace ( "/\<\?php echo (\\\$.+?);\?\>/s", "{\\1}", $expr );
$expr = str_replace ( "\\\"", "\"", @preg_replace ( "/\[\'([a-zA-Z0-9_\-\.\x7f-\xff]+)\'\]/s", "[\\1]", $expr ) );
return $expr;
}
function stripv($vv) {
$vv = str_replace ( '<?php', '', $vv );
$vv = str_replace ( 'echo', '', $vv );
$vv = str_replace ( ';', '', $vv );
$vv = str_replace ( '?>', '', $vv );
return $vv;
}
/**
* 将模板中的块替换成BLOCK函数
*
* @param string $blockname
*
* @param string $parameter
*
* @return string
*/
function stripBlock($parameter) {
return $this->stripTagQuotes ( "<?php Mooblock(\"$parameter\"); ?>" );
}
/**
* 替换模板中的LOOP循环
*
* @param string $arr
*
* @param string $k
*
* @param string $v
*
* @param string $statement
*
* @return string
*/
function loopSection($arr, $k, $v, $statement) {
$arr = $this->stripvTag ( $arr );
$k = $this->stripvTag ( $k );
$v = $this->stripvTag ( $v );
$statement = str_replace ( "\\\"", '"', $statement );
return $k ? "<?php foreach((array)$arr as $k=>$v) {?>$statement<?php }?>" : "<?php foreach((array)$arr as $v) {?>$statement<?php } ?>";
}
}
+199
View File
@@ -0,0 +1,199 @@
<?php
/**
* PHP 富文本XSS过滤类
*
* @package XssHtml
* @version 1.0.1
* @link http://phith0n.github.io/XssHtml
* @since 20140621
* @copyright (c) Phithon All Rights Reserved
*
*【2019-02-15由ThinkSAAS继续完善修正部分问题】
*/
class XssHtml {
private $m_dom;
private $m_xss;
private $m_ok;
private $m_AllowAttr = array('title', 'src', 'href', 'id', 'class', 'style', 'width', 'height', 'alt', 'target', 'align','type','pluginspage','wmode','play','loop','menu','allowscriptaccess','allowfullscreen','frameborder','preload','data-setup','tabindex','aria-live','aria-label','aria-hidden','aria-haspopup','role','controls','color');
private $m_AllowTag = array('a', 'img', 'br', 'strong', 'b', 'code', 'pre', 'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'table', 'ul', 'ol', 'tr', 'th', 'td', 'hr', 'li', 'u','video','audio','source','blockquote','iframe','embed','font');
/**
* 构造函数
*
* @param string $html 待过滤的文本
* @param string $charset 文本编码,默认utf-8
* @param array $AllowTag 允许的标签,如果不清楚请保持默认,默认已涵盖大部分功能,不要增加危险标签
*/
public function __construct($html, $charset = 'utf-8', $AllowTag = array()){
$this->m_AllowTag = empty($AllowTag) ? $this->m_AllowTag : $AllowTag;
$this->m_xss = strip_tags($html, '<' . implode('><', $this->m_AllowTag) . '>');
if (empty($this->m_xss)) {
$this->m_ok = FALSE;
return ;
}
$this->m_xss = "<meta http-equiv=\"Content-Type\" content=\"text/html;charset={$charset}\">" . $this->m_xss;
$this->m_dom = new DOMDocument();
$this->m_dom->strictErrorChecking = FALSE;
$this->m_ok = @$this->m_dom->loadHTML($this->m_xss);
}
/**
* 获得过滤后的内容
*/
public function getHtml()
{
if (!$this->m_ok) {
return '';
}
$nodeList = $this->m_dom->getElementsByTagName('*');
for ($i = 0; $i < $nodeList->length; $i++){
$node = $nodeList->item($i);
if (in_array($node->nodeName, $this->m_AllowTag)) {
if (method_exists($this, "__node_{$node->nodeName}")) {
call_user_func(array($this, "__node_{$node->nodeName}"), $node);
}else{
call_user_func(array($this, '__node_default'), $node);
}
}
}
return strip_tags($this->m_dom->saveHTML(), '<' . implode('><', $this->m_AllowTag) . '>');
}
private function __true_url($url){
/*
if (preg_match('#^https?://.+#is', $url)) {
return $url;
}else{
return 'http://' . $url;
}
*/
$href = $url;
if (substr($href,0, 7) == "http://" || substr($href,0, 8) == "https://" || substr($href,0, 7) == "mailto:" || substr($href,0, 4) == "tel:" || substr($href,0, 1) == "#" || substr($href,0, 1) == "/") {
return $href;
}else{
return '';
}
}
private function __get_style($node){
if ($node->attributes->getNamedItem('style')) {
$style = $node->attributes->getNamedItem('style')->nodeValue;
$style = str_replace('\\', ' ', $style);
$style = str_replace(array('&#', '/*', '*/'), ' ', $style);
$style = preg_replace('#e.*x.*p.*r.*e.*s.*s.*i.*o.*n#Uis', ' ', $style);
return $style;
}else{
return '';
}
}
private function __get_link($node, $att){
$link = $node->attributes->getNamedItem($att);
if ($link) {
return $this->__true_url($link->nodeValue);
//return $link->nodeValue;
}else{
return '';
}
}
private function __setAttr($dom, $attr, $val){
/*
if (!empty($val)) {
$dom->setAttribute($attr, $val);
}
*/
if(($attr=='href' && $val=='') || ($attr && $val)){
$dom->setAttribute($attr, $val);
}
}
private function __set_default_attr($node, $attr, $default = '')
{
$o = $node->attributes->getNamedItem($attr);
if ($o) {
$this->__setAttr($node, $attr, $o->nodeValue);
}else{
$this->__setAttr($node, $attr, $default);
}
}
private function __common_attr($node)
{
$list = array();
foreach ($node->attributes as $attr) {
if (!in_array($attr->nodeName,
$this->m_AllowAttr)) {
$list[] = $attr->nodeName;
}
}
foreach ($list as $attr) {
$node->removeAttribute($attr);
}
$style = $this->__get_style($node);
$this->__setAttr($node, 'style', $style);
$this->__set_default_attr($node, 'title');
$this->__set_default_attr($node, 'id');
$this->__set_default_attr($node, 'class');
}
private function __node_img($node){
$this->__common_attr($node);
$this->__set_default_attr($node, 'src');
$this->__set_default_attr($node, 'width');
$this->__set_default_attr($node, 'height');
$this->__set_default_attr($node, 'alt');
$this->__set_default_attr($node, 'align');
}
private function __node_a($node){
$this->__common_attr($node);
$href = $this->__get_link($node, 'href');
$this->__setAttr($node, 'href', $href);
//$this->__set_default_attr($node, 'target', '_blank');
}
private function __node_embed($node){
$this->__common_attr($node);
//$link = strtolower($this->__get_link($node, 'src'));
$link = $this->__get_link($node, 'src');
$arrType = explode('.',$link);
$type = end($arrType);
if(!in_array($type,array('swf','mp4','mp3'))) {
tsNotice('不支持的embed链接类型!');
}
$this->__setAttr($node, 'src', $link);
$this->__setAttr($node, 'allowscriptaccess', 'never');
$this->__set_default_attr($node, 'width');
$this->__set_default_attr($node, 'height');
}
private function __node_iframe($node){
$this->__common_attr($node);
//$link = strtolower($this->__get_link($node, 'src'));
$link = $this->__get_link($node, 'src');
$url = str_replace('//','',$link);
$arrUrl = explode('/',$url);
if(!in_array($arrUrl[0],array('v.qq.com','player.youku.com','player.bilibili.com'))) {
tsNotice('不支持的第三方视频!');
}
$this->__setAttr($node, 'src', $link);
}
private function __node_default($node){
$this->__common_attr($node);
}
}
?>