first commit
This commit is contained in:
commit
41681f1f18
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.DS_Store
|
||||||
|
.svn
|
5
config.yaml
Normal file
5
config.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
name: engine
|
||||||
|
version: 1
|
||||||
|
handle:
|
||||||
|
- rewrite: if(!is_dir() && !is_file()) goto "index.php?%{QUERY_STRING}"
|
4
config/app.config.php
Executable file
4
config/app.config.php
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
<?php
|
||||||
|
$__config['akey'] ='';// appkey
|
||||||
|
$__config['skey'] = '';// secret key
|
||||||
|
$__config['callback'] = 'http://'.$_SERVER['HTTP_HOST'].'/?c=callback';
|
15
config/db.config.php
Executable file
15
config/db.config.php
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
// main db setting
|
||||||
|
$master['host'] = 'localhost';
|
||||||
|
$master['user'] = 'root';
|
||||||
|
$master['passwd'] = '';
|
||||||
|
$master['dbname'] = '';
|
||||||
|
|
||||||
|
/* slave db seting
|
||||||
|
|
||||||
|
$slave['host'] = 'localhost';
|
||||||
|
$slave['user'] = 'root';
|
||||||
|
$slave['passwd'] = '';
|
||||||
|
$slave['dbname'] = '';
|
||||||
|
|
||||||
|
*/
|
39
controllers/callback.class.php
Executable file
39
controllers/callback.class.php
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
class callback extends BaseController {
|
||||||
|
public function enter(){
|
||||||
|
if( v('code') && !$_SESSION['__SINA']['TOKEN'] ){
|
||||||
|
$keys = array();
|
||||||
|
$keys['code'] = v('code');
|
||||||
|
$keys['redirect_uri'] = c('callback');
|
||||||
|
if( $token = Weibo::getAccessToken( 'code',$keys ) ){
|
||||||
|
$res = Weibo::show_user_by_id( $token['uid'] );
|
||||||
|
if( $res && !isset( $res['error_code'] ) ){
|
||||||
|
foreach ($res as $key => $value) {
|
||||||
|
$_SESSION[$key] = $value;
|
||||||
|
}
|
||||||
|
$_SESSION['__SINA']['TOKEN'] = $token;
|
||||||
|
}else{
|
||||||
|
die( 'REST API ERROR!' );
|
||||||
|
}
|
||||||
|
$_SESSION['expiresTime'] = time() + $token['remind_in'];
|
||||||
|
$_SESSION['__SINA']['TOKEN'] = $token['access_token'];
|
||||||
|
$_SESSION['uid'] = $token['uid'] ;
|
||||||
|
$uid=$_SESSION['uid'];
|
||||||
|
|
||||||
|
|
||||||
|
if( $_SESSION['backUrl'] ){
|
||||||
|
if( strpos( $_SESSION['backUrl'] , '?' ) === false ){
|
||||||
|
$backUrl = $_SESSION['backUrl'].'?viewer='.$_SESSION['uid'];
|
||||||
|
}else{
|
||||||
|
$backUrl = $_SESSION['backUrl'].'&viewer='.$_SESSION['uid'];
|
||||||
|
}
|
||||||
|
header("Location: ".$backUrl );
|
||||||
|
}else{
|
||||||
|
header('Location: http://'.$_SERVER['HTTP_HOST'].'/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
die( '<div style="padding:20px;text-aligin:center">只有授权后才能进入应用 </div>' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
controllers/main.class.php
Normal file
15
controllers/main.class.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
class Main extends BaseController{
|
||||||
|
public function enter(){
|
||||||
|
echo '<br/><br/><br/><br/>';
|
||||||
|
echo 'isAjax:'.isAjax();
|
||||||
|
echo Url::getMethod();
|
||||||
|
echo Url::$url;
|
||||||
|
$this->render();
|
||||||
|
}
|
||||||
|
public function test(){
|
||||||
|
print_r( $_REQUEST );
|
||||||
|
echo 'isAjax:'.isAjax();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
26
engine/Autoloader.class.php
Executable file
26
engine/Autoloader.class.php
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
class Autoloader {
|
||||||
|
private static $autoloaderData = array();
|
||||||
|
|
||||||
|
public static function addLoadPath( $dir ) {
|
||||||
|
array_unshift( self::$autoloaderData, $dir);
|
||||||
|
}
|
||||||
|
public static function getPathByClassName($className) {
|
||||||
|
$className = str_replace( array('/','\\') , array('','') , $className );
|
||||||
|
$file = NULL;
|
||||||
|
if( self::$autoloaderData ){
|
||||||
|
foreach (self::$autoloaderData as $path ) {
|
||||||
|
if( is_file( $path.'/'.$className.'.class.php' ) ){
|
||||||
|
return $path.'/'.$className.'.class.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function engine_autoload($class_name) {
|
||||||
|
$path = Autoloader::getPathByClassName($class_name);
|
||||||
|
if( $path ){
|
||||||
|
require($path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spl_autoload_register("engine_autoload");
|
9
engine/config/core.config.php
Executable file
9
engine/config/core.config.php
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
$__config['version'] = '1.0';
|
||||||
|
$__config['default_method'] = 'enter';
|
||||||
|
$__config['default_class'] = 'main';
|
||||||
|
|
||||||
|
$__config['cdn'] = false;
|
||||||
|
//url and db
|
||||||
|
$__config['static_url'] = 1;
|
||||||
|
$__config['use_rdc'] = 1;
|
19
engine/init.inc.php
Executable file
19
engine/init.inc.php
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* this file is init the framework
|
||||||
|
*/
|
||||||
|
if( !defined('IN') ) die('bad request');
|
||||||
|
define( 'ENGINE' , dirname( __FILE__ ) . '/' );
|
||||||
|
define( 'ISSAE', isset( $_SERVER['HTTP_APPNAME'] )&&$_SERVER['HTTP_APPNAME']?true:false );
|
||||||
|
|
||||||
|
include_once(ENGINE."Autoloader.class.php");
|
||||||
|
include_once(ENGINE."lib/core.function.php");
|
||||||
|
include_once(ROOT."lib/app.function.php");
|
||||||
|
|
||||||
|
Autoloader::addLoadPath( ENGINE. 'lib' );
|
||||||
|
Autoloader::addLoadPath( ROOT. 'lib');
|
||||||
|
if( c('static_url') )
|
||||||
|
Url::initParams();
|
||||||
|
|
||||||
|
if( c('cdn') )
|
||||||
|
Cdn::init( c('cdn') );
|
38
engine/lib/Cache.class.php
Executable file
38
engine/lib/Cache.class.php
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
Class Cache{
|
||||||
|
const CACHEDB = 'SaeMemcache';
|
||||||
|
private static $mmc = false;
|
||||||
|
private static $cacheGet = array();
|
||||||
|
private static function init(){
|
||||||
|
if( self::$mmc === false ){
|
||||||
|
self::$mmc = memcache_init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static function get($key){
|
||||||
|
if( !self::$cacheGet[$key] ){
|
||||||
|
self::init();
|
||||||
|
if( self::$mmc === false ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::$cacheGet[$key] = memcache_get(self::$mmc,$key);
|
||||||
|
}
|
||||||
|
return self::$cacheGet[$key];
|
||||||
|
}
|
||||||
|
public static function set( $key , $value , $time = 18000 ){
|
||||||
|
if( !self::$cacheGet[$key] ){
|
||||||
|
self::$cacheGet[$key] = $value;
|
||||||
|
}
|
||||||
|
self::init();
|
||||||
|
if( self::$mmc === false ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcache_set( self::$mmc , $key ,$value , false , $time );
|
||||||
|
}
|
||||||
|
public static function increment( $key , $value = 1 ){
|
||||||
|
if( !self::$cacheGet[$key] ){
|
||||||
|
self::$cacheGet[$key] += $value;
|
||||||
|
}
|
||||||
|
self::init();
|
||||||
|
return memcache_increment( self::$mmc , $key ,$value );
|
||||||
|
}
|
||||||
|
}
|
41
engine/lib/Cdn.class.php
Normal file
41
engine/lib/Cdn.class.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
class Cdn{
|
||||||
|
public static $cdnHost = false;
|
||||||
|
public static function init( $cdnHost ){
|
||||||
|
self::$cdnHost = $cdnHost;
|
||||||
|
ob_start();
|
||||||
|
}
|
||||||
|
public static function flush(){
|
||||||
|
$html = ob_get_clean();
|
||||||
|
$regs['linkReg']['reg'] = '/<link\s*([^\r\n]+?)href=[\'\"](?!http:\/\/|https:\/\/)\/?(.+?)[\'\"]/is';
|
||||||
|
$regs['linkReg']['replace'] = '<link ${1}href="http://'.self::$cdnHost.'/$2"';
|
||||||
|
|
||||||
|
$regs['scriptReg']['reg'] = '/<script\s*([^\r\n]+?)src=[\'\"](?!http:\/\/|https:\/\/)\/?(.+?)[\'\"]/is';
|
||||||
|
$regs['scriptReg']['replace'] = '<script $1src="http://'.self::$cdnHost.'/$2"';
|
||||||
|
|
||||||
|
$regs['imgReg1']['reg'] = '/<img([^\r\n]+?)src=\'(?!http:\/\/|https:\/\/)\/?(.+?)\'/is';
|
||||||
|
$regs['imgReg1']['replace'] = '<img${1}src=\'http://'.self::$cdnHost.'/$2\'';
|
||||||
|
|
||||||
|
$regs['imgReg2']['reg'] = '/<img([^\r\n]+?)src="(?!http:\/\/|https:\/\/)\/?(.+?)"/is';
|
||||||
|
$regs['imgReg2']['replace'] = '<img${1}src="http://'.self::$cdnHost.'/$2"';
|
||||||
|
|
||||||
|
|
||||||
|
$regs['bgReg']['reg'] = '/background-image:(\s*?)url\([\'\"]?(?!http:\/\/|https:\/\/)\/?(.+?)[\'\"]?\)/is';
|
||||||
|
$regs['bgReg']['replace'] = 'background-image:url( http://'.self::$cdnHost.'/$2 )';
|
||||||
|
|
||||||
|
$regs['aReg1']['reg'] = '/<a[\s\r\n]*([^\r\n]*?)href=\'(?!http:\/\/|https:\/\/)\/?([^\r\n]+?)(\.jpg\'|\.png\'|\.gif\')/is';
|
||||||
|
$regs['aReg1']['replace'] = '<a $1href=\'http://'.self::$cdnHost.'/$2';
|
||||||
|
|
||||||
|
$regs['aReg2']['reg'] = '/<a[\s\r\n]*([^\r\n]*?)href="(?!http:\/\/|https:\/\/)\/?([^\r\n]+?)(\.jpg"|\.png"|\.gif")/is';
|
||||||
|
$regs['aReg2']['replace'] = '<a $1href="http://'.self::$cdnHost.'/$2$3';
|
||||||
|
|
||||||
|
foreach ($regs as $key => $value) {
|
||||||
|
$html = preg_replace($value['reg'], $value['replace'], $html);
|
||||||
|
}
|
||||||
|
echo $html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function cdnFlush(){
|
||||||
|
Cdn::flush();
|
||||||
|
}
|
||||||
|
register_shutdown_function( 'cdnFlush' );
|
444
engine/lib/Db.class.php
Normal file
444
engine/lib/Db.class.php
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
<?php
|
||||||
|
class Db{
|
||||||
|
public $ar_sql = NULL;
|
||||||
|
private $ar_select = array();
|
||||||
|
private $ar_from = array();
|
||||||
|
private $ar_where = array();
|
||||||
|
private $ar_like = array();
|
||||||
|
private $ar_set = array();
|
||||||
|
private $ar_offset = FALSE;
|
||||||
|
//private $ar_groupby = array();
|
||||||
|
private $ar_limit = FALSE;
|
||||||
|
private $ar_orderby = array();
|
||||||
|
private $mysql = false;
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
if( defined( 'ISSAE' ) && ISSAE ){
|
||||||
|
$master['host'] = SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT;
|
||||||
|
$master['user'] = SAE_MYSQL_USER;
|
||||||
|
$master['passwd'] =SAE_MYSQL_PASS;
|
||||||
|
$master['dbname'] = SAE_MYSQL_DB;
|
||||||
|
$slave['host'] = SAE_MYSQL_HOST_S.':'.SAE_MYSQL_PORT;
|
||||||
|
}else{
|
||||||
|
include_once( ROOT.'config/db.config.php' );
|
||||||
|
}
|
||||||
|
$this->mysql = new Mysql( $master );
|
||||||
|
if( isset( $slave ) && $slave ){
|
||||||
|
$this->mysql->setSlave( $slave );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function __set( $key , $value ){
|
||||||
|
if( $key == 'do_replication' ){
|
||||||
|
$this->mysql->$key = $value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function __get( $key ){
|
||||||
|
if( $key == 'sql' ){
|
||||||
|
return $this->getSql();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function escape( $str ){
|
||||||
|
return $this->mysql->escape( $str );
|
||||||
|
}
|
||||||
|
private function getSql(){
|
||||||
|
if( $this->ar_from ){
|
||||||
|
$this->ar_sql = $this->_compile_select();
|
||||||
|
$this->_resetCache();
|
||||||
|
}
|
||||||
|
if( $this->ar_sql ){
|
||||||
|
return $this->ar_sql;
|
||||||
|
}else{
|
||||||
|
die('can not make sql...');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function getData( $sql = NULL , $key = NULL ){
|
||||||
|
if( $sql == NULL ){
|
||||||
|
$sql = $this->getSql();
|
||||||
|
}else{
|
||||||
|
$this->_resetCache();
|
||||||
|
$this->ar_sql = $sql;
|
||||||
|
}
|
||||||
|
return $this->mysql->getData($sql , $key );
|
||||||
|
}
|
||||||
|
public function getLine( $sql = NULL ){
|
||||||
|
if( $sql == NULL ){
|
||||||
|
$sql = $this->getSql();
|
||||||
|
}else{
|
||||||
|
$this->_resetCache();
|
||||||
|
$this->ar_sql = $sql;
|
||||||
|
}
|
||||||
|
return $this->mysql->getLine($sql);
|
||||||
|
}
|
||||||
|
public function getVar( $sql = NULL ){
|
||||||
|
if( $sql == NULL ){
|
||||||
|
$sql = $this->getSql();
|
||||||
|
}else{
|
||||||
|
$this->_resetCache();
|
||||||
|
$this->ar_sql = $sql;
|
||||||
|
}
|
||||||
|
return $this->mysql->getVar($sql);
|
||||||
|
}
|
||||||
|
public function runSql( $sql = NULL ){
|
||||||
|
if( $sql == NULL ){
|
||||||
|
$sql = $this->getSql();
|
||||||
|
}else{
|
||||||
|
$this->_resetCache();
|
||||||
|
$this->ar_sql = $sql;
|
||||||
|
}
|
||||||
|
return $this->mysql->runSql($sql);
|
||||||
|
}
|
||||||
|
public function lastId(){
|
||||||
|
return $this->mysql->lastId();
|
||||||
|
}
|
||||||
|
public function error(){
|
||||||
|
return $this->mysql->error();
|
||||||
|
}
|
||||||
|
public function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE){
|
||||||
|
if ($table == ''){
|
||||||
|
if ( ! isset($this->ar_from[0])){
|
||||||
|
die('can not delete error no params...');
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $this->ar_from[0];
|
||||||
|
}elseif (is_array($table)){
|
||||||
|
foreach ($table as $single_table){
|
||||||
|
$this->delete($single_table, $where, $limit, FALSE);
|
||||||
|
}
|
||||||
|
$this->_resetCache();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($where != ''){
|
||||||
|
$this->where($where);
|
||||||
|
}
|
||||||
|
if ($limit != NULL){
|
||||||
|
$this->limit($limit);
|
||||||
|
}
|
||||||
|
if (count($this->ar_where) == 0 && count($this->ar_like) == 0){
|
||||||
|
die('db_del_must_use_where...');
|
||||||
|
}
|
||||||
|
$sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);
|
||||||
|
|
||||||
|
if ($reset_data){
|
||||||
|
$this->ar_sql = $sql;
|
||||||
|
$this->_resetCache();
|
||||||
|
}
|
||||||
|
return $this->runSql($sql);
|
||||||
|
}
|
||||||
|
public function replace($table = '', $set = NULL){
|
||||||
|
if ( ! is_null($set)){
|
||||||
|
$this->set($set);
|
||||||
|
}
|
||||||
|
if (count($this->ar_set) == 0){
|
||||||
|
die('can not replace error no params...');
|
||||||
|
}
|
||||||
|
if ($table == ''){
|
||||||
|
if ( ! isset($this->ar_from[0])){
|
||||||
|
die('can not replace error no table to use...');
|
||||||
|
}
|
||||||
|
$table = $this->ar_from[0];
|
||||||
|
}
|
||||||
|
$sql = $this->_replace($table, array_keys($this->ar_set), array_values($this->ar_set));
|
||||||
|
$this->ar_sql = $sql;
|
||||||
|
$this->_resetCache();
|
||||||
|
return $this->runSql($sql);
|
||||||
|
}
|
||||||
|
public function update($table = '', $set = NULL, $where = NULL, $limit = NULL , $escape = true ){
|
||||||
|
|
||||||
|
if ( ! is_null($set)){
|
||||||
|
$this->set($set);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->ar_set) == 0){
|
||||||
|
die('can not update error no params...');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($table == ''){
|
||||||
|
if ( ! isset($this->ar_from[0])){
|
||||||
|
die('can not update error no table to use...');
|
||||||
|
}
|
||||||
|
$table = $this->ar_from[0];
|
||||||
|
}
|
||||||
|
if ($where != NULL){
|
||||||
|
$this->where($where);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($limit != NULL){
|
||||||
|
$this->limit($limit);
|
||||||
|
}
|
||||||
|
if ( $escape && !preg_match("/(`)/i", trim($table))){
|
||||||
|
$table = '`'.trim($table).'`';
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = $this->_update($table, $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
|
||||||
|
$this->ar_sql = $sql;
|
||||||
|
$this->_resetCache();
|
||||||
|
return $this->runSql($sql);
|
||||||
|
}
|
||||||
|
public function insert($table = '', $set = NULL){
|
||||||
|
if ( ! is_null($set)){
|
||||||
|
$this->set($set);
|
||||||
|
}
|
||||||
|
if (count($this->ar_set) == 0){
|
||||||
|
die('can not insert error no params...');
|
||||||
|
}
|
||||||
|
if ($table == ''){
|
||||||
|
if ( ! isset($this->ar_from[0])){
|
||||||
|
die('can not insert error no table to use...');
|
||||||
|
}
|
||||||
|
$table = $this->ar_from[0];
|
||||||
|
}
|
||||||
|
$sql = $this->_insert($table, array_keys($this->ar_set), array_values($this->ar_set));
|
||||||
|
$this->ar_sql = $sql;
|
||||||
|
$this->_resetCache();
|
||||||
|
return $this->runSql($sql);
|
||||||
|
}
|
||||||
|
public function select($select = '*'){
|
||||||
|
if (is_string($select)){
|
||||||
|
$select = explode(',', $select);
|
||||||
|
}
|
||||||
|
foreach ($select as $val){
|
||||||
|
$val = trim($val);
|
||||||
|
if ($val != ''){
|
||||||
|
$this->ar_select[] = $val;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
public function from($from , $escape = true ){
|
||||||
|
foreach ((array)$from as $val){
|
||||||
|
if (strpos($val, ',') !== FALSE){
|
||||||
|
foreach (explode(',', $val) as $v){
|
||||||
|
$v = trim($v);
|
||||||
|
if ($escape && !preg_match("/(`)/i", $v )){
|
||||||
|
$v = '`'.trim($v).'`';
|
||||||
|
}
|
||||||
|
$this->ar_from[] = $v;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$val = trim($val);
|
||||||
|
if ($escape && !preg_match("/(`)/i", $val )){
|
||||||
|
$val = '`'.trim($val).'`';
|
||||||
|
}
|
||||||
|
$this->ar_from[] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
function like($field, $match = ''){
|
||||||
|
return $this->_like($field, $match, 'AND ');
|
||||||
|
}
|
||||||
|
function notLike($field, $match = '', $side = 'both'){
|
||||||
|
return $this->_like($field, $match, 'AND ', 'NOT');
|
||||||
|
}
|
||||||
|
function orLike($field, $match = ''){
|
||||||
|
return $this->_like($field, $match, 'OR ');
|
||||||
|
}
|
||||||
|
function orNotLike($field, $match = ''){
|
||||||
|
return $this->_like($field, $match, 'OR ', 'NOT');
|
||||||
|
}
|
||||||
|
public function where($key, $value = NULL){
|
||||||
|
return $this->_where($key, $value, 'AND ');
|
||||||
|
}
|
||||||
|
public function orWhere($key, $value = NULL, $escape = TRUE){
|
||||||
|
return $this->_where($key, $value, 'OR ', $escape);
|
||||||
|
}
|
||||||
|
public function orderBy($orderby, $direction = '' , $escape = true ){
|
||||||
|
if (trim($direction) != ''){
|
||||||
|
$direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';
|
||||||
|
}
|
||||||
|
if ( $escape && strpos($orderby, ',') !== FALSE){
|
||||||
|
$temp = array();
|
||||||
|
foreach (explode(',', $orderby) as $part)
|
||||||
|
{
|
||||||
|
$part = trim($part);
|
||||||
|
$temp[] = '`'.$part.'`';
|
||||||
|
}
|
||||||
|
$orderby = implode(', ', $temp);
|
||||||
|
}elseif($escape == true ){
|
||||||
|
$orderby ='`'.$orderby.'`';
|
||||||
|
}
|
||||||
|
$orderby_statement = $orderby.$direction;
|
||||||
|
$this->ar_orderby[] = $orderby_statement;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
public function limit($value , $offset = NULL){
|
||||||
|
$this->ar_limit = $value;
|
||||||
|
if ($offset != ''){
|
||||||
|
$this->ar_offset = $offset;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
public function set($key, $value = NULL , $escape = true ){
|
||||||
|
if ( ! is_array($key)){
|
||||||
|
if(is_null($value) && $this->_has_operator($key) ){
|
||||||
|
$key = array( $key );
|
||||||
|
}else{
|
||||||
|
$key = array($key => $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($key as $k => $v){
|
||||||
|
if( is_numeric($k) && strpos( $v , '=' ) !== false ){
|
||||||
|
list( $k , $v ) = explode( '=' , $v , 2 );
|
||||||
|
$k = trim($k);
|
||||||
|
$v = trim($v);
|
||||||
|
if( $escape ){
|
||||||
|
if ( !preg_match("/(`)/i", trim($k))){
|
||||||
|
$k = '`'.trim($k).'`';
|
||||||
|
}
|
||||||
|
if ( !preg_match("/(\-|\+)/i", $v)){
|
||||||
|
$v = '`'.trim($v).'`';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
if ( $escape ){
|
||||||
|
$k = '`'.$k.'`';
|
||||||
|
$v = "'".$this->escape($v)."'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ar_set[$k] = $v;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
private function _resetCache(){
|
||||||
|
$this->ar_select = array();
|
||||||
|
$this->ar_from = array();
|
||||||
|
$this->ar_where = array();
|
||||||
|
$this->ar_like = array();
|
||||||
|
$this->ar_offset = FALSE;
|
||||||
|
$this->ar_limit = FALSE;
|
||||||
|
$this->ar_orderby = array();
|
||||||
|
$this->ar_set = array();
|
||||||
|
}
|
||||||
|
private function _like($field, $match = '', $type = 'AND ', $not = ''){
|
||||||
|
if ( ! is_array($field)){
|
||||||
|
$field = array($field => $match);
|
||||||
|
}
|
||||||
|
foreach ($field as $k => $v){
|
||||||
|
$prefix = (count($this->ar_like) == 0) ? '' : $type;
|
||||||
|
$v = $this->escape($v);
|
||||||
|
$like_statement = $prefix." `$k` $not LIKE '%{$v}%'";
|
||||||
|
$this->ar_like[] = $like_statement;
|
||||||
|
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
private function _where($key, $value = NULL, $type = 'AND ', $escape = NULL){
|
||||||
|
if ( ! is_array($key)){
|
||||||
|
$key = array($key => $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the escape value was not set will will base it on the global setting
|
||||||
|
if ( ! is_bool($escape)){
|
||||||
|
//$escape = $this->_protect_identifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($key as $k => $v){
|
||||||
|
$prefix = (count($this->ar_where) == 0 ) ? '' : $type;
|
||||||
|
if( !is_numeric($k) ){
|
||||||
|
|
||||||
|
if (is_null($v) && ! $this->_has_operator($k)){
|
||||||
|
// value appears not to have been set, assign the test to IS NULL
|
||||||
|
$k = '`'.$k.'`'.' IS NULL';
|
||||||
|
//$v = "'".$this->escape($v)."'";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! is_null($v)){
|
||||||
|
if ( ! $this->_has_operator($k)){
|
||||||
|
$k = '`'.$k.'` =';
|
||||||
|
}
|
||||||
|
$v = "'".$this->escape($v)."'";
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$k = NULL;
|
||||||
|
}
|
||||||
|
$this->ar_where[] = $prefix.$k.$v;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
private function _has_operator($str){
|
||||||
|
$str = trim($str);
|
||||||
|
if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str)){
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
private function _compile_select(){
|
||||||
|
|
||||||
|
$sql = 'SELECT ' ;
|
||||||
|
|
||||||
|
if (count($this->ar_select) == 0){
|
||||||
|
$sql .= '*';
|
||||||
|
}else{
|
||||||
|
$sql .= implode(', ', $this->ar_select);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->ar_from) > 0){
|
||||||
|
$sql .= "\nFROM ";
|
||||||
|
$sql .= implode("\n", $this->ar_from);
|
||||||
|
}
|
||||||
|
if (count($this->ar_where) > 0 OR count($this->ar_like) > 0){
|
||||||
|
$sql .= "\n";
|
||||||
|
$sql .= "WHERE ";
|
||||||
|
}
|
||||||
|
$sql .= implode("\n", $this->ar_where);
|
||||||
|
if (count($this->ar_like) > 0){
|
||||||
|
if (count($this->ar_where) > 0){
|
||||||
|
$sql .= "\nAND ";
|
||||||
|
}
|
||||||
|
$sql .= implode("\n", $this->ar_like);
|
||||||
|
}
|
||||||
|
if (count($this->ar_orderby) > 0){
|
||||||
|
$sql .= "\nORDER BY ";
|
||||||
|
$sql .= implode(', ', $this->ar_orderby);
|
||||||
|
}
|
||||||
|
if (is_numeric($this->ar_limit)){
|
||||||
|
$sql .= "\nLIMIT ";
|
||||||
|
$sql .= $this->ar_limit;
|
||||||
|
if( intval( $this->ar_offset ) ){
|
||||||
|
$sql .= ','.intval( $this->ar_offset );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $sql;
|
||||||
|
}
|
||||||
|
private function _insert($table , $keys , $values ){
|
||||||
|
$sql = "INSERT INTO $table (".join(',',$keys).")VALUES(".join(",",$values).")";
|
||||||
|
return $sql;
|
||||||
|
}
|
||||||
|
private function _update($table, $values, $where, $orderby = array(), $limit = FALSE){
|
||||||
|
foreach ($values as $key => $val){
|
||||||
|
$valstr[] = $key . ' = ' . $val;
|
||||||
|
}
|
||||||
|
$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
|
||||||
|
$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
|
||||||
|
$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
|
||||||
|
$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
|
||||||
|
$sql .= $orderby.$limit;
|
||||||
|
|
||||||
|
return $sql;
|
||||||
|
}
|
||||||
|
private function _replace($table, $keys, $values){
|
||||||
|
return "REPLACE INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
|
||||||
|
}
|
||||||
|
private function _delete($table, $where = array(), $like = array(), $limit = FALSE){
|
||||||
|
$conditions = '';
|
||||||
|
if (count($where) > 0 OR count($like) > 0){
|
||||||
|
$conditions = "\nWHERE ";
|
||||||
|
$conditions .= implode("\n", $where);
|
||||||
|
if (count($like) > 0){
|
||||||
|
$conditions .= " AND ";
|
||||||
|
$conditions .= implode("\n", $like);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
|
||||||
|
|
||||||
|
return "DELETE FROM ".$table.$conditions.$limit;
|
||||||
|
}
|
||||||
|
}
|
19
engine/lib/IFCookie.class.php
Normal file
19
engine/lib/IFCookie.class.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
class IFCookie{
|
||||||
|
const SESSIONSTR = 'SID';
|
||||||
|
public static function isNeedFix(){
|
||||||
|
$agent = $_SERVER['HTTP_USER_AGENT'];
|
||||||
|
if( strpos($agent,"iPhone") || strpos($agent,"Safari") ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static function fix(){
|
||||||
|
$pre = $_REQUEST[Url::SHORT_CLASS_TAG] == 'callback'?'state':self::SESSIONSTR;
|
||||||
|
if( isset( $_REQUEST[$pre] ) && $_REQUEST[$pre] && self::isNeedFix() ){
|
||||||
|
$sid = $_REQUEST[$pre];
|
||||||
|
session_id( $sid );
|
||||||
|
Url::$custom[self::SESSIONSTR] = $sid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
engine/lib/Icon.class.php
Executable file
117
engine/lib/Icon.class.php
Executable file
@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
class Icon{
|
||||||
|
|
||||||
|
function createIcon(){
|
||||||
|
$this->getImgSize();
|
||||||
|
//print_r( $this->img_info );
|
||||||
|
if( !$this->img_info ) return false;
|
||||||
|
$this->getNewSize();
|
||||||
|
$this->makeIcon();
|
||||||
|
}
|
||||||
|
function getImgSize(){
|
||||||
|
$this->img_info = @getImagesize( $this->path );
|
||||||
|
$this->w = $this->img_info[0];
|
||||||
|
$this->h = $this->img_info[1];
|
||||||
|
|
||||||
|
switch ( $this->img_info[2] ){
|
||||||
|
case 1:
|
||||||
|
$this->t = 'gif';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$this->t = 'jpg';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$this->t = 'png';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNewSize(){
|
||||||
|
if( $this->w > $this->h ){
|
||||||
|
$this->nh = $this->size;
|
||||||
|
$this->nw = ($this->size/$this->h) * $this->w;
|
||||||
|
$this->type = 1;
|
||||||
|
}else{
|
||||||
|
$this->nw = $this->size;
|
||||||
|
$this->nh = ($this->size/$this->w) * $this->h;
|
||||||
|
$this->type = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeIcon(){
|
||||||
|
$type = $this->type;
|
||||||
|
//$img_des = ImageCreateTrueColor ( $this->size, $this->size );
|
||||||
|
$img_des = ImageCreateTrueColor ( $this->size , $this->size );
|
||||||
|
|
||||||
|
$background = imagecolorallocate( $img_des , 255 , 255 , 255 );
|
||||||
|
imagefill( $img_des , 0 , 0 , $background );
|
||||||
|
|
||||||
|
switch ( $this->t ){
|
||||||
|
case 'gif':
|
||||||
|
$img_src = ImageCreateFromGIF ( $this->path );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'jpg':
|
||||||
|
$img_src = ImageCreateFromJPEG ( $this->path );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'png':
|
||||||
|
$img_src = ImageCreateFromPNG ( $this->path );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( $type === 1 ){
|
||||||
|
imagecopyresampled( $img_des, $img_src, 0, 0, ($this->w-$this->h)/2 , 0, $this->nw , $this->nh, $this->w, $this->h );
|
||||||
|
}elseif( $type === 0 ){
|
||||||
|
imagecopyresampled( $img_des, $img_src, 0, 0, 0 , ($this->h-$this->w)/2, $this->nw , $this->nh, $this->w, $this->h );
|
||||||
|
}else{
|
||||||
|
imagecopyresampled( $img_des, $img_src, 0, 0, 0 , 0 , $this->size, $this->size , $this->w, $this->h );
|
||||||
|
}
|
||||||
|
|
||||||
|
imageline( $img_des , 0 , 0 , 0 , ($this->size-1) , imagecolorallocate( $img_des , 220 , 220 , 220 ) );
|
||||||
|
imageline( $img_des , 0 , ($this->size-1) , ($this->size-1) , ($this->size-1) , imagecolorallocate( $img_des , 220 , 220 , 220 ) );
|
||||||
|
imageline( $img_des , ($this->size-1) , ($this->size-1) , ($this->size-1) , 0 , imagecolorallocate( $img_des , 220 , 220 , 220 ) );
|
||||||
|
imageline( $img_des , ($this->size-1) , 0 , 0 , 0 , imagecolorallocate( $img_des , 220 , 220 , 220 ) );
|
||||||
|
|
||||||
|
//echo $this->dest ;
|
||||||
|
|
||||||
|
switch ( $this->t ){
|
||||||
|
case 'gif':
|
||||||
|
if ( empty( $this->dest ) ){
|
||||||
|
header( "Content-type: image/gif" );
|
||||||
|
return ImageGIF( $img_des );
|
||||||
|
}else{
|
||||||
|
return ImageGIF( $img_des, $this->dest );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'jpg':
|
||||||
|
if ( empty( $this->dest ) ){
|
||||||
|
header ( "Content-type: image/jpeg" );
|
||||||
|
return ImageJPEG( $img_des );
|
||||||
|
}else{
|
||||||
|
return ImageJPEG( $img_des, $this->dest );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'png':
|
||||||
|
if ( empty( $this->dest ) ){
|
||||||
|
header ( "Content-type: image/png" );
|
||||||
|
return ImagePNG( $img_des );
|
||||||
|
}else{
|
||||||
|
return ImagePNG( $img_des, $this->dest );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
$icon = new Icon();
|
||||||
|
$icon->path = 'a.gif';
|
||||||
|
$icon->size = 64;
|
||||||
|
$icon->dest = 'b.gif';
|
||||||
|
$icon->createIcon();
|
||||||
|
*/
|
||||||
|
?>
|
51
engine/lib/Lock.class.php
Executable file
51
engine/lib/Lock.class.php
Executable file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
class Lock{
|
||||||
|
const LOCKTIME = 3;
|
||||||
|
private static $locked = array();
|
||||||
|
private static $memcache = false;
|
||||||
|
private static function init(){
|
||||||
|
if( self::$memcache == false ){
|
||||||
|
self::$memcache = memcache_init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static function add( $key ){
|
||||||
|
self::init();
|
||||||
|
if( self::$memcache !== false ){
|
||||||
|
$time = self::LOCKTIME;
|
||||||
|
while( $time > 0 ){
|
||||||
|
if( memcache_add( self::$memcache , $key , 'Locking' ,false , self::LOCKTIME ) ){
|
||||||
|
self::$locked[$key] = 1;
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
$time--;
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static function del( $key ){
|
||||||
|
if( self::$locked[$key] ){
|
||||||
|
self::init();
|
||||||
|
if( self::$memcache !== false ){
|
||||||
|
if( memcache_delete( self::$memcache , $key ) ){
|
||||||
|
unset( self::$locked[$key] );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public static function delAll(){
|
||||||
|
if( self::$locked && self::$memcache ){
|
||||||
|
foreach( self::$locked as $k => $v ){
|
||||||
|
if( memcache_delete( self::$memcache , $k ) ){
|
||||||
|
unset( self::$locked[$k] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function autounLock(){
|
||||||
|
Lock::delAll();
|
||||||
|
}
|
||||||
|
register_shutdown_function( 'autounLock' );
|
137
engine/lib/Mysql.class.php
Normal file
137
engine/lib/Mysql.class.php
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<?php
|
||||||
|
class Mysql{
|
||||||
|
private $master;
|
||||||
|
private $slave;
|
||||||
|
public $do_replication = false;
|
||||||
|
function __construct( $master ){
|
||||||
|
$this->master = $master;
|
||||||
|
}
|
||||||
|
private function connect( $is_master = true ){
|
||||||
|
if( $is_master ) $dbInfo = $this->master;
|
||||||
|
else $dbInfo = $this->slave;
|
||||||
|
if( !$db = mysql_connect( $dbInfo['host'] , $dbInfo['user'] , $dbInfo['passwd'] ) ){
|
||||||
|
die('can\'t connect to mysql ' . $ $dbInfo['host'] );
|
||||||
|
}else{
|
||||||
|
// mysql_query( "set names 'utf8'" , $db );
|
||||||
|
mysql_query( "set names 'utf8mb4'" , $db );
|
||||||
|
}
|
||||||
|
//echo 'connect to: '. $dbInfo['host'].'at db:'.$dbInfo['dbname'].'<br>';
|
||||||
|
mysql_select_db( $dbInfo['dbname'] , $db );
|
||||||
|
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
private function dbRead(){
|
||||||
|
if( isset( $this->dbRead ) ){
|
||||||
|
mysql_ping( $this->dbRead );
|
||||||
|
return $this->dbRead;
|
||||||
|
}else{
|
||||||
|
if( !$this->do_replication ) return $this->dbWrite();
|
||||||
|
else {
|
||||||
|
$this->dbRead = $this->connect( false );
|
||||||
|
return $this->dbRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function dbWrite(){
|
||||||
|
if( isset( $this->dbWrite ) ){
|
||||||
|
mysql_ping( $this->dbWrite );
|
||||||
|
return $this->dbWrite;
|
||||||
|
}else{
|
||||||
|
$this->dbWrite = $this->connect( true );
|
||||||
|
return $this->dbWrite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function setSlave( $slave ){
|
||||||
|
|
||||||
|
$this->slave['host'] = $slave['host'];
|
||||||
|
$this->slave['user'] = isset($slave['user']) ? $slave['user'] : $this->master['user'];
|
||||||
|
$this->slave['passwd'] = isset($slave['passwd']) ? $slave['passwd'] : $this->master['passwd'];
|
||||||
|
$this->slave['dbname'] = isset($slave['dbname']) ? $slave['dbname'] : $this->master['dbname'];
|
||||||
|
$this->do_replication = true;
|
||||||
|
}
|
||||||
|
public function saveError() {
|
||||||
|
//$GLOBALS['MYSQL_LAST_ERROR'] = mysql_error();
|
||||||
|
//$GLOBALS['MYSQL_LAST_ERRNO'] = mysql_errno();
|
||||||
|
if( mysql_errno() ){
|
||||||
|
print_r( mysql_error() );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function runSql( $sql ) {
|
||||||
|
$ret = mysql_query( $sql , $this->dbWrite() );
|
||||||
|
$this->saveError();
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
public function getData( $sql , $key = NULL ){
|
||||||
|
$GLOBALS['MYSQL_LAST_SQL'] = $sql;
|
||||||
|
$data = Array();
|
||||||
|
$i = 0;
|
||||||
|
$result = mysql_query( $sql , $this->do_replication ? $this->dbRead() : $this->dbWrite() );
|
||||||
|
|
||||||
|
$this->saveError();
|
||||||
|
|
||||||
|
while( $Array = mysql_fetch_array($result, MYSQL_ASSOC ) ){
|
||||||
|
if( $key && isset( $Array[$key] ) ){
|
||||||
|
$data[$Array[$key]] = $Array;
|
||||||
|
}else{
|
||||||
|
$data[$i++] = $Array;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if( mysql_errno() != 0 )
|
||||||
|
echo mysql_error() .' ' . $sql;
|
||||||
|
*/
|
||||||
|
|
||||||
|
mysql_free_result($result);
|
||||||
|
|
||||||
|
if( count( $data ) > 0 )
|
||||||
|
return $data;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLine( $sql ){
|
||||||
|
$data = $this->getData( $sql );
|
||||||
|
return @reset($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getVar( $sql ){
|
||||||
|
$data = $this->getLine( $sql );
|
||||||
|
return $data[ @reset(@array_keys( $data )) ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function lastId(){
|
||||||
|
$result = mysql_query( "SELECT LAST_INSERT_ID()" , $this->dbWrite() );
|
||||||
|
return reset( mysql_fetch_array( $result, MYSQL_ASSOC ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function closeDb(){
|
||||||
|
if( isset( $this->dbRead ) ){
|
||||||
|
@mysql_close( $this->dbRead );
|
||||||
|
unset( $this->dbRead );
|
||||||
|
}
|
||||||
|
if( isset( $this->dbWrite ) ){
|
||||||
|
@mysql_close( $this->dbWrite );
|
||||||
|
unset( $this->dbWrite );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function escape( $str ){
|
||||||
|
if( isset($this->dbRead)) $db = $this->dbRead ;
|
||||||
|
elseif( isset($this->dbWrite) ) $db = $this->dbWrite;
|
||||||
|
else $db = $this->dbRead();
|
||||||
|
|
||||||
|
return mysql_real_escape_string( $str , $db );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function errno(){
|
||||||
|
return $GLOBALS['MYSQL_LAST_ERRNO'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function error(){
|
||||||
|
return $GLOBALS['MYSQL_LAST_ERROR'];
|
||||||
|
}
|
||||||
|
}
|
676
engine/lib/SafeHtml.class.php
Executable file
676
engine/lib/SafeHtml.class.php
Executable file
@ -0,0 +1,676 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML_Safe Parser
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category HTML
|
||||||
|
* @package HTML_Safe
|
||||||
|
* @author Roman Ivanov <thingol@mail.ru>
|
||||||
|
* @copyright 2004-2005 Roman Ivanov
|
||||||
|
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
|
||||||
|
* @version CVS: $Id:$
|
||||||
|
* @link http://pear.php.net/package/HTML_Safe
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This package requires HTMLSax3 package
|
||||||
|
*/
|
||||||
|
require_once __DIR__.'/XML/HTMLSax3.php';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* HTML_Safe Parser
|
||||||
|
*
|
||||||
|
* This parser strips down all potentially dangerous content within HTML:
|
||||||
|
* <ul>
|
||||||
|
* <li>opening tag without its closing tag</li>
|
||||||
|
* <li>closing tag without its opening tag</li>
|
||||||
|
* <li>any of these tags: "base", "basefont", "head", "html", "body", "applet",
|
||||||
|
* "object", "iframe", "frame", "frameset", "script", "layer", "ilayer", "embed",
|
||||||
|
* "bgsound", "link", "meta", "style", "title", "blink", "xml" etc.</li>
|
||||||
|
* <li>any of these attributes: on*, data*, dynsrc</li>
|
||||||
|
* <li>javascript:/vbscript:/about: etc. protocols</li>
|
||||||
|
* <li>expression/behavior etc. in styles</li>
|
||||||
|
* <li>any other active content</li>
|
||||||
|
* </ul>
|
||||||
|
* It also tries to convert code to XHTML valid, but htmltidy is far better
|
||||||
|
* solution for this task.
|
||||||
|
*
|
||||||
|
* <b>Example:</b>
|
||||||
|
* <pre>
|
||||||
|
* $parser =new HTML_Safe();
|
||||||
|
* $result = $parser->parse($doc);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @category HTML
|
||||||
|
* @package HTML_Safe
|
||||||
|
* @author Roman Ivanov <thingol@mail.ru>
|
||||||
|
* @copyright 1997-2005 Roman Ivanov
|
||||||
|
* @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
|
||||||
|
* @version Release: @package_version@
|
||||||
|
* @link http://pear.php.net/package/HTML_Safe
|
||||||
|
*/
|
||||||
|
class SafeHtml
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Storage for resulting HTML output
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_xhtml = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of counters for each tag
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_counter = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stack of unclosed tags
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_stack = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of counters for tags that must be deleted with all content
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_dcCounter = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stack of unclosed tags that must be deleted with all content
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_dcStack = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores level of list (ol/ul) nesting
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_listScope = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stack of unclosed list tags
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_liStack = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of prepared regular expressions for protocols (schemas) matching
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_protoRegexps = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of prepared regular expressions for CSS matching
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_cssRegexps = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of single tags ("<tag />")
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $singleTags = array('area', 'br', 'img', 'input', 'hr', 'wbr', );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of dangerous tags (such tags will be deleted)
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $deleteTags = array(
|
||||||
|
'applet', 'base', 'basefont', 'bgsound', 'blink', 'body',
|
||||||
|
'embed', 'frame', 'frameset', 'head', 'html', 'ilayer',
|
||||||
|
'iframe', 'layer', 'link', 'meta', 'object', 'style',
|
||||||
|
'title', 'script',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of dangerous tags (such tags will be deleted, and all content
|
||||||
|
* inside this tags will be also removed)
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $deleteTagsContent = array('script', 'style', 'title', 'xml', );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of protocols filtering ('white' or 'black')
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $protocolFiltering = 'white';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of "dangerous" protocols (used for blacklist-filtering)
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $blackProtocols = array(
|
||||||
|
'about', 'chrome', 'data', 'disk', 'hcp',
|
||||||
|
'help', 'javascript', 'livescript', 'lynxcgi', 'lynxexec',
|
||||||
|
'ms-help', 'ms-its', 'mhtml', 'mocha', 'opera',
|
||||||
|
'res', 'resource', 'shell', 'vbscript', 'view-source',
|
||||||
|
'vnd.ms.radio', 'wysiwyg',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of "safe" protocols (used for whitelist-filtering)
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $whiteProtocols = array(
|
||||||
|
'ed2k', 'file', 'ftp', 'gopher', 'http', 'https',
|
||||||
|
'irc', 'mailto', 'news', 'nntp', 'telnet', 'webcal',
|
||||||
|
'xmpp', 'callto',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of attributes that can contain protocols
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $protocolAttributes = array(
|
||||||
|
'action', 'background', 'codebase', 'dynsrc', 'href', 'lowsrc', 'src',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of dangerous CSS keywords
|
||||||
|
*
|
||||||
|
* Whole style="" attribute will be removed, if parser will find one of
|
||||||
|
* these keywords
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $cssKeywords = array(
|
||||||
|
'absolute', 'behavior', 'behaviour', 'content', 'expression',
|
||||||
|
'fixed', 'include-source', 'moz-binding',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of tags that can have no "closing tag"
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
* @deprecated XHTML does not allow such tags
|
||||||
|
*/
|
||||||
|
var $noClose = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of block-level tags that terminates paragraph
|
||||||
|
*
|
||||||
|
* Paragraph will be closed when this tags opened
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $closeParagraph = array(
|
||||||
|
'address', 'blockquote', 'center', 'dd', 'dir', 'div',
|
||||||
|
'dl', 'dt', 'h1', 'h2', 'h3', 'h4',
|
||||||
|
'h5', 'h6', 'hr', 'isindex', 'listing', 'marquee',
|
||||||
|
'menu', 'multicol', 'ol', 'p', 'plaintext', 'pre',
|
||||||
|
'table', 'ul', 'xmp',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of table tags, all table tags outside a table will be removed
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $tableTags = array(
|
||||||
|
'caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th',
|
||||||
|
'thead', 'tr',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of list tags
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $listTags = array('dir', 'menu', 'ol', 'ul', 'dl', );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of dangerous attributes
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $attributes = array('dynsrc', 'name', );
|
||||||
|
/**
|
||||||
|
* List of delete attributes
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $deleteAttrs = array( 'id', 'class', 'urltoajax', 'action-data', 'action-type', 'confirm', 'hovertip', 'textcount',);
|
||||||
|
/**
|
||||||
|
* List of allowed "namespaced" attributes
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $attributesNS = array('xml:lang', );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs class
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function HTML_Safe()
|
||||||
|
{
|
||||||
|
//making regular expressions based on Proto & CSS arrays
|
||||||
|
foreach ($this->blackProtocols as $proto) {
|
||||||
|
$preg = "/[\s\x01-\x1F]*";
|
||||||
|
for ($i=0; $i<strlen($proto); $i++) {
|
||||||
|
$preg .= $proto{$i} . "[\s\x01-\x1F]*";
|
||||||
|
}
|
||||||
|
$preg .= ":/i";
|
||||||
|
$this->_protoRegexps[] = $preg;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->cssKeywords as $css) {
|
||||||
|
$this->_cssRegexps[] = '/' . $css . '/i';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the writing of attributes - called from $this->_openHandler()
|
||||||
|
*
|
||||||
|
* @param array $attrs array of attributes $name => $value
|
||||||
|
* @return boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _writeAttrs ($attrs)
|
||||||
|
{
|
||||||
|
if (is_array($attrs) ) {
|
||||||
|
foreach ($attrs as $name => $value) {
|
||||||
|
$name = strtolower($name);
|
||||||
|
if(in_array( $name , $this->deleteAttrs )){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strpos($name, 'on') === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strpos($name, 'data') === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (in_array($name, $this->attributes)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!preg_match("/^[a-z0-9]+$/i", $name)) {
|
||||||
|
if (!in_array($name, $this->attributesNS)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($value === TRUE) || (is_null($value))) {
|
||||||
|
$value = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($name == 'style') {
|
||||||
|
|
||||||
|
// removes insignificant backslahes
|
||||||
|
$value = str_replace("\\", '', $value);
|
||||||
|
|
||||||
|
// removes CSS comments
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
$_value = preg_replace("!/\*.*?\*/!s", '', $value);
|
||||||
|
if ($_value == $value) break;
|
||||||
|
$value = $_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace all & to &
|
||||||
|
$value = str_replace('&', '&', $value);
|
||||||
|
$value = str_replace('&', '&', $value);
|
||||||
|
|
||||||
|
foreach ($this->_cssRegexps as $css) {
|
||||||
|
if (preg_match($css, $value)) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($this->_protoRegexps as $proto) {
|
||||||
|
if (preg_match($proto, $value)) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tempval = preg_replace('/&#(\d+);?/me', "chr('\\1')", $value); //"'
|
||||||
|
$tempval = preg_replace('/&#x([0-9a-f]+);?/mei', "chr(hexdec('\\1'))", $tempval);
|
||||||
|
|
||||||
|
if ((in_array($name, $this->protocolAttributes)) &&
|
||||||
|
(strpos($tempval, ':') !== false))
|
||||||
|
{
|
||||||
|
if ($this->protocolFiltering == 'black') {
|
||||||
|
foreach ($this->_protoRegexps as $proto) {
|
||||||
|
if (preg_match($proto, $tempval)) continue 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_tempval = explode(':', $tempval);
|
||||||
|
$proto = $_tempval[0];
|
||||||
|
if (!in_array($proto, $this->whiteProtocols)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = str_replace("\"", """, $value);
|
||||||
|
$this->_xhtml .= ' ' . $name . '="' . $value . '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opening tag handler - called from HTMLSax
|
||||||
|
*
|
||||||
|
* @param object $parser HTML Parser
|
||||||
|
* @param string $name tag name
|
||||||
|
* @param array $attrs tag attributes
|
||||||
|
* @return boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _openHandler(&$parser, $name, $attrs)
|
||||||
|
{
|
||||||
|
$name = strtolower($name);
|
||||||
|
|
||||||
|
if (in_array($name, $this->deleteTagsContent)) {
|
||||||
|
array_push($this->_dcStack, $name);
|
||||||
|
$this->_dcCounter[$name] = isset($this->_dcCounter[$name]) ? $this->_dcCounter[$name]+1 : 1;
|
||||||
|
}
|
||||||
|
if (count($this->_dcStack) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($name, $this->deleteTags)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match("/^[a-z0-9]+$/i", $name)) {
|
||||||
|
if (preg_match("!(?:\@|://)!i", $name)) {
|
||||||
|
$this->_xhtml .= '<' . $name . '>';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($name, $this->singleTags)) {
|
||||||
|
$this->_xhtml .= '<' . $name;
|
||||||
|
$this->_writeAttrs($attrs);
|
||||||
|
$this->_xhtml .= ' />';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TABLES: cannot open table elements when we are not inside table
|
||||||
|
if ((isset($this->_counter['table'])) && ($this->_counter['table'] <= 0)
|
||||||
|
&& (in_array($name, $this->tableTags)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PARAGRAPHS: close paragraph when closeParagraph tags opening
|
||||||
|
if ((in_array($name, $this->closeParagraph)) && (in_array('p', $this->_stack))) {
|
||||||
|
$this->_closeHandler($parser, 'p');
|
||||||
|
}
|
||||||
|
|
||||||
|
// LISTS: we should close <li> if <li> of the same level opening
|
||||||
|
if ($name == 'li' && count($this->_liStack) &&
|
||||||
|
$this->_listScope == $this->_liStack[count($this->_liStack)-1])
|
||||||
|
{
|
||||||
|
$this->_closeHandler($parser, 'li');
|
||||||
|
}
|
||||||
|
|
||||||
|
// LISTS: we want to know on what nesting level of lists we are
|
||||||
|
if (in_array($name, $this->listTags)) {
|
||||||
|
$this->_listScope++;
|
||||||
|
}
|
||||||
|
if ($name == 'li') {
|
||||||
|
array_push($this->_liStack, $this->_listScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_xhtml .= '<' . $name;
|
||||||
|
$this->_writeAttrs($attrs);
|
||||||
|
$this->_xhtml .= '>';
|
||||||
|
array_push($this->_stack,$name);
|
||||||
|
$this->_counter[$name] = isset($this->_counter[$name]) ? $this->_counter[$name]+1 : 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closing tag handler - called from HTMLSax
|
||||||
|
*
|
||||||
|
* @param object $parsers HTML parser
|
||||||
|
* @param string $name tag name
|
||||||
|
* @return boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _closeHandler(&$parser, $name)
|
||||||
|
{
|
||||||
|
|
||||||
|
$name = strtolower($name);
|
||||||
|
|
||||||
|
if (isset($this->_dcCounter[$name]) && ($this->_dcCounter[$name] > 0) &&
|
||||||
|
(in_array($name, $this->deleteTagsContent)))
|
||||||
|
{
|
||||||
|
while ($name != ($tag = array_pop($this->_dcStack))) {
|
||||||
|
$this->_dcCounter[$tag]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_dcCounter[$name]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->_dcStack) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((isset($this->_counter[$name])) && ($this->_counter[$name] > 0)) {
|
||||||
|
while ($name != ($tag = array_pop($this->_stack))) {
|
||||||
|
$this->_closeTag($tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_closeTag($name);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes tag
|
||||||
|
*
|
||||||
|
* @param string $tag tag name
|
||||||
|
* @return boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _closeTag($tag)
|
||||||
|
{
|
||||||
|
if (!in_array($tag, $this->noClose)) {
|
||||||
|
$this->_xhtml .= '</' . $tag . '>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_counter[$tag]--;
|
||||||
|
|
||||||
|
if (in_array($tag, $this->listTags)) {
|
||||||
|
$this->_listScope--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($tag == 'li') {
|
||||||
|
array_pop($this->_liStack);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Character data handler - called from HTMLSax
|
||||||
|
*
|
||||||
|
* @param object $parser HTML parser
|
||||||
|
* @param string $data textual data
|
||||||
|
* @return boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _dataHandler(&$parser, $data)
|
||||||
|
{
|
||||||
|
if (count($this->_dcStack) == 0) {
|
||||||
|
$this->_xhtml .= $data;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape handler - called from HTMLSax
|
||||||
|
*
|
||||||
|
* @param object $parser HTML parser
|
||||||
|
* @param string $data comments or other type of data
|
||||||
|
* @return boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _escapeHandler(&$parser, $data)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the XHTML document
|
||||||
|
*
|
||||||
|
* @return string Processed (X)HTML document
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getXHTML ()
|
||||||
|
{
|
||||||
|
while ($tag = array_pop($this->_stack)) {
|
||||||
|
$this->_closeTag($tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_xhtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears current document data
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function clear()
|
||||||
|
{
|
||||||
|
$this->_xhtml = '';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main parsing fuction
|
||||||
|
*
|
||||||
|
* @param string $doc HTML document for processing
|
||||||
|
* @return string Processed (X)HTML document
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function parse($doc)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Save all '<' symbols
|
||||||
|
$doc = preg_replace("/<(?=[^a-zA-Z\/\!\?\%])/", '<', $doc);
|
||||||
|
|
||||||
|
// Web documents shouldn't contains \x00 symbol
|
||||||
|
$doc = str_replace("\x00", '', $doc);
|
||||||
|
|
||||||
|
// Opera6 bug workaround
|
||||||
|
$doc = str_replace("\xC0\xBC", '<', $doc);
|
||||||
|
|
||||||
|
// UTF-7 encoding ASCII decode
|
||||||
|
$doc = $this->repackUTF7($doc);
|
||||||
|
|
||||||
|
// Instantiate the parser
|
||||||
|
$parser=new XML_HTMLSax3();
|
||||||
|
|
||||||
|
// Set up the parser
|
||||||
|
$parser->set_object($this);
|
||||||
|
|
||||||
|
$parser->set_element_handler('_openHandler','_closeHandler');
|
||||||
|
$parser->set_data_handler('_dataHandler');
|
||||||
|
$parser->set_escape_handler('_escapeHandler');
|
||||||
|
|
||||||
|
$parser->parse($doc);
|
||||||
|
|
||||||
|
return $this->getXHTML();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UTF-7 decoding fuction
|
||||||
|
*
|
||||||
|
* @param string $str HTML document for recode ASCII part of UTF-7 back to ASCII
|
||||||
|
* @return string Decoded document
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function repackUTF7($str)
|
||||||
|
{
|
||||||
|
return preg_replace_callback('!\+([0-9a-zA-Z/]+)\-!', array($this, 'repackUTF7Callback'), $str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional UTF-7 decoding fuction
|
||||||
|
*
|
||||||
|
* @param string $str String for recode ASCII part of UTF-7 back to ASCII
|
||||||
|
* @return string Recoded string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function repackUTF7Callback($str)
|
||||||
|
{
|
||||||
|
$str = base64_decode($str[1]);
|
||||||
|
$str = preg_replace_callback('/^((?:\x00.)*)((?:[^\x00].)+)/', array($this, 'repackUTF7Back'), $str);
|
||||||
|
return preg_replace('/\x00(.)/', '$1', $str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional UTF-7 encoding fuction
|
||||||
|
*
|
||||||
|
* @param string $str String for recode ASCII part of UTF-7 back to ASCII
|
||||||
|
* @return string Recoded string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function repackUTF7Back($str)
|
||||||
|
{
|
||||||
|
return $str[1].'+'.rtrim(base64_encode($str[2]), '=').'-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* tab-width: 4
|
||||||
|
* c-basic-offset: 4
|
||||||
|
* c-hanging-comment-ender-p: nil
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
|
|
||||||
|
?>
|
167
engine/lib/Thumbnail.class.php
Executable file
167
engine/lib/Thumbnail.class.php
Executable file
@ -0,0 +1,167 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Blaz Grapar, blaz.grapar@email.si
|
||||||
|
|
||||||
|
Please don't delete my name in the script. Thanks.
|
||||||
|
|
||||||
|
This simple class creates a thumbnail of an image. Size of thumbnail is determined with maximum width and height of an thumbnail.
|
||||||
|
|
||||||
|
|
||||||
|
EXAMPLE:
|
||||||
|
$myThumb = new Thumbnail; // Start using a class
|
||||||
|
$myThumb->setMaxSize( 200, 200 ); // Specify maximum size (width, height)
|
||||||
|
$myThumb->setImgSource( 'image_original.jpg' ); // Specify original image filename
|
||||||
|
$myThumb->Create( 'image_thumbnail.jpg' ); // Specify destination image filename or leave empty to output directly
|
||||||
|
|
||||||
|
You can also get additional info about original image or thumbnail...
|
||||||
|
|
||||||
|
$myThumb = new Thumbnail; // Start using a class
|
||||||
|
$myThumb->setImgSource( 'image_original.jpg' ); // Specify original image filename
|
||||||
|
$myThumb->getImageData( 'width' ) // This will get you pixel width of original image. getImageData arguments are width|height|type
|
||||||
|
|
||||||
|
You can also use getThumbData to see the size of thumbnail that will be created.
|
||||||
|
$myThumb = new Thumbnail; // Start using a class
|
||||||
|
$myThumb->setMaxSize( 200, 200 ); // Specify maximum size (width, height)
|
||||||
|
$myThumb->getThumbData( 'width' ) // This will get you pixel width of thumbnail image. getImageData arguments are width|height|type
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class Thumbnail
|
||||||
|
{
|
||||||
|
|
||||||
|
// Set destination filename
|
||||||
|
function setImgSource( $source )
|
||||||
|
{
|
||||||
|
$this->source = $source;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set maximum size of thumbnail
|
||||||
|
function setMaxSize ( $max_width = 100, $max_height = 100 )
|
||||||
|
{
|
||||||
|
$this->max_width = $max_width;
|
||||||
|
$this->max_height = $max_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get info about original image
|
||||||
|
function getImageData( $data )
|
||||||
|
{
|
||||||
|
$size = getimagesize( $this->source );
|
||||||
|
|
||||||
|
switch ( $data )
|
||||||
|
{
|
||||||
|
case 'width':
|
||||||
|
return $size[0];
|
||||||
|
break;
|
||||||
|
case 'height':
|
||||||
|
return $size[1];
|
||||||
|
break;
|
||||||
|
case 'type':
|
||||||
|
switch ( $size[2] )
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return 'gif';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return 'jpg';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return 'png';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get info about thumbnail
|
||||||
|
function getThumbData( $data ){
|
||||||
|
$w_ratio = $this->max_width / $this->GetImageData('width');
|
||||||
|
$h_ratio = $this->max_height / $this->GetImageData('height');
|
||||||
|
|
||||||
|
if ( $h_ratio < $w_ratio ){
|
||||||
|
$height = $this->max_height;
|
||||||
|
$width = round( $this->GetImageData('width') * $h_ratio, 0);
|
||||||
|
}else{
|
||||||
|
$width = $this->max_width;
|
||||||
|
$height = round( $this->GetImageData('height') * $w_ratio, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( $data ){
|
||||||
|
case 'width':
|
||||||
|
return $width;
|
||||||
|
break;
|
||||||
|
case 'height':
|
||||||
|
return $height;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Creating a thumbnail
|
||||||
|
function Create( $dest = NULL ){
|
||||||
|
$img_des = imagecreatetruecolor( $this->GetThumbData('width'), $this->GetThumbData('height') );
|
||||||
|
|
||||||
|
$background = imagecolorallocate( $img_des , 255 , 255 , 255 );
|
||||||
|
imagefill( $img_des , 0 , 0 , $background );
|
||||||
|
|
||||||
|
switch ( $this->GetImageData('type') ){
|
||||||
|
case 'gif':
|
||||||
|
$img_src = imagecreatefromgif( $this->source );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'jpg':
|
||||||
|
$img_src = imagecreatefromjpeg( $this->source );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'png':
|
||||||
|
$img_src = imagecreatefrompng( $this->source );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GD 1.0
|
||||||
|
//ImageCopyResized( $img_des, $img_src, 0, 0, 0, 0, $this->GetThumbData('width'), $this->GetThumbData('height'), $this->GetImageData('width'), $this->GetImageData('height') );
|
||||||
|
// GD 2.0
|
||||||
|
imagecopyresampled( $img_des, $img_src, 0, 0, 0, 0, $this->GetThumbData('width'), $this->GetThumbData('height'), $this->GetImageData('width'), $this->GetImageData('height') );
|
||||||
|
|
||||||
|
switch ( $this->GetImageData('type') ){
|
||||||
|
case 'gif':
|
||||||
|
if ( empty( $dest ) ){
|
||||||
|
ob_start();
|
||||||
|
//header( "Content-type: image/gif" );
|
||||||
|
imagegif( $img_des );
|
||||||
|
$return = ob_get_clean();
|
||||||
|
return $return;
|
||||||
|
}else{
|
||||||
|
return imagegif( $img_des, $dest );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'jpg':
|
||||||
|
if ( empty( $dest ) ){
|
||||||
|
ob_start();
|
||||||
|
//header ( "Content-type: image/jpeg" );
|
||||||
|
imagejpeg( $img_des );
|
||||||
|
$return = ob_get_clean();
|
||||||
|
return $return;
|
||||||
|
}else{
|
||||||
|
return imagejpeg( $img_des, $dest );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'png':
|
||||||
|
if ( empty( $dest ) ){
|
||||||
|
ob_start();
|
||||||
|
//header ( "Content-type: image/png" );
|
||||||
|
imagepng( $img_des );
|
||||||
|
$return = ob_get_clean();
|
||||||
|
return $return;
|
||||||
|
}else{
|
||||||
|
return imagepng( $img_des, $dest );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
147
engine/lib/Url.class.php
Executable file
147
engine/lib/Url.class.php
Executable file
@ -0,0 +1,147 @@
|
|||||||
|
<?php
|
||||||
|
class Url{
|
||||||
|
const SHORT_CLASS_TAG = 'c';
|
||||||
|
const SHORT_METHOD_TAG = 'm';
|
||||||
|
const URLBASE = '/';
|
||||||
|
public static $enter = array();
|
||||||
|
public static $params = array();
|
||||||
|
public static $custom = array();
|
||||||
|
public static $url = false;
|
||||||
|
|
||||||
|
public static function setUrl( $url ){
|
||||||
|
self::$enter = self::$params = array();
|
||||||
|
self::$url = $url;
|
||||||
|
self::initParams();
|
||||||
|
}
|
||||||
|
public static function getUrl(){
|
||||||
|
self::initParams();
|
||||||
|
return self::$url;
|
||||||
|
}
|
||||||
|
public static function get( $str ){
|
||||||
|
self::initParams();
|
||||||
|
return isset( self::$params[$str] )?self::$params[$str]:false ;
|
||||||
|
}
|
||||||
|
public static function getClass(){
|
||||||
|
self::initParams();
|
||||||
|
return self::$enter['class'];
|
||||||
|
}
|
||||||
|
public static function getMethod(){
|
||||||
|
self::initParams();
|
||||||
|
return self::$enter['method'];
|
||||||
|
}
|
||||||
|
public static function make( $custom = array() , $old = array() ){
|
||||||
|
self::initParams();
|
||||||
|
|
||||||
|
$base = array();
|
||||||
|
|
||||||
|
self::formatUrlParams( $base , $custom , $old );
|
||||||
|
|
||||||
|
//$base[self::SHORT_CLASS_TAG] = $base[self::SHORT_CLASS_TAG]?:self::getClass();
|
||||||
|
//$base[self::SHORT_METHOD_TAG] = $base[self::SHORT_METHOD_TAG]?:c('default_method');
|
||||||
|
|
||||||
|
if( !$base[self::SHORT_CLASS_TAG] ){
|
||||||
|
$base[self::SHORT_CLASS_TAG] = self::getClass();
|
||||||
|
if( !$base[self::SHORT_METHOD_TAG] ){
|
||||||
|
$base[self::SHORT_METHOD_TAG] = self::getMethod();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( !$base[self::SHORT_METHOD_TAG] ){
|
||||||
|
$base[self::SHORT_METHOD_TAG] = c('default_method');
|
||||||
|
}
|
||||||
|
|
||||||
|
if( $base[self::SHORT_METHOD_TAG]== c('default_method') ){
|
||||||
|
unset( $base[self::SHORT_METHOD_TAG] );
|
||||||
|
if( !$custom && !$old && $base[self::SHORT_CLASS_TAG]== c('default_class') ){
|
||||||
|
unset( $base[self::SHORT_CLASS_TAG] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//start to make url
|
||||||
|
$url = c('url_base')?c('url_base'):self::URLBASE;
|
||||||
|
if( c('static_url') ){
|
||||||
|
if( $base )
|
||||||
|
$url .= join('/',$base).'/';
|
||||||
|
|
||||||
|
if( $custom ){
|
||||||
|
foreach( $custom as $k => $v ){
|
||||||
|
if( $v ){
|
||||||
|
$url .= $k.'/'.$v.'/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if( $base )
|
||||||
|
$custom += $base;
|
||||||
|
|
||||||
|
if( $custom )
|
||||||
|
$url .= '?'.http_build_query($custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
public static function initParams(){
|
||||||
|
if( !self::$enter ){
|
||||||
|
$custom = array();
|
||||||
|
if( !self::$url ){
|
||||||
|
if( c('static_url') ){
|
||||||
|
self::$url = isset($_SERVER['REDIRECT_URL'])&&$_SERVER['REDIRECT_URL']?$_SERVER['REDIRECT_URL']:$_SERVER['PATH_INFO'];
|
||||||
|
}else{
|
||||||
|
self::$url = $_GET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( c('static_url') ){
|
||||||
|
$tempArray = explode( '/' , trim(self::$url , '/' ) );
|
||||||
|
if( $tempArray ){
|
||||||
|
if( count( $tempArray )%2 == 0 ){
|
||||||
|
$custom['class'] = safeUrlString(array_shift( $tempArray ));
|
||||||
|
$custom['method'] = safeUrlString(array_shift( $tempArray ));
|
||||||
|
}else{
|
||||||
|
$custom['class'] = safeUrlString(array_shift( $tempArray ));
|
||||||
|
$custom['method'] = c('default_method');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( $tempArray ){
|
||||||
|
foreach( array_chunk($tempArray, 2) as $v ){
|
||||||
|
list( $key , $value ) = $v;
|
||||||
|
$custom[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$custom = self::$url;
|
||||||
|
}
|
||||||
|
$base = array();
|
||||||
|
self::formatUrlParams( $base , $custom );
|
||||||
|
self::$enter['class'] = $base[self::SHORT_CLASS_TAG]?:c('default_class');
|
||||||
|
self::$enter['method'] = $base[self::SHORT_METHOD_TAG]?:c('default_method');
|
||||||
|
self::$params = $custom;
|
||||||
|
if( c('static_url') ){
|
||||||
|
$_REQUEST += $base + $custom;
|
||||||
|
$_GET += $base + $custom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static function formatUrlParams( &$base , &$custom , $old = array() ){
|
||||||
|
// init url params
|
||||||
|
if( !is_array( $custom ) ){
|
||||||
|
parse_str( ltrim( $custom , '?' ) , $custom);
|
||||||
|
}
|
||||||
|
$custom += self::$custom;
|
||||||
|
if( $old ){
|
||||||
|
foreach( $old as $v ){
|
||||||
|
if( $v && self::$params[$v] ){
|
||||||
|
$custom[$v] = self::$params[$v];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//init custom params
|
||||||
|
$needFix = array( 'class' , 'method' , self::SHORT_CLASS_TAG , self::SHORT_CLASS_TAG );
|
||||||
|
foreach( $needFix as $v ){
|
||||||
|
$custom[$v] = $custom[$v]?:NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = $custom[self::SHORT_CLASS_TAG]?:$custom['class'];
|
||||||
|
$method = $custom[self::SHORT_METHOD_TAG]?:$custom['method'];
|
||||||
|
unset( $custom['class'], $custom[self::SHORT_CLASS_TAG] , $custom['method'] ,$custom[self::SHORT_METHOD_TAG] );
|
||||||
|
$base[self::SHORT_CLASS_TAG] = $class;
|
||||||
|
$base[self::SHORT_METHOD_TAG] = $method;
|
||||||
|
}
|
||||||
|
}
|
64
engine/lib/Weibo.class.php
Executable file
64
engine/lib/Weibo.class.php
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
Class Weibo{
|
||||||
|
private static $weiboClient,$weiboOAuth;
|
||||||
|
private static $akey,$skey,$access_token,$refresh_token;
|
||||||
|
private static $ip;
|
||||||
|
public static function init( $akey, $skey, $access_token = NULL , $refresh_token = NULL ){
|
||||||
|
self::$akey = $akey; self::$skey = $skey; self::$access_token = $access_token; self::$refresh_token = $refresh_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function setIp( $ip ){
|
||||||
|
self::$ip = $ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function __callStatic($funcName, $args){
|
||||||
|
if( !self::$akey && !self::$skey ){
|
||||||
|
die( 'Weibo Class is not init.' );
|
||||||
|
}
|
||||||
|
self::initWeiboClient();
|
||||||
|
if( self::$weiboClient ){
|
||||||
|
if( method_exists(self::$weiboClient ,$funcName ) ){
|
||||||
|
$res = call_user_func_array(array(self::$weiboClient , $funcName) , $args );
|
||||||
|
if( $fun = c('after_weibo') ){
|
||||||
|
if( function_exists( $fun ) ){
|
||||||
|
$fun( $res );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self::initWeiboOAuth();
|
||||||
|
if( self::$weiboOAuth ){
|
||||||
|
if( method_exists(self::$weiboOAuth ,$funcName ) ){
|
||||||
|
if( $funcName == 'getAccessToken' ){
|
||||||
|
$token = call_user_func_array( array(self::$weiboOAuth ,$funcName ), $args );
|
||||||
|
if( !self::$weiboClient && $token['access_token'] ){
|
||||||
|
self::$access_token = $token['access_token'];
|
||||||
|
self::initWeiboClient();
|
||||||
|
}
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
return call_user_func_array( array(self::$weiboOAuth ,$funcName ), $args );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
die( 'Function '.$funcName.' is not find in Weibo Class' );
|
||||||
|
}
|
||||||
|
private static function initWeiboClient(){
|
||||||
|
if( !self::$weiboClient && self::$access_token ){
|
||||||
|
include_once( "saetv2.ex.class.php" );
|
||||||
|
self::$weiboClient = new SaeTClientV2( self::$akey, self::$skey, self::$access_token, self::$refresh_token );
|
||||||
|
if( self::$ip ){
|
||||||
|
self::$weiboClient->set_remote_ip( self::$ip );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static function initWeiboOAuth(){
|
||||||
|
if( !self::$weiboOAuth ){
|
||||||
|
include_once( "saetv2.ex.class.php" );
|
||||||
|
self::$weiboOAuth = new SaeTOAuthV2( self::$akey, self::$skey, self::$access_token, self::$refresh_token );
|
||||||
|
if( self::$ip ){
|
||||||
|
self::$weiboOAuth->remote_ip = self::$ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
688
engine/lib/XML/HTMLSax3.php
Normal file
688
engine/lib/XML/HTMLSax3.php
Normal file
@ -0,0 +1,688 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
//
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2002 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject toversion 3.0 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/3_0.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Authors: Alexander Zhukov <alex@veresk.ru> Original port from Python |
|
||||||
|
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> Port to PEAR + more |
|
||||||
|
// | Authors: Many @ Sitepointforums Advanced PHP Forums |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: HTMLSax3.php,v 1.2 2007/10/29 21:41:34 hfuecks Exp $
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* Main parser components
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @version $Id: HTMLSax3.php,v 1.2 2007/10/29 21:41:34 hfuecks Exp $
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Required classes
|
||||||
|
*/
|
||||||
|
define('XML_HTMLSAX3', 'XML/');
|
||||||
|
if (!defined('XML_HTMLSAX3')) {
|
||||||
|
define('XML_HTMLSAX3', 'XML/');
|
||||||
|
}
|
||||||
|
require_once(__DIR__ . '/HTMLSax3/States.php');
|
||||||
|
require_once(__DIR__ . '/HTMLSax3/Decorators.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base State Parser
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_StateParser {
|
||||||
|
/**
|
||||||
|
* Instance of user front end class to be passed to callbacks
|
||||||
|
* @var XML_HTMLSax3
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $htmlsax;
|
||||||
|
/**
|
||||||
|
* User defined object for handling elements
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_object_element;
|
||||||
|
/**
|
||||||
|
* User defined open tag handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_method_opening;
|
||||||
|
/**
|
||||||
|
* User defined close tag handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_method_closing;
|
||||||
|
/**
|
||||||
|
* User defined object for handling data in elements
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_object_data;
|
||||||
|
/**
|
||||||
|
* User defined data handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_method_data;
|
||||||
|
/**
|
||||||
|
* User defined object for handling processing instructions
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_object_pi;
|
||||||
|
/**
|
||||||
|
* User defined processing instruction handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_method_pi;
|
||||||
|
/**
|
||||||
|
* User defined object for handling JSP/ASP tags
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_object_jasp;
|
||||||
|
/**
|
||||||
|
* User defined JSP/ASP handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_method_jasp;
|
||||||
|
/**
|
||||||
|
* User defined object for handling XML escapes
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_object_escape;
|
||||||
|
/**
|
||||||
|
* User defined XML escape handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_method_escape;
|
||||||
|
/**
|
||||||
|
* User defined handler object or NullHandler
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $handler_default;
|
||||||
|
/**
|
||||||
|
* Parser options determining parsing behavior
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $parser_options = array();
|
||||||
|
/**
|
||||||
|
* XML document being parsed
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $rawtext;
|
||||||
|
/**
|
||||||
|
* Position in XML document relative to start (0)
|
||||||
|
* @var int
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $position;
|
||||||
|
/**
|
||||||
|
* Length of the XML document in characters
|
||||||
|
* @var int
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $length;
|
||||||
|
/**
|
||||||
|
* Array of state objects
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $State = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_StateParser setting up states
|
||||||
|
* @var XML_HTMLSax3 instance of user front end class
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_StateParser (& $htmlsax) {
|
||||||
|
$this->htmlsax = & $htmlsax;
|
||||||
|
$this->State[XML_HTMLSAX3_STATE_START] =new XML_HTMLSax3_StartingState();
|
||||||
|
|
||||||
|
$this->State[XML_HTMLSAX3_STATE_CLOSING_TAG] =new XML_HTMLSax3_ClosingTagState();
|
||||||
|
$this->State[XML_HTMLSAX3_STATE_TAG] =new XML_HTMLSax3_TagState();
|
||||||
|
$this->State[XML_HTMLSAX3_STATE_OPENING_TAG] =new XML_HTMLSax3_OpeningTagState();
|
||||||
|
|
||||||
|
$this->State[XML_HTMLSAX3_STATE_PI] =new XML_HTMLSax3_PiState();
|
||||||
|
$this->State[XML_HTMLSAX3_STATE_JASP] =new XML_HTMLSax3_JaspState();
|
||||||
|
$this->State[XML_HTMLSAX3_STATE_ESCAPE] =new XML_HTMLSax3_EscapeState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the position back one character
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function unscanCharacter() {
|
||||||
|
$this->position -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the position forward one character
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function ignoreCharacter() {
|
||||||
|
$this->position += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next character from the XML document or void if at end
|
||||||
|
* @access protected
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function scanCharacter() {
|
||||||
|
if ($this->position < $this->length) {
|
||||||
|
return $this->rawtext{$this->position++};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string from the current position to the next occurance
|
||||||
|
* of the supplied string
|
||||||
|
* @param string string to search until
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function scanUntilString($string) {
|
||||||
|
$start = $this->position;
|
||||||
|
$this->position = strpos($this->rawtext, $string, $start);
|
||||||
|
if ($this->position === FALSE) {
|
||||||
|
$this->position = $this->length;
|
||||||
|
}
|
||||||
|
return substr($this->rawtext, $start, $this->position - $start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string from the current position until the first instance of
|
||||||
|
* one of the characters in the supplied string argument
|
||||||
|
* @param string string to search until
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function scanUntilCharacters($string) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the position forward past any whitespace characters
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function ignoreWhitespace() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins the parsing operation, setting up any decorators, depending on
|
||||||
|
* parse options invoking _parse() to execute parsing
|
||||||
|
* @param string XML document to parse
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function parse($data) {
|
||||||
|
if ($this->parser_options['XML_OPTION_TRIM_DATA_NODES']==1) {
|
||||||
|
$decorator =new XML_HTMLSax3_Trim(
|
||||||
|
$this->handler_object_data,
|
||||||
|
$this->handler_method_data);
|
||||||
|
$this->handler_object_data =& $decorator;
|
||||||
|
$this->handler_method_data = 'trimData';
|
||||||
|
}
|
||||||
|
if ($this->parser_options['XML_OPTION_CASE_FOLDING']==1) {
|
||||||
|
$open_decor =new XML_HTMLSax3_CaseFolding(
|
||||||
|
$this->handler_object_element,
|
||||||
|
$this->handler_method_opening,
|
||||||
|
$this->handler_method_closing);
|
||||||
|
$this->handler_object_element =& $open_decor;
|
||||||
|
$this->handler_method_opening ='foldOpen';
|
||||||
|
$this->handler_method_closing ='foldClose';
|
||||||
|
}
|
||||||
|
if ($this->parser_options['XML_OPTION_LINEFEED_BREAK']==1) {
|
||||||
|
$decorator =new XML_HTMLSax3_Linefeed(
|
||||||
|
$this->handler_object_data,
|
||||||
|
$this->handler_method_data);
|
||||||
|
$this->handler_object_data =& $decorator;
|
||||||
|
$this->handler_method_data = 'breakData';
|
||||||
|
}
|
||||||
|
if ($this->parser_options['XML_OPTION_TAB_BREAK']==1) {
|
||||||
|
$decorator =new XML_HTMLSax3_Tab(
|
||||||
|
$this->handler_object_data,
|
||||||
|
$this->handler_method_data);
|
||||||
|
$this->handler_object_data =& $decorator;
|
||||||
|
$this->handler_method_data = 'breakData';
|
||||||
|
}
|
||||||
|
if ($this->parser_options['XML_OPTION_ENTITIES_UNPARSED']==1) {
|
||||||
|
$decorator =new XML_HTMLSax3_Entities_Unparsed(
|
||||||
|
$this->handler_object_data,
|
||||||
|
$this->handler_method_data);
|
||||||
|
$this->handler_object_data =& $decorator;
|
||||||
|
$this->handler_method_data = 'breakData';
|
||||||
|
}
|
||||||
|
if ($this->parser_options['XML_OPTION_ENTITIES_PARSED']==1) {
|
||||||
|
$decorator =new XML_HTMLSax3_Entities_Parsed(
|
||||||
|
$this->handler_object_data,
|
||||||
|
$this->handler_method_data);
|
||||||
|
$this->handler_object_data =& $decorator;
|
||||||
|
$this->handler_method_data = 'breakData';
|
||||||
|
}
|
||||||
|
// Note switched on by default
|
||||||
|
if ($this->parser_options['XML_OPTION_STRIP_ESCAPES']==1) {
|
||||||
|
$decorator =new XML_HTMLSax3_Escape_Stripper(
|
||||||
|
$this->handler_object_escape,
|
||||||
|
$this->handler_method_escape);
|
||||||
|
$this->handler_object_escape =& $decorator;
|
||||||
|
$this->handler_method_escape = 'strip';
|
||||||
|
}
|
||||||
|
$this->rawtext = $data;
|
||||||
|
$this->length = strlen($data);
|
||||||
|
$this->position = 0;
|
||||||
|
$this->_parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the parsing itself, delegating calls to a specific parser
|
||||||
|
* state
|
||||||
|
* @param constant state object to parse with
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function _parse($state = XML_HTMLSAX3_STATE_START) {
|
||||||
|
do {
|
||||||
|
$state = $this->State[$state]->parse($this);
|
||||||
|
} while ($state != XML_HTMLSAX3_STATE_STOP &&
|
||||||
|
$this->position < $this->length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser for PHP Versions below 4.3.0. Uses a slower parsing mechanism than
|
||||||
|
* the equivalent PHP 4.3.0+ subclass of StateParser
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
* @see XML_HTMLSax3_StateParser_Gtet430
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_StateParser_Lt430 extends XML_HTMLSax3_StateParser {
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_StateParser_Lt430 defining available
|
||||||
|
* parser options
|
||||||
|
* @var XML_HTMLSax3 instance of user front end class
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_StateParser_Lt430(& $htmlsax) {
|
||||||
|
parent::XML_HTMLSax3_StateParser($htmlsax);
|
||||||
|
$this->parser_options['XML_OPTION_TRIM_DATA_NODES'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_CASE_FOLDING'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_LINEFEED_BREAK'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_TAB_BREAK'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_ENTITIES_PARSED'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_ENTITIES_UNPARSED'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_STRIP_ESCAPES'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string from the current position until the first instance of
|
||||||
|
* one of the characters in the supplied string argument
|
||||||
|
* @param string string to search until
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function scanUntilCharacters($string) {
|
||||||
|
$startpos = $this->position;
|
||||||
|
while ($this->position < $this->length && strpos($string, $this->rawtext{$this->position}) === FALSE) {
|
||||||
|
$this->position++;
|
||||||
|
}
|
||||||
|
return substr($this->rawtext, $startpos, $this->position - $startpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the position forward past any whitespace characters
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function ignoreWhitespace() {
|
||||||
|
while ($this->position < $this->length &&
|
||||||
|
strpos(" \n\r\t", $this->rawtext{$this->position}) !== FALSE) {
|
||||||
|
$this->position++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins the parsing operation, setting up the unparsed XML entities
|
||||||
|
* decorator if necessary then delegating further work to parent
|
||||||
|
* @param string XML document to parse
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function parse($data) {
|
||||||
|
parent::parse($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser for PHP Versions equal to or greater than 4.3.0. Uses a faster
|
||||||
|
* parsing mechanism than the equivalent PHP < 4.3.0 subclass of StateParser
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
* @see XML_HTMLSax3_StateParser_Lt430
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_StateParser_Gtet430 extends XML_HTMLSax3_StateParser {
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_StateParser_Gtet430 defining available
|
||||||
|
* parser options
|
||||||
|
* @var XML_HTMLSax3 instance of user front end class
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_StateParser_Gtet430(& $htmlsax) {
|
||||||
|
parent::XML_HTMLSax3_StateParser($htmlsax);
|
||||||
|
$this->parser_options['XML_OPTION_TRIM_DATA_NODES'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_CASE_FOLDING'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_LINEFEED_BREAK'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_TAB_BREAK'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_ENTITIES_PARSED'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_ENTITIES_UNPARSED'] = 0;
|
||||||
|
$this->parser_options['XML_OPTION_STRIP_ESCAPES'] = 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a string from the current position until the first instance of
|
||||||
|
* one of the characters in the supplied string argument.
|
||||||
|
* @param string string to search until
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function scanUntilCharacters($string) {
|
||||||
|
$startpos = $this->position;
|
||||||
|
$length = strcspn($this->rawtext, $string, $startpos);
|
||||||
|
$this->position += $length;
|
||||||
|
return substr($this->rawtext, $startpos, $length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the position forward past any whitespace characters
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function ignoreWhitespace() {
|
||||||
|
$this->position += strspn($this->rawtext, " \n\r\t", $this->position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins the parsing operation, setting up the parsed and unparsed
|
||||||
|
* XML entity decorators if necessary then delegating further work
|
||||||
|
* to parent
|
||||||
|
* @param string XML document to parse
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function parse($data) {
|
||||||
|
parent::parse($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default NullHandler for methods which were not set by user
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_NullHandler {
|
||||||
|
/**
|
||||||
|
* Generic handler method which does nothing
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function DoNothing() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User interface class. All user calls should only be made to this class
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3 {
|
||||||
|
/**
|
||||||
|
* Instance of concrete subclass of XML_HTMLSax3_StateParser
|
||||||
|
* @var XML_HTMLSax3_StateParser
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $state_parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3 selecting concrete StateParser subclass
|
||||||
|
* depending on PHP version being used as well as setting the default
|
||||||
|
* NullHandler for all callbacks<br />
|
||||||
|
* <b>Example:</b>
|
||||||
|
* <pre>
|
||||||
|
* $myHandler = new MyHandler();
|
||||||
|
* $parser = new XML_HTMLSax3();
|
||||||
|
* $parser->set_object($myHandler);
|
||||||
|
* $parser->set_option('XML_OPTION_CASE_FOLDING');
|
||||||
|
* $parser->set_element_handler('myOpenHandler','myCloseHandler');
|
||||||
|
* $parser->set_data_handler('myDataHandler');
|
||||||
|
* $parser->parser($xml);
|
||||||
|
* </pre>
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3() {
|
||||||
|
if (version_compare(phpversion(), '4.3', 'ge')) {
|
||||||
|
$this->state_parser =new XML_HTMLSax3_StateParser_Gtet430($this);
|
||||||
|
} else {
|
||||||
|
$this->state_parser =new XML_HTMLSax3_StateParser_Lt430($this);
|
||||||
|
}
|
||||||
|
$nullhandler =new XML_HTMLSax3_NullHandler();
|
||||||
|
$this->set_object($nullhandler);
|
||||||
|
$this->set_element_handler('DoNothing', 'DoNothing');
|
||||||
|
$this->set_data_handler('DoNothing');
|
||||||
|
$this->set_pi_handler('DoNothing');
|
||||||
|
$this->set_jasp_handler('DoNothing');
|
||||||
|
$this->set_escape_handler('DoNothing');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the user defined handler object. Returns a PEAR Error
|
||||||
|
* if supplied argument is not an object.
|
||||||
|
* @param object handler object containing SAX callback methods
|
||||||
|
* @access public
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function set_object(&$object) {
|
||||||
|
if ( is_object($object) ) {
|
||||||
|
$this->state_parser->handler_default =& $object;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
require_once('PEAR.php');
|
||||||
|
PEAR::raiseError('XML_HTMLSax3::set_object requires '.
|
||||||
|
'an object instance');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a parser option. By default all options are switched off.
|
||||||
|
* Returns a PEAR Error if option is invalid<br />
|
||||||
|
* <b>Available options:</b>
|
||||||
|
* <ul>
|
||||||
|
* <li>XML_OPTION_TRIM_DATA_NODES: trim whitespace off the beginning
|
||||||
|
* and end of data passed to the data handler</li>
|
||||||
|
* <li>XML_OPTION_LINEFEED_BREAK: linefeeds result in additional data
|
||||||
|
* handler calls</li>
|
||||||
|
* <li>XML_OPTION_TAB_BREAK: tabs result in additional data handler
|
||||||
|
* calls</li>
|
||||||
|
* <li>XML_OPTION_ENTITIES_UNPARSED: XML entities are returned as
|
||||||
|
* seperate data handler calls in unparsed form</li>
|
||||||
|
* <li>XML_OPTION_ENTITIES_PARSED: (PHP 4.3.0+ only) XML entities are
|
||||||
|
* returned as seperate data handler calls and are parsed with
|
||||||
|
* PHP's html_entity_decode() function</li>
|
||||||
|
* <li>XML_OPTION_STRIP_ESCAPES: strips out the -- -- comment markers
|
||||||
|
* or CDATA markup inside an XML escape, if found.</li>
|
||||||
|
* </ul>
|
||||||
|
* To get HTMLSax to behave in the same way as the native PHP SAX parser,
|
||||||
|
* using it's default state, you need to switch on XML_OPTION_LINEFEED_BREAK,
|
||||||
|
* XML_OPTION_ENTITIES_PARSED and XML_OPTION_CASE_FOLDING
|
||||||
|
* @param string name of parser option
|
||||||
|
* @param int (optional) 1 to switch on, 0 for off
|
||||||
|
* @access public
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
function set_option($name, $value=1) {
|
||||||
|
if ( array_key_exists($name,$this->state_parser->parser_options) ) {
|
||||||
|
$this->state_parser->parser_options[$name] = $value;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
require_once('PEAR.php');
|
||||||
|
PEAR::raiseError('XML_HTMLSax3::set_option('.$name.') illegal');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the data handler method which deals with the contents of XML
|
||||||
|
* elements.<br />
|
||||||
|
* The handler method must accept two arguments, the first being an
|
||||||
|
* instance of XML_HTMLSax3 and the second being the contents of an
|
||||||
|
* XML element e.g.
|
||||||
|
* <pre>
|
||||||
|
* function myDataHander(& $parser,$data){}
|
||||||
|
* </pre>
|
||||||
|
* @param string name of method
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
* @see set_object
|
||||||
|
*/
|
||||||
|
function set_data_handler($data_method) {
|
||||||
|
$this->state_parser->handler_object_data =& $this->state_parser->handler_default;
|
||||||
|
$this->state_parser->handler_method_data = $data_method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the open and close tag handlers
|
||||||
|
* <br />The open handler method must accept three arguments; the parser,
|
||||||
|
* the tag name and an array of attributes e.g.
|
||||||
|
* <pre>
|
||||||
|
* function myOpenHander(& $parser,$tagname,$attrs=array()){}
|
||||||
|
* </pre>
|
||||||
|
* The close handler method must accept two arguments; the parser and
|
||||||
|
* the tag name e.g.
|
||||||
|
* <pre>
|
||||||
|
* function myCloseHander(& $parser,$tagname){}
|
||||||
|
* </pre>
|
||||||
|
* @param string name of open method
|
||||||
|
* @param string name of close method
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
* @see set_object
|
||||||
|
*/
|
||||||
|
function set_element_handler($opening_method, $closing_method) {
|
||||||
|
$this->state_parser->handler_object_element =& $this->state_parser->handler_default;
|
||||||
|
$this->state_parser->handler_method_opening = $opening_method;
|
||||||
|
$this->state_parser->handler_method_closing = $closing_method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the processing instruction handler method e.g. for PHP open
|
||||||
|
* and close tags<br />
|
||||||
|
* The handler method must accept three arguments; the parser, the
|
||||||
|
* PI target and data inside the PI
|
||||||
|
* <pre>
|
||||||
|
* function myPIHander(& $parser,$target, $data){}
|
||||||
|
* </pre>
|
||||||
|
* @param string name of method
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
* @see set_object
|
||||||
|
*/
|
||||||
|
function set_pi_handler($pi_method) {
|
||||||
|
$this->state_parser->handler_object_pi =& $this->state_parser->handler_default;
|
||||||
|
$this->state_parser->handler_method_pi = $pi_method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the XML escape handler method e.g. for comments and doctype
|
||||||
|
* declarations<br />
|
||||||
|
* The handler method must accept two arguments; the parser and the
|
||||||
|
* contents of the escaped section
|
||||||
|
* <pre>
|
||||||
|
* function myEscapeHander(& $parser, $data){}
|
||||||
|
* </pre>
|
||||||
|
* @param string name of method
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
* @see set_object
|
||||||
|
*/
|
||||||
|
function set_escape_handler($escape_method) {
|
||||||
|
$this->state_parser->handler_object_escape =& $this->state_parser->handler_default;
|
||||||
|
$this->state_parser->handler_method_escape = $escape_method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the JSP/ASP markup handler<br />
|
||||||
|
* The handler method must accept two arguments; the parser and
|
||||||
|
* body of the JASP tag
|
||||||
|
* <pre>
|
||||||
|
* function myJaspHander(& $parser, $data){}
|
||||||
|
* </pre>
|
||||||
|
* @param string name of method
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
* @see set_object
|
||||||
|
*/
|
||||||
|
function set_jasp_handler ($jasp_method) {
|
||||||
|
$this->state_parser->handler_object_jasp =& $this->state_parser->handler_default;
|
||||||
|
$this->state_parser->handler_method_jasp = $jasp_method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current string position of the "cursor" inside the XML
|
||||||
|
* document
|
||||||
|
* <br />Intended for use from within a user defined handler called
|
||||||
|
* via the $parser reference e.g.
|
||||||
|
* <pre>
|
||||||
|
* function myDataHandler(& $parser,$data) {
|
||||||
|
* echo( 'Current position: '.$parser->get_current_position() );
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* @access public
|
||||||
|
* @return int
|
||||||
|
* @see get_length
|
||||||
|
*/
|
||||||
|
function get_current_position() {
|
||||||
|
return $this->state_parser->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string length of the XML document being parsed
|
||||||
|
* @access public
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
function get_length() {
|
||||||
|
return $this->state_parser->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start parsing some XML
|
||||||
|
* @param string XML document
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function parse($data) {
|
||||||
|
$this->state_parser->parse($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
363
engine/lib/XML/HTMLSax3/Decorators.php
Normal file
363
engine/lib/XML/HTMLSax3/Decorators.php
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
//
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2002 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject toversion 3.0 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/3_0.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Authors: Alexander Zhukov <alex@veresk.ru> Original port from Python |
|
||||||
|
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> Port to PEAR + more |
|
||||||
|
// | Authors: Many @ Sitepointforums Advanced PHP Forums |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: Decorators.php,v 1.2 2007/10/29 21:41:35 hfuecks Exp $
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* Decorators for dealing with parser options
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @version $Id: Decorators.php,v 1.2 2007/10/29 21:41:35 hfuecks Exp $
|
||||||
|
* @see XML_HTMLSax3::set_option
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Trims the contents of element data from whitespace at start and end
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_Trim {
|
||||||
|
/**
|
||||||
|
* Original handler object
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_obj;
|
||||||
|
/**
|
||||||
|
* Original handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_method;
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_Trim
|
||||||
|
* @param object handler object being decorated
|
||||||
|
* @param string original handler method
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_Trim(&$orig_obj, $orig_method) {
|
||||||
|
$this->orig_obj =& $orig_obj;
|
||||||
|
$this->orig_method = $orig_method;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Trims the data
|
||||||
|
* @param XML_HTMLSax3
|
||||||
|
* @param string element data
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function trimData(&$parser, $data) {
|
||||||
|
$data = trim($data);
|
||||||
|
if ($data != '') {
|
||||||
|
$this->orig_obj->{$this->orig_method}($parser, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Coverts tag names to upper case
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_CaseFolding {
|
||||||
|
/**
|
||||||
|
* Original handler object
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_obj;
|
||||||
|
/**
|
||||||
|
* Original open handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_open_method;
|
||||||
|
/**
|
||||||
|
* Original close handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_close_method;
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_CaseFolding
|
||||||
|
* @param object handler object being decorated
|
||||||
|
* @param string original open handler method
|
||||||
|
* @param string original close handler method
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_CaseFolding(&$orig_obj, $orig_open_method, $orig_close_method) {
|
||||||
|
$this->orig_obj =& $orig_obj;
|
||||||
|
$this->orig_open_method = $orig_open_method;
|
||||||
|
$this->orig_close_method = $orig_close_method;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Folds up open tag callbacks
|
||||||
|
* @param XML_HTMLSax3
|
||||||
|
* @param string tag name
|
||||||
|
* @param array tag attributes
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function foldOpen(&$parser, $tag, $attrs=array(), $empty = FALSE) {
|
||||||
|
$this->orig_obj->{$this->orig_open_method}($parser, strtoupper($tag), $attrs, $empty);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Folds up close tag callbacks
|
||||||
|
* @param XML_HTMLSax3
|
||||||
|
* @param string tag name
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function foldClose(&$parser, $tag, $empty = FALSE) {
|
||||||
|
$this->orig_obj->{$this->orig_close_method}($parser, strtoupper($tag), $empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Breaks up data by linefeed characters, resulting in additional
|
||||||
|
* calls to the data handler
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_Linefeed {
|
||||||
|
/**
|
||||||
|
* Original handler object
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_obj;
|
||||||
|
/**
|
||||||
|
* Original handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_method;
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_LineFeed
|
||||||
|
* @param object handler object being decorated
|
||||||
|
* @param string original handler method
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_LineFeed(&$orig_obj, $orig_method) {
|
||||||
|
$this->orig_obj =& $orig_obj;
|
||||||
|
$this->orig_method = $orig_method;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Breaks the data up by linefeeds
|
||||||
|
* @param XML_HTMLSax3
|
||||||
|
* @param string element data
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function breakData(&$parser, $data) {
|
||||||
|
$data = explode("\n",$data);
|
||||||
|
foreach ( $data as $chunk ) {
|
||||||
|
$this->orig_obj->{$this->orig_method}($parser, $chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Breaks up data by tab characters, resulting in additional
|
||||||
|
* calls to the data handler
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_Tab {
|
||||||
|
/**
|
||||||
|
* Original handler object
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_obj;
|
||||||
|
/**
|
||||||
|
* Original handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_method;
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_Tab
|
||||||
|
* @param object handler object being decorated
|
||||||
|
* @param string original handler method
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_Tab(&$orig_obj, $orig_method) {
|
||||||
|
$this->orig_obj =& $orig_obj;
|
||||||
|
$this->orig_method = $orig_method;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Breaks the data up by linefeeds
|
||||||
|
* @param XML_HTMLSax3
|
||||||
|
* @param string element data
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function breakData(&$parser, $data) {
|
||||||
|
$data = explode("\t",$data);
|
||||||
|
foreach ( $data as $chunk ) {
|
||||||
|
$this->orig_obj->{$this->orig_method}($this, $chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Breaks up data by XML entities and parses them with html_entity_decode(),
|
||||||
|
* resulting in additional calls to the data handler<br />
|
||||||
|
* Requires PHP 4.3.0+
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_Entities_Parsed {
|
||||||
|
/**
|
||||||
|
* Original handler object
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_obj;
|
||||||
|
/**
|
||||||
|
* Original handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_method;
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_Entities_Parsed
|
||||||
|
* @param object handler object being decorated
|
||||||
|
* @param string original handler method
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_Entities_Parsed(&$orig_obj, $orig_method) {
|
||||||
|
$this->orig_obj =& $orig_obj;
|
||||||
|
$this->orig_method = $orig_method;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Breaks the data up by XML entities
|
||||||
|
* @param XML_HTMLSax3
|
||||||
|
* @param string element data
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function breakData(&$parser, $data) {
|
||||||
|
$data = preg_split('/(&.+?;)/',$data,-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||||
|
foreach ( $data as $chunk ) {
|
||||||
|
$chunk = html_entity_decode($chunk,ENT_NOQUOTES);
|
||||||
|
$this->orig_obj->{$this->orig_method}($this, $chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Compatibility with older PHP versions
|
||||||
|
*/
|
||||||
|
if (version_compare(phpversion(), '4.3', '<') && !function_exists('html_entity_decode') ) {
|
||||||
|
function html_entity_decode($str, $style=ENT_NOQUOTES) {
|
||||||
|
return strtr($str,
|
||||||
|
array_flip(get_html_translation_table(HTML_ENTITIES,$style)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Breaks up data by XML entities but leaves them unparsed,
|
||||||
|
* resulting in additional calls to the data handler<br />
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_Entities_Unparsed {
|
||||||
|
/**
|
||||||
|
* Original handler object
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_obj;
|
||||||
|
/**
|
||||||
|
* Original handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_method;
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_Entities_Unparsed
|
||||||
|
* @param object handler object being decorated
|
||||||
|
* @param string original handler method
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_Entities_Unparsed(&$orig_obj, $orig_method) {
|
||||||
|
$this->orig_obj =& $orig_obj;
|
||||||
|
$this->orig_method = $orig_method;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Breaks the data up by XML entities
|
||||||
|
* @param XML_HTMLSax3
|
||||||
|
* @param string element data
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function breakData(&$parser, $data) {
|
||||||
|
$data = preg_split('/(&.+?;)/',$data,-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||||
|
foreach ( $data as $chunk ) {
|
||||||
|
$this->orig_obj->{$this->orig_method}($this, $chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strips the HTML comment markers or CDATA sections from an escape.
|
||||||
|
* If XML_OPTIONS_FULL_ESCAPES is on, this decorator is not used.<br />
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_Escape_Stripper {
|
||||||
|
/**
|
||||||
|
* Original handler object
|
||||||
|
* @var object
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_obj;
|
||||||
|
/**
|
||||||
|
* Original handler method
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $orig_method;
|
||||||
|
/**
|
||||||
|
* Constructs XML_HTMLSax3_Entities_Unparsed
|
||||||
|
* @param object handler object being decorated
|
||||||
|
* @param string original handler method
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function XML_HTMLSax3_Escape_Stripper(&$orig_obj, $orig_method) {
|
||||||
|
$this->orig_obj =& $orig_obj;
|
||||||
|
$this->orig_method = $orig_method;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Breaks the data up by XML entities
|
||||||
|
* @param XML_HTMLSax3
|
||||||
|
* @param string element data
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function strip(&$parser, $data) {
|
||||||
|
// Check for HTML comments first
|
||||||
|
if ( substr($data,0,2) == '--' ) {
|
||||||
|
$patterns = array(
|
||||||
|
'/^\-\-/', // Opening comment: --
|
||||||
|
'/\-\-$/', // Closing comment: --
|
||||||
|
);
|
||||||
|
$data = preg_replace($patterns,'',$data);
|
||||||
|
|
||||||
|
// Check for XML CDATA sections (note: don't do both!)
|
||||||
|
} else if ( substr($data,0,1) == '[' ) {
|
||||||
|
$patterns = array(
|
||||||
|
'/^\[.*CDATA.*\[/s', // Opening CDATA
|
||||||
|
'/\].*\]$/s', // Closing CDATA
|
||||||
|
);
|
||||||
|
$data = preg_replace($patterns,'',$data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->orig_obj->{$this->orig_method}($this, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
287
engine/lib/XML/HTMLSax3/States.php
Normal file
287
engine/lib/XML/HTMLSax3/States.php
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
//
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2002 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject toversion 3.0 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/3_0.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Authors: Alexander Zhukov <alex@veresk.ru> Original port from Python |
|
||||||
|
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> Port to PEAR + more |
|
||||||
|
// | Authors: Many @ Sitepointforums Advanced PHP Forums |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: States.php,v 1.3 2007/10/29 21:41:35 hfuecks Exp $
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* Parsing states.
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @version $Id: States.php,v 1.3 2007/10/29 21:41:35 hfuecks Exp $
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Define parser states
|
||||||
|
*/
|
||||||
|
define('XML_HTMLSAX3_STATE_STOP', 0);
|
||||||
|
define('XML_HTMLSAX3_STATE_START', 1);
|
||||||
|
define('XML_HTMLSAX3_STATE_TAG', 2);
|
||||||
|
define('XML_HTMLSAX3_STATE_OPENING_TAG', 3);
|
||||||
|
define('XML_HTMLSAX3_STATE_CLOSING_TAG', 4);
|
||||||
|
define('XML_HTMLSAX3_STATE_ESCAPE', 6);
|
||||||
|
define('XML_HTMLSAX3_STATE_JASP', 7);
|
||||||
|
define('XML_HTMLSAX3_STATE_PI', 8);
|
||||||
|
/**
|
||||||
|
* StartingState searches for the start of any XML tag
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_StartingState {
|
||||||
|
/**
|
||||||
|
* @param XML_HTMLSax3_StateParser subclass
|
||||||
|
* @return constant XML_HTMLSAX3_STATE_TAG
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function parse(&$context) {
|
||||||
|
$data = $context->scanUntilString('<');
|
||||||
|
if ($data != '') {
|
||||||
|
$context->handler_object_data->
|
||||||
|
{$context->handler_method_data}($context->htmlsax, $data);
|
||||||
|
}
|
||||||
|
$context->IgnoreCharacter();
|
||||||
|
return XML_HTMLSAX3_STATE_TAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Decides which state to move one from after StartingState
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_TagState {
|
||||||
|
/**
|
||||||
|
* @param XML_HTMLSax3_StateParser subclass
|
||||||
|
* @return constant the next state to move into
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function parse(&$context) {
|
||||||
|
switch($context->ScanCharacter()) {
|
||||||
|
case '/':
|
||||||
|
return XML_HTMLSAX3_STATE_CLOSING_TAG;
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
return XML_HTMLSAX3_STATE_PI;
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
return XML_HTMLSAX3_STATE_JASP;
|
||||||
|
break;
|
||||||
|
case '!':
|
||||||
|
return XML_HTMLSAX3_STATE_ESCAPE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$context->unscanCharacter();
|
||||||
|
return XML_HTMLSAX3_STATE_OPENING_TAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Dealing with closing XML tags
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_ClosingTagState {
|
||||||
|
/**
|
||||||
|
* @param XML_HTMLSax3_StateParser subclass
|
||||||
|
* @return constant XML_HTMLSAX3_STATE_START
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function parse(&$context) {
|
||||||
|
$tag = $context->scanUntilCharacters('/>');
|
||||||
|
if ($tag != '') {
|
||||||
|
$char = $context->scanCharacter();
|
||||||
|
if ($char == '/') {
|
||||||
|
$char = $context->scanCharacter();
|
||||||
|
if ($char != '>') {
|
||||||
|
$context->unscanCharacter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$context->handler_object_element->
|
||||||
|
{$context->handler_method_closing}($context->htmlsax, $tag, FALSE);
|
||||||
|
}
|
||||||
|
return XML_HTMLSAX3_STATE_START;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Dealing with opening XML tags
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_OpeningTagState {
|
||||||
|
/**
|
||||||
|
* Handles attributes
|
||||||
|
* @param string attribute name
|
||||||
|
* @param string attribute value
|
||||||
|
* @return void
|
||||||
|
* @access protected
|
||||||
|
* @see XML_HTMLSax3_AttributeStartState
|
||||||
|
*/
|
||||||
|
function parseAttributes(&$context) {
|
||||||
|
$Attributes = array();
|
||||||
|
|
||||||
|
$context->ignoreWhitespace();
|
||||||
|
$attributename = $context->scanUntilCharacters("=/> \n\r\t");
|
||||||
|
while ($attributename != '') {
|
||||||
|
$attributevalue = NULL;
|
||||||
|
$context->ignoreWhitespace();
|
||||||
|
$char = $context->scanCharacter();
|
||||||
|
if ($char == '=') {
|
||||||
|
$context->ignoreWhitespace();
|
||||||
|
$char = $context->ScanCharacter();
|
||||||
|
if ($char == '"') {
|
||||||
|
$attributevalue= $context->scanUntilString('"');
|
||||||
|
$context->IgnoreCharacter();
|
||||||
|
} else if ($char == "'") {
|
||||||
|
$attributevalue = $context->scanUntilString("'");
|
||||||
|
$context->IgnoreCharacter();
|
||||||
|
} else {
|
||||||
|
$context->unscanCharacter();
|
||||||
|
$attributevalue =
|
||||||
|
$context->scanUntilCharacters("> \n\r\t");
|
||||||
|
}
|
||||||
|
} else if ($char !== NULL) {
|
||||||
|
$attributevalue = NULL;
|
||||||
|
$context->unscanCharacter();
|
||||||
|
}
|
||||||
|
$Attributes[$attributename] = $attributevalue;
|
||||||
|
|
||||||
|
$context->ignoreWhitespace();
|
||||||
|
$attributename = $context->scanUntilCharacters("=/> \n\r\t");
|
||||||
|
}
|
||||||
|
return $Attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param XML_HTMLSax3_StateParser subclass
|
||||||
|
* @return constant XML_HTMLSAX3_STATE_START
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function parse(&$context) {
|
||||||
|
$tag = $context->scanUntilCharacters("/> \n\r\t");
|
||||||
|
if ($tag != '') {
|
||||||
|
$this->attrs = array();
|
||||||
|
$Attributes = $this->parseAttributes($context);
|
||||||
|
$char = $context->scanCharacter();
|
||||||
|
if ($char == '/') {
|
||||||
|
$char = $context->scanCharacter();
|
||||||
|
if ($char != '>') {
|
||||||
|
$context->unscanCharacter();
|
||||||
|
}
|
||||||
|
$context->handler_object_element->
|
||||||
|
{$context->handler_method_opening}($context->htmlsax, $tag,
|
||||||
|
$Attributes, TRUE);
|
||||||
|
$context->handler_object_element->
|
||||||
|
{$context->handler_method_closing}($context->htmlsax, $tag,
|
||||||
|
TRUE);
|
||||||
|
} else {
|
||||||
|
$context->handler_object_element->
|
||||||
|
{$context->handler_method_opening}($context->htmlsax, $tag,
|
||||||
|
$Attributes, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return XML_HTMLSAX3_STATE_START;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deals with XML escapes handling comments and CDATA correctly
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_EscapeState {
|
||||||
|
/**
|
||||||
|
* @param XML_HTMLSax3_StateParser subclass
|
||||||
|
* @return constant XML_HTMLSAX3_STATE_START
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function parse(&$context) {
|
||||||
|
$char = $context->ScanCharacter();
|
||||||
|
if ($char == '-') {
|
||||||
|
$char = $context->ScanCharacter();
|
||||||
|
if ($char == '-') {
|
||||||
|
$context->unscanCharacter();
|
||||||
|
$context->unscanCharacter();
|
||||||
|
$text = $context->scanUntilString('-->');
|
||||||
|
$text .= $context->scanCharacter();
|
||||||
|
$text .= $context->scanCharacter();
|
||||||
|
} else {
|
||||||
|
$context->unscanCharacter();
|
||||||
|
$text = $context->scanUntilString('>');
|
||||||
|
}
|
||||||
|
} else if ( $char == '[') {
|
||||||
|
$context->unscanCharacter();
|
||||||
|
$text = $context->scanUntilString(']>');
|
||||||
|
$text.= $context->scanCharacter();
|
||||||
|
} else {
|
||||||
|
$context->unscanCharacter();
|
||||||
|
$text = $context->scanUntilString('>');
|
||||||
|
}
|
||||||
|
|
||||||
|
$context->IgnoreCharacter();
|
||||||
|
if ($text != '') {
|
||||||
|
$context->handler_object_escape->
|
||||||
|
{$context->handler_method_escape}($context->htmlsax, $text);
|
||||||
|
}
|
||||||
|
return XML_HTMLSAX3_STATE_START;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Deals with JASP/ASP markup
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_JaspState {
|
||||||
|
/**
|
||||||
|
* @param XML_HTMLSax3_StateParser subclass
|
||||||
|
* @return constant XML_HTMLSAX3_STATE_START
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function parse(&$context) {
|
||||||
|
$text = $context->scanUntilString('%>');
|
||||||
|
if ($text != '') {
|
||||||
|
$context->handler_object_jasp->
|
||||||
|
{$context->handler_method_jasp}($context->htmlsax, $text);
|
||||||
|
}
|
||||||
|
$context->IgnoreCharacter();
|
||||||
|
$context->IgnoreCharacter();
|
||||||
|
return XML_HTMLSAX3_STATE_START;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Deals with XML processing instructions
|
||||||
|
* @package XML_HTMLSax3
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
class XML_HTMLSax3_PiState {
|
||||||
|
/**
|
||||||
|
* @param XML_HTMLSax3_StateParser subclass
|
||||||
|
* @return constant XML_HTMLSAX3_STATE_START
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function parse(&$context) {
|
||||||
|
$target = $context->scanUntilCharacters(" \n\r\t");
|
||||||
|
$data = $context->scanUntilString('?>');
|
||||||
|
if ($data != '') {
|
||||||
|
$context->handler_object_pi->
|
||||||
|
{$context->handler_method_pi}($context->htmlsax, $target, $data);
|
||||||
|
}
|
||||||
|
$context->IgnoreCharacter();
|
||||||
|
$context->IgnoreCharacter();
|
||||||
|
return XML_HTMLSAX3_STATE_START;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
140
engine/lib/core.function.php
Executable file
140
engine/lib/core.function.php
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
<?php
|
||||||
|
/*文件扩展名说明
|
||||||
|
*7173 gif *255216 jpg *13780 png *6677 bmp *239187 txt,aspx,asp,sql *208207 xls.doc.ppt *6063 xml *6033 htm,html *4742 js
|
||||||
|
*8075 xlsx,zip,pptx,mmap,zip *8297 rar *01 accdb,mdb *7790 exe,dll *5666 psd *255254 rdp *10056 bt种子 *64101 bat
|
||||||
|
*/
|
||||||
|
function getFileType( $file ){
|
||||||
|
$fp = fopen($file, "rb");
|
||||||
|
$bin = fread($fp, 2); //只读2字节
|
||||||
|
fclose($fp);
|
||||||
|
$str_info = @unpack("C2chars", $bin);
|
||||||
|
$type_code = intval($str_info['chars1'].$str_info['chars2']);
|
||||||
|
$file_type = '';
|
||||||
|
switch ($type_code) {
|
||||||
|
case 239187:
|
||||||
|
$file_type = 'txt';
|
||||||
|
break;
|
||||||
|
case 7784:
|
||||||
|
$file_type = 'midi';
|
||||||
|
break;
|
||||||
|
case 8075:
|
||||||
|
$file_type = 'zip';
|
||||||
|
break;
|
||||||
|
case 8297:
|
||||||
|
$file_type = 'rar';
|
||||||
|
break;
|
||||||
|
case 255216:
|
||||||
|
$file_type = 'jpg';
|
||||||
|
break;
|
||||||
|
case 7173:
|
||||||
|
$file_type = 'gif';
|
||||||
|
break;
|
||||||
|
case 6677:
|
||||||
|
$file_type = 'bmp';
|
||||||
|
break;
|
||||||
|
case 13780:
|
||||||
|
$file_type = 'png';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$file_type = 'unknown';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $file_type;
|
||||||
|
}
|
||||||
|
function isAjax(){
|
||||||
|
if( isset( $GLOBALS['__isAjax'] ) ){
|
||||||
|
return $GLOBALS['__isAjax'];
|
||||||
|
}
|
||||||
|
$headers = apache_request_headers();
|
||||||
|
$GLOBALS['__isAjax'] = (isset( $headers['X-Requested-With'] ) && ( $headers['X-Requested-With'] == 'XMLHttpRequest' )) || (isset( $headers['x-requested-with'] ) && ($headers['x-requested-with'] == 'XMLHttpRequest' ));
|
||||||
|
return $GLOBALS['__isAjax'];
|
||||||
|
}
|
||||||
|
function c( $name ){
|
||||||
|
if( !isset( $GLOBALS['__config'] ) ){
|
||||||
|
$__config = NULL;
|
||||||
|
include( ENGINE.'config/core.config.php' );
|
||||||
|
include( ROOT.'config/app.config.php' );
|
||||||
|
$GLOBALS['__config'] = $__config;
|
||||||
|
}
|
||||||
|
if( isset( $GLOBALS['__config'][$name] ) ){
|
||||||
|
return $GLOBALS['__config'][$name];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function db(){
|
||||||
|
if( !$GLOBALS['__db'] ){
|
||||||
|
$GLOBALS['__db'] = new Db();
|
||||||
|
}
|
||||||
|
return $GLOBALS['__db'];
|
||||||
|
}
|
||||||
|
function get_ip() {
|
||||||
|
if (isSet($_SERVER)) {
|
||||||
|
if (isSet($_SERVER["HTTP_X_FORWARDED_FOR"])) {
|
||||||
|
$realip = $_SERVER["HTTP_X_FORWARDED_FOR"];
|
||||||
|
} elseif (isSet($_SERVER["HTTP_CLIENT_IP"])) {
|
||||||
|
$realip = $_SERVER["HTTP_CLIENT_IP"];
|
||||||
|
} else {
|
||||||
|
$realip = $_SERVER["REMOTE_ADDR"];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( getenv( 'HTTP_X_FORWARDED_FOR' ) ) {
|
||||||
|
$realip = getenv( 'HTTP_X_FORWARDED_FOR' );
|
||||||
|
} elseif ( getenv( 'HTTP_CLIENT_IP' ) ) {
|
||||||
|
$realip = getenv( 'HTTP_CLIENT_IP' );
|
||||||
|
} else {
|
||||||
|
$realip = getenv( 'REMOTE_ADDR' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return current( explode(',' , $realip ) );
|
||||||
|
}
|
||||||
|
function v( $str ){
|
||||||
|
return getDataFromArray( $str , $_REQUEST );
|
||||||
|
}
|
||||||
|
function p( $str ){
|
||||||
|
return getDataFromArray( $str , $_POST );
|
||||||
|
}
|
||||||
|
function getDataFromArray( $array , $data ){
|
||||||
|
if( is_array( $array ) ){
|
||||||
|
$return = array();
|
||||||
|
foreach( $array as $v ){
|
||||||
|
if( isset( $data[$v] ) && $data[$v] !== '' ){
|
||||||
|
$return[trim($v)] = $data[$v];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
return isset( $data[$array] )?$data[$array]:false;
|
||||||
|
}
|
||||||
|
function render( $data , $__showPage = NULL , $layout = NULL , $layoutTpl = true ){
|
||||||
|
$__showPage = strtolower( $__showPage);
|
||||||
|
if( $layout == NULL ){
|
||||||
|
$layout = 'default';
|
||||||
|
}
|
||||||
|
if( isAjax() ){
|
||||||
|
$requiteFile = ROOT.'themes/'.$layout.'/ajax/'.$__showPage.'.tpl.html';
|
||||||
|
}else{
|
||||||
|
$requiteFile = ROOT.'themes/'.$layout.'/'.($layoutTpl?'layout':$__showPage).'.tpl.html';
|
||||||
|
}
|
||||||
|
if( !is_file( $requiteFile ) ){
|
||||||
|
die('can\'t load themes '.$__showPage.' files ');
|
||||||
|
}
|
||||||
|
@extract( $data );
|
||||||
|
require( $requiteFile );
|
||||||
|
}
|
||||||
|
if(!function_exists('apache_request_headers')) {
|
||||||
|
function apache_request_headers(){
|
||||||
|
foreach($_SERVER as $key=>$value){
|
||||||
|
if (substr($key,0,5)=="HTTP_") {
|
||||||
|
$key=str_replace(" ","-",ucwords(strtolower(str_replace("_"," ",substr($key,5)))));
|
||||||
|
$out[$key]=$value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function safeUrlString( $str ){
|
||||||
|
$str = urldecode($str);
|
||||||
|
return str_replace( array( '.' , '/' ) , array() , $str );
|
||||||
|
}
|
29
index.php
Normal file
29
index.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
define( 'IN' , true );
|
||||||
|
define( 'ROOT' , dirname( __FILE__ ) . '/' );
|
||||||
|
|
||||||
|
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
|
||||||
|
error_reporting( E_ALL^E_NOTICE );
|
||||||
|
include_once( ROOT . 'engine/init.inc.php' );
|
||||||
|
session_cache_limiter('private, must-revalidate');
|
||||||
|
session_set_cookie_params( 60*60*24*1 ); //1day
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if( !isAjax() ){
|
||||||
|
header("content-Type: text/html; charset=Utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = safeUrlString($_REQUEST['c']?:c('default_class'));
|
||||||
|
$method = $_REQUEST['m']?:c('default_method');
|
||||||
|
$controllersFile = ROOT.'controllers/'.$class.'.class.php';
|
||||||
|
if( !is_file( $controllersFile ) ){
|
||||||
|
die( "can't find controller file " );
|
||||||
|
}else{
|
||||||
|
include_once( $controllersFile );
|
||||||
|
if( !class_exists( $class ) ) die('Error Can\'t find class' );
|
||||||
|
if( !method_exists( $class , $method ) ) die('Error Can\'t find method ' );
|
||||||
|
$class = new $class;
|
||||||
|
}
|
||||||
|
//print_r( $_SERVER );
|
||||||
|
call_user_func(array($class, $method ));
|
||||||
|
?>
|
750
js/core.js
Executable file
750
js/core.js
Executable file
@ -0,0 +1,750 @@
|
|||||||
|
var TEMP = {};
|
||||||
|
TEMP.MESSAGE = '<div class="FB_boxBg"><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td><div class="content okBg">{message}</div></td></tr></tbody></table></div>';
|
||||||
|
//normal function for apps
|
||||||
|
|
||||||
|
function afterAjax(res) {
|
||||||
|
var error = false;
|
||||||
|
var showAjaxMessage = function(res) {
|
||||||
|
res = res.replace(/<message type="([\s\S]+?)">([\s\S]+?)<\/message>/, function(message) {
|
||||||
|
if (showMessage && arguments.length > 2) {
|
||||||
|
if (arguments[1] == 'error') {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
showMessage(arguments[2], arguments[1]);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
if (typeof(res) == 'string' && res) {
|
||||||
|
res = showAjaxMessage(res);
|
||||||
|
} else if (typeof(res) == 'object' && typeof(res.message) == 'string' && res.message) {
|
||||||
|
showAjaxMessage(res.message);
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMessage(message) {
|
||||||
|
var res = {};
|
||||||
|
res.message = message;
|
||||||
|
if (arguments.length >= 2) {
|
||||||
|
res.type = arguments[1];
|
||||||
|
} else {
|
||||||
|
res.type = 'notice';
|
||||||
|
}
|
||||||
|
res = $(res).substitute(TEMP.MESSAGE);
|
||||||
|
if ($('#js_message').length > 0 && $('#js_message').get(0).messageAuto) {
|
||||||
|
clearTimeout($('#js_message').get(0).messageAuto);
|
||||||
|
}
|
||||||
|
var messageBox = popBox(res, 'js_message', 999);
|
||||||
|
$('#js_message').css('z-index', 999);
|
||||||
|
$('#js_message').get(0).messageAuto = setTimeout(function() {
|
||||||
|
$('#js_message').hide();
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function popBox(res, id) {
|
||||||
|
if (typeof(id) == 'string') {
|
||||||
|
if (typeof(res) != 'object' && $(res).length == 0) {
|
||||||
|
res = $('<div>' + res + '</div>');
|
||||||
|
} else {
|
||||||
|
res = $(res);
|
||||||
|
}
|
||||||
|
if (res.length > 0) {
|
||||||
|
var box = $('#' + id);
|
||||||
|
if (box.length < 1) {
|
||||||
|
box = $('<div id="' + id + '"></div>');
|
||||||
|
box.appendTo("body");
|
||||||
|
if (res.find('.close').length > 0) {
|
||||||
|
$('#' + id).on('click', '.close', function() {
|
||||||
|
$('#' + id).hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
box.html('');
|
||||||
|
}
|
||||||
|
box.show();
|
||||||
|
if (arguments.length > 2 && parseInt(arguments[2], 10) > 0) {
|
||||||
|
res.appendTo(box).pop(arguments[2]);
|
||||||
|
} else {
|
||||||
|
res.appendTo(box).pop();
|
||||||
|
}
|
||||||
|
//box.children().not(res).remove();
|
||||||
|
autoEvent('#' + id);
|
||||||
|
return res.parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function forceInt(obj) {
|
||||||
|
var oldVal = $(obj).val();
|
||||||
|
var newVal = $(obj).val().replace(/[^\d\.]/g, '').replace(/\..*/, '').replace(/^0+/, '0').replace(/^0*([1-9])/, '$1');
|
||||||
|
if (newVal != oldVal) $(obj).val(newVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
function forceFloat(obj) {
|
||||||
|
var oldVal = $(obj).val();
|
||||||
|
var newVal = $(obj).val().replace(/[^\d\.]/g, '');
|
||||||
|
newVal = newVal.match(/\d*\.*\d{0,2}/)[0];
|
||||||
|
newVal = newVal.replace(/\.+/g, '.').replace(/^\./, '0.').replace(/^0+/, '0').replace(/^0*([1-9])/, '$1');
|
||||||
|
if (newVal != oldVal) $(obj).val(newVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAll(obj, name) {
|
||||||
|
if ($(obj).attr('checked') && name) {
|
||||||
|
$(document).find(':checkbox[name*=' + name + ']').each(function() {
|
||||||
|
if (!$(this).attr('checked')) {
|
||||||
|
$(this).attr('checked', 'checked');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if (name) {
|
||||||
|
$(document).find(':checkbox[name*=' + name + ']').each(function() {
|
||||||
|
if ($(this).attr('checked')) {
|
||||||
|
$(this).attr('checked', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function jConfirm(target, text) {
|
||||||
|
var type = 'click';
|
||||||
|
var $target = $(target);
|
||||||
|
var saveHandlers = function() {
|
||||||
|
var events = $.data(target, 'events');
|
||||||
|
if (target.href) {
|
||||||
|
// No handlers but we have href
|
||||||
|
var url = target.href;
|
||||||
|
$target.bind('click', function() {
|
||||||
|
window.location.href = url;
|
||||||
|
});
|
||||||
|
target.href = 'javascript:void(0)';
|
||||||
|
events = $.data(target, 'events');
|
||||||
|
} else if (!events) {
|
||||||
|
// There are no handlers to save.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target._handlers = new Array();
|
||||||
|
for (var i in events[type]) {
|
||||||
|
target._handlers.push(events[type][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var handler = function() {
|
||||||
|
var text = $(this).attr('confirm');
|
||||||
|
if (!text) {
|
||||||
|
text = '确认进行此操作吗?';
|
||||||
|
}
|
||||||
|
var html = '<div class="W_layer" style="z-index:900">' + '<div class="bg">' + '<table cellspacing="0" cellpadding="0" border="0">' + '<tbody>' + '<tr>' + '<td>' + '<div class="content layer_mini_info">' + '<p class="clearfix">' + '<span class="icon_ask"></span>' + text + '</p>' + '<p class="btn">' + '<a class="btn_b yes" href="javascript:void(0)">' + '<span>??</span>' + '</a>' + '<a class="btn_d ml5 no" href="javascript:void(0)">' + '<span>??</span>' + '</a>' + '</p>' + '</div>' + '</td>' + '</tr>' + '</tbody>' + '</table>' + '</div>' + '</div>';
|
||||||
|
// show confirm box
|
||||||
|
var $box = $('#confirmBox');
|
||||||
|
if ($box.length == 0) {
|
||||||
|
$box = $('<div id="confirmBox" class="pa" style="position:absolute;overflow:hidden"><div class="confirmMask"></div><div class="confirmBody"></div></div>');
|
||||||
|
$box.appendTo("body");
|
||||||
|
} else {
|
||||||
|
$box.html('');
|
||||||
|
$box.html('<div class="confirmMask"></div><div class="confirmBody"></div>');
|
||||||
|
}
|
||||||
|
$box.show();
|
||||||
|
var height = 95;
|
||||||
|
var width = 200;
|
||||||
|
var rect = this.getBoundingClientRect();
|
||||||
|
var sizeObj = $(this).getObjSize();
|
||||||
|
var newLeft = parseInt(rect.left + $(document).scrollLeft(), 10) + parseInt((sizeObj.width - width) / 2, 10);
|
||||||
|
if (newLeft + width > $(document).width()) {
|
||||||
|
newLeft = $(document).width() - width;
|
||||||
|
}
|
||||||
|
$box.css("top", parseInt(rect.top + $(document).scrollTop(), 10) - height + "px").css("left", newLeft + "px");
|
||||||
|
$box.css({
|
||||||
|
'width': width + 'px',
|
||||||
|
'height': height + 'px'
|
||||||
|
});
|
||||||
|
$('#confirmBox .confirmMask').css({
|
||||||
|
'width': width + 'px',
|
||||||
|
'height': height + 'px'
|
||||||
|
});
|
||||||
|
$('#confirmBox .confirmMask').show();
|
||||||
|
$('#confirmBox .confirmBody').html(html);
|
||||||
|
$('#confirmBox .confirmMask').slideUp('normal');
|
||||||
|
$('#confirmBox .confirmBody .yes').click(function() {
|
||||||
|
if (target._handlers != undefined) {
|
||||||
|
$.each(target._handlers, function() {
|
||||||
|
$target.click(this.handler);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Trigger click event.
|
||||||
|
$target.click();
|
||||||
|
$target.unbind(type);
|
||||||
|
$('#confirmBox .confirmMask').slideDown('normal', function() {
|
||||||
|
$target.one(type, handler);
|
||||||
|
$('#confirmBox').hide();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$('#confirmBox .confirmBody .no').click(function() {
|
||||||
|
$('#confirmBox .confirmMask').slideDown('normal', function() {
|
||||||
|
$('#confirmBox').hide();
|
||||||
|
$target.one(type, handler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
saveHandlers();
|
||||||
|
$target.unbind(type);
|
||||||
|
$target.one('click', handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
function textCount(obj) {
|
||||||
|
if (!$(obj).attr('textCount')) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
var noticeDiv = false;
|
||||||
|
$(obj).parents('div').each(function() {
|
||||||
|
if (noticeDiv == false && $(this).find('.textCountTip').length > 0) {
|
||||||
|
noticeDiv = $(this).find('.textCountTip');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var count = $.trim($(obj).val()).length;
|
||||||
|
var limit = parseInt($(obj).attr('textCount'), 10);
|
||||||
|
if (limit >= count) {
|
||||||
|
if ($(obj).hasClass('wrongInput')) {
|
||||||
|
$(obj).removeClass('wrongInput');
|
||||||
|
}
|
||||||
|
noticeDiv.html('您还能输入<em>' + (limit - count) + '</em>个字');
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (!$(obj).hasClass('wrongInput')) {
|
||||||
|
$(obj).addClass('wrongInput');
|
||||||
|
}
|
||||||
|
noticeDiv.html('已超过<em class="red">' + (count - limit) + '</em>个字');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ajaxBox(url) {
|
||||||
|
var data = {};
|
||||||
|
if (arguments.length > 1) {
|
||||||
|
data = arguments[1];
|
||||||
|
}
|
||||||
|
$.post(url, data, function(res) {
|
||||||
|
if (res) {
|
||||||
|
popBox(res, 'js_ajaxBox', 500).addMask( document , 0.5, 250 );
|
||||||
|
if ($("#js_ajaxBox .Move").length >= 1) {
|
||||||
|
var size = $("#js_ajaxBox").getObjSize();
|
||||||
|
var left = $(document).width() - size.width;
|
||||||
|
var top = $(document).height() - size.height;
|
||||||
|
$("#js_ajaxBox").children(':first').Drags({
|
||||||
|
handler: '.Move',
|
||||||
|
area: [0, 0, left, top],
|
||||||
|
zIndex: 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$('#js_ajaxBox').hide().html('');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoEvent() {
|
||||||
|
var objs;
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
objs = $(arguments[0]).find('[action-type],[confirm],[hoverTip],[urlToAjax],[textCount]');
|
||||||
|
} else {
|
||||||
|
objs = $('[action-type],[confirm],[hoverTip],[urlToAjax],[textCount]');
|
||||||
|
}
|
||||||
|
if (objs.not('[switch]').length > 0) {
|
||||||
|
objs.not('[switch]').bind('click', function() {
|
||||||
|
if ($(this).attr('action-type') == 'ajaxBox') {
|
||||||
|
if ($(this).attr('action-data')) {
|
||||||
|
ajaxBox($(this).attr('action-data'));
|
||||||
|
}
|
||||||
|
} else if ($(this).attr('action-type') == 'fun') {
|
||||||
|
if ($(this).attr('action-data')) {
|
||||||
|
var fn = window[$(this).attr('action-data')];
|
||||||
|
if (typeof(fn) == 'function') {
|
||||||
|
fn(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ($(this).attr('action-type') == 'selectAll') {
|
||||||
|
if ($(this).attr('action-data')) {
|
||||||
|
var name = $(this).attr('action-data');
|
||||||
|
if (select_all(this, name)) {
|
||||||
|
$('[action-type=selectAll]').filter('[action-data=' + name + ']').attr('checked', true);
|
||||||
|
} else {
|
||||||
|
$('[action-type=selectAll]').filter('[action-data=' + name + ']').attr('checked', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//check if has selectAll
|
||||||
|
var names = {};
|
||||||
|
objs.filter('[action-type=selectAll]').each(function() {
|
||||||
|
var obj = this;
|
||||||
|
var name = $(this).attr('action-data');
|
||||||
|
if (name && names[name] != true) {
|
||||||
|
$(':checkbox[name*=' + name + ']').live('click', function() {
|
||||||
|
if ($(':checkbox[name*=' + name + ']:checked').length != $(':checkbox[name*=' + name + ']').length) {
|
||||||
|
$('[action-type=selectAll]').filter('[action-data=' + name + ']').attr('checked', false);
|
||||||
|
} else {
|
||||||
|
$('[action-type=selectAll]').filter('[action-data=' + name + ']').attr('checked', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
names[name] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//check if has confirm
|
||||||
|
objs.filter('[confirm]').each(function() {
|
||||||
|
if (typeof($(this).attr('confirm')) != 'undefined') {
|
||||||
|
jConfirm(this, $(this).attr('confirm'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
objs.filter('[hoverTip]').hover(
|
||||||
|
|
||||||
|
function() {
|
||||||
|
$($(this).attr('hoverTip')).show();
|
||||||
|
}, function() {
|
||||||
|
$($(this).attr('hoverTip')).hide();
|
||||||
|
});
|
||||||
|
objs.filter('[urlToAjax]').each(function() {
|
||||||
|
var fn = window[$(this).attr('urlToAjax')];
|
||||||
|
if (typeof(fn) == 'function') {
|
||||||
|
$(this).find('a').each(function() {
|
||||||
|
var url = $(this).attr('href');
|
||||||
|
if (url && url != '#' && url.substr(0, 11).toLowerCase() != 'javascript:') {
|
||||||
|
$(this).attr('href', 'javascript:void(0)');
|
||||||
|
$(this).bind('click', function() {
|
||||||
|
fn(this, url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
objs.filter('[textCount]').each(function() {
|
||||||
|
textCount(this);
|
||||||
|
$(this).bind('propertychange', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
textCount(this);
|
||||||
|
}).bind("input", function() {
|
||||||
|
textCount(this);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//(function($) {
|
||||||
|
$.extend($.fn, {
|
||||||
|
getCss: function(key) {
|
||||||
|
var v = parseInt(this.css(key));
|
||||||
|
if (isNaN(v)) return false;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$.fn.Drags = function(opts) {
|
||||||
|
var ps = $.extend({
|
||||||
|
zIndex: 20,
|
||||||
|
opacity: .7,
|
||||||
|
handler: null,
|
||||||
|
area: null,
|
||||||
|
onMove: function() {},
|
||||||
|
onDrop: function() {}
|
||||||
|
}, opts);
|
||||||
|
var dragndrop = {
|
||||||
|
drag: function(e) {
|
||||||
|
var dragData = e.data.dragData;
|
||||||
|
var left = dragData.left + e.pageX - dragData.offLeft;
|
||||||
|
var top = dragData.top + e.pageY - dragData.offTop;
|
||||||
|
if (dragData.area) {
|
||||||
|
left = Math.min(Math.max(dragData.area[0], left), dragData.area[2]);
|
||||||
|
top = Math.min(Math.max(dragData.area[1], top), dragData.area[3]);
|
||||||
|
}
|
||||||
|
//left = Math.min( Math.max( 0 , left ) , ps.maxLeft );
|
||||||
|
//top = Math.min( Math.max( 0 , top ) , ps.maxTop );
|
||||||
|
dragData.target.css({
|
||||||
|
left: left,
|
||||||
|
top: top
|
||||||
|
});
|
||||||
|
dragData.handler.css({
|
||||||
|
cursor: 'move'
|
||||||
|
});
|
||||||
|
dragData.onMove(e);
|
||||||
|
e = e || window.event;
|
||||||
|
if (e.stopProgation) {
|
||||||
|
e.stopPropagation();
|
||||||
|
} else {
|
||||||
|
e.cancelBubble = true;
|
||||||
|
}
|
||||||
|
if (e.preventDefault) {
|
||||||
|
e.preventDefault();
|
||||||
|
} else {
|
||||||
|
e.returnValue = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
drop: function(e) {
|
||||||
|
var dragData = e.data.dragData;
|
||||||
|
dragData.target.css(dragData.oldCss); //.css({ 'opacity': '' });
|
||||||
|
//dragData.handler.css('cursor', dragData.oldCss.cursor);
|
||||||
|
dragData.onDrop(e);
|
||||||
|
$(document).unbind('mousemove', dragndrop.drag).unbind('mouseup', dragndrop.drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.each(function() {
|
||||||
|
var me = this;
|
||||||
|
var handler = null;
|
||||||
|
if (typeof ps.handler == 'undefined' || ps.handler == null) handler = $(me);
|
||||||
|
else handler = (typeof ps.handler == 'string' ? $(ps.handler, this) : ps.handle);
|
||||||
|
handler.bind('mousedown', {
|
||||||
|
e: me
|
||||||
|
}, function(s) {
|
||||||
|
var target = $(s.data.e);
|
||||||
|
var oldCss = {};
|
||||||
|
if (target.css('position') != 'absolute') {
|
||||||
|
try {
|
||||||
|
target.position(oldCss);
|
||||||
|
} catch (ex) {}
|
||||||
|
target.css('position', 'absolute');
|
||||||
|
}
|
||||||
|
oldCss.cursor = target.css('cursor') || 'default';
|
||||||
|
//oldCss.opacity = target.getCss('opacity') || 1;
|
||||||
|
var dragData = {
|
||||||
|
left: oldCss.left || target.getCss('left') || 0,
|
||||||
|
top: oldCss.top || target.getCss('top') || 0,
|
||||||
|
width: target.width() || target.getCss('width'),
|
||||||
|
height: target.height() || target.getCss('height'),
|
||||||
|
offLeft: s.pageX,
|
||||||
|
offTop: s.pageY,
|
||||||
|
oldCss: oldCss,
|
||||||
|
area: ps.area,
|
||||||
|
onMove: ps.onMove,
|
||||||
|
onDrop: ps.onDrop,
|
||||||
|
handler: handler,
|
||||||
|
target: target
|
||||||
|
}
|
||||||
|
//target.css('opacity', ps.opacity);
|
||||||
|
$(document).bind('mousemove', {
|
||||||
|
dragData: dragData
|
||||||
|
}, dragndrop.drag).bind('mouseup', {
|
||||||
|
dragData: dragData
|
||||||
|
}, dragndrop.drop);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//})(jQuery);
|
||||||
|
$(function() {
|
||||||
|
autoEvent();
|
||||||
|
});
|
||||||
|
//add on
|
||||||
|
(function($, afterAjax) {
|
||||||
|
var inIframe = true;
|
||||||
|
var ajaxLock = {};
|
||||||
|
var lastTargetInfo = false;
|
||||||
|
var getEvent = function() {
|
||||||
|
if (document.all) return window.event;
|
||||||
|
func = getEvent.caller;
|
||||||
|
while (func != null && func.arguments) {
|
||||||
|
var arg0 = func.arguments[0];
|
||||||
|
if (arg0) {
|
||||||
|
if ((arg0.constructor == Event || arg0.constructor == MouseEvent) || (typeof(arg0) == "object" && arg0.preventDefault && arg0.stopPropagation)) {
|
||||||
|
return arg0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func = func.caller;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var getlastObj = function() {
|
||||||
|
var event = getEvent();
|
||||||
|
if (event) {
|
||||||
|
var elem = event.srcElement || event.target;
|
||||||
|
if (elem && typeof(elem.nodeType) != undefined && elem.nodeType) {
|
||||||
|
return elem;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var originalAjax = $.ajax;
|
||||||
|
$.ajax = function() {
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
var url = arguments[0].url;
|
||||||
|
if (ajaxLock[url] == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var originalSuccess = function() {};
|
||||||
|
var cleanLock = function() {
|
||||||
|
ajaxLock[url] = false;
|
||||||
|
};
|
||||||
|
if (arguments[0].success) {
|
||||||
|
originalSuccess = arguments[0].success;
|
||||||
|
}
|
||||||
|
if (inIframe) {
|
||||||
|
var elem = getlastObj();
|
||||||
|
if (elem && elem != document) {
|
||||||
|
lastTargetInfo = {};
|
||||||
|
lastTargetInfo.isLastTarget = true;
|
||||||
|
lastTargetInfo.rect = elem.getBoundingClientRect();
|
||||||
|
lastTargetInfo.size = $(elem).getObjSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arguments[0].success = function(res) {
|
||||||
|
cleanLock();
|
||||||
|
if (afterAjax && typeof(afterAjax) == 'function') {
|
||||||
|
res = afterAjax(res, lastTargetInfo);
|
||||||
|
}
|
||||||
|
if (res !== false) originalSuccess(res, lastTargetInfo);
|
||||||
|
}
|
||||||
|
ajaxLock[url] = true;
|
||||||
|
return originalAjax.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$.fn.getObjSize = function() {
|
||||||
|
var size = {
|
||||||
|
'width': 0,
|
||||||
|
'height': 0,
|
||||||
|
'top': 0,
|
||||||
|
'left': 0
|
||||||
|
};
|
||||||
|
var level = 5;
|
||||||
|
var obj = this;
|
||||||
|
while (obj.outerHeight() == 0 && obj.length > 0 && level > 0) {
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
obj = obj.children().find(arguments[0]);
|
||||||
|
} else {
|
||||||
|
obj = obj.children(':first');
|
||||||
|
}
|
||||||
|
level = level - 1;
|
||||||
|
}
|
||||||
|
size.width = obj.outerWidth();
|
||||||
|
size.height = obj.outerHeight();
|
||||||
|
return size;
|
||||||
|
};
|
||||||
|
$.fn.getObjSize = function() {
|
||||||
|
var size = {
|
||||||
|
'width': 0,
|
||||||
|
'height': 0,
|
||||||
|
'top': 0,
|
||||||
|
'left': 0
|
||||||
|
};
|
||||||
|
var level = 5;
|
||||||
|
var obj = this;
|
||||||
|
while (obj.outerHeight() == 0 && obj.length > 0 && level > 0) {
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
obj = obj.children().find(arguments[0]);
|
||||||
|
} else {
|
||||||
|
obj = obj.children(':first');
|
||||||
|
}
|
||||||
|
level = level - 1;
|
||||||
|
}
|
||||||
|
size.width = obj.outerWidth();
|
||||||
|
size.height = obj.outerHeight();
|
||||||
|
return size;
|
||||||
|
};
|
||||||
|
$.fn.pop = function() {
|
||||||
|
var size = this.getObjSize();
|
||||||
|
if (this.css('position') != 'absolute') {
|
||||||
|
this.css('position','absolute');
|
||||||
|
}
|
||||||
|
if (($(window).height() - size.height) / 2 + $(window).scrollTop() < 0) {
|
||||||
|
this.css("top", "0px");
|
||||||
|
} else {
|
||||||
|
if (inIframe) {
|
||||||
|
var rect, rectSize;
|
||||||
|
var elem = getlastObj();
|
||||||
|
if (elem == false) {
|
||||||
|
var func = arguments.callee.caller;
|
||||||
|
do {
|
||||||
|
if (func.arguments && func.arguments.length == 2 && func.arguments[1].isLastTarget != undefined) {
|
||||||
|
var lastTarget = func.arguments[1];
|
||||||
|
rect = lastTarget.rect;
|
||||||
|
rectSize = lastTarget.size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
func = func.caller;
|
||||||
|
} while (func);
|
||||||
|
if (!func && lastTargetInfo) {
|
||||||
|
rect = lastTargetInfo.rect;
|
||||||
|
rectSize = lastTargetInfo.size;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rect = elem.getBoundingClientRect();
|
||||||
|
rectSize = $(elem).getObjSize();
|
||||||
|
}
|
||||||
|
if (!rect || !rectSize) {
|
||||||
|
this.css("top", "50px");
|
||||||
|
} else if (!$(elem).is($(this))) {
|
||||||
|
var mY = parseInt(rect.top, 10) + rectSize.height / 2 + $(document).scrollTop() - size.height / 2;
|
||||||
|
if (mY + size.height > $(window).height() + $(window).scrollTop()) {
|
||||||
|
mY = $(window).scrollTop() + $(window).height() - size.height;
|
||||||
|
}
|
||||||
|
if (mY < 0) {
|
||||||
|
mY = 0;
|
||||||
|
}
|
||||||
|
this.css("top", mY + "px");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.css("top", ($(window).height() - size.height) / 2 + $(window).scrollTop() + "px");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.css("left", ($(window).width() - size.width) / 2 + $(window).scrollLeft() + "px");
|
||||||
|
if (arguments.length > 0 && parseInt(arguments[0], 10) > 0) {
|
||||||
|
this.css('z-index', parseInt(arguments[0], 10));
|
||||||
|
}
|
||||||
|
if ($(this).find('.js_maskIframe').length == 0 && $.browser.msie && ($.browser.version == "6.0") && !$.support.style) {
|
||||||
|
if ($(document).find('select').length > 0) {
|
||||||
|
$(this).wrapInner('<div style="position:relative;width:' + size.width + 'px;height:' + size.height + 'px;" class="maskDiv"></div>');
|
||||||
|
$('.maskDiv').before('<iframe class="js_maskIframe" style="position:absolute;z-index:-1;width:' + size.width + 'px;height:' + size.height + 'px;top:' + size.top + 'px;left:' + size.left + 'px;" frameBorder=0 ></iframe>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
$.fn.blink = function() {
|
||||||
|
var o = {};
|
||||||
|
var $target = this;
|
||||||
|
var id = $(this).attr('id') || $(this).attr('name');
|
||||||
|
o[id] = {};
|
||||||
|
o[id].begin = 0;
|
||||||
|
o[id].end = 0;
|
||||||
|
o[id].lock = false;
|
||||||
|
o[id].step = 6;
|
||||||
|
o[id].times = 6;
|
||||||
|
o[id].color = function(i) {
|
||||||
|
$target.css('background', 'rgb(255,' + i + ',' + i + ')');
|
||||||
|
}
|
||||||
|
o[id].color_next = function(f) {
|
||||||
|
if (o[id].begin > o[id].end) {
|
||||||
|
o[id].begin -= o[id].step;
|
||||||
|
} else if (o[id].begin < o[id].end) {
|
||||||
|
o[id].begin += o[id].step;
|
||||||
|
} else {
|
||||||
|
o[id].lock = false;
|
||||||
|
if (typeof(f) == 'function') {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
o[id].color(o[id].begin);
|
||||||
|
setTimeout(function() {
|
||||||
|
o[id].color_next(f);
|
||||||
|
}, 25);
|
||||||
|
}
|
||||||
|
o[id].color_to = function(x, y, f) {
|
||||||
|
if (o[id].lock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
o[id].begin = x;
|
||||||
|
o[id].end = y;
|
||||||
|
o[id].lock = true;
|
||||||
|
o[id].color_next(f);
|
||||||
|
}
|
||||||
|
var _c = 255 - o[id].step * o[id].times;
|
||||||
|
o[id].color_to(255, _c, function() {
|
||||||
|
o[id].color_to(_c, 255, function() {
|
||||||
|
o[id].color_to(255, _c, function() {
|
||||||
|
o[id].color_to(_c, 255);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
$.fn.substitute = function(str) {
|
||||||
|
var obj = this[0];
|
||||||
|
if (!(Object.prototype.toString.call(str) === '[object String]')) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (!(Object.prototype.toString.call(obj) === '[object Object]' && 'isPrototypeOf' in obj)) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
return str.replace(/\{([^{}]+)\}/g, function(match, key) {
|
||||||
|
var value = obj[key];
|
||||||
|
return (value !== undefined) ? '' + value : '';
|
||||||
|
});
|
||||||
|
};
|
||||||
|
$.fn.setValue = function(json) {
|
||||||
|
if (typeof(json) == 'string' && arguments.length == 2) {
|
||||||
|
var key = json;
|
||||||
|
json = {};
|
||||||
|
json[key] = arguments[1];
|
||||||
|
}
|
||||||
|
var _this = this;
|
||||||
|
var jsonNameFormat = function( json ){
|
||||||
|
var prefix = '' , jsonFormated = {};
|
||||||
|
if( arguments[1] ){
|
||||||
|
prefix = arguments[1];
|
||||||
|
}
|
||||||
|
$.each(json, function(name , value ){
|
||||||
|
name = prefix?prefix+'['+name+']':name;
|
||||||
|
if( typeof(value) == 'object' ){
|
||||||
|
//alert(name);
|
||||||
|
jsonFormated = $.extend( jsonFormated , jsonNameFormat( value , name ) );
|
||||||
|
}else{
|
||||||
|
jsonFormated[name] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return jsonFormated;
|
||||||
|
};
|
||||||
|
if (typeof(json) == 'object') {
|
||||||
|
json = jsonNameFormat( json );
|
||||||
|
$.each(json, function(name, value) {
|
||||||
|
var obj = $(_this).find(":input[name='" + name + "']");
|
||||||
|
if (obj.length > 0) {
|
||||||
|
switch (obj.get(0).type) {
|
||||||
|
case 'radio':
|
||||||
|
case 'checkbox':
|
||||||
|
obj.filter("[value='" + value + "']").filter(":not(:checked)").click();
|
||||||
|
break;
|
||||||
|
case 'select-one':
|
||||||
|
case 'textarea':
|
||||||
|
case 'text':
|
||||||
|
case 'hidden':
|
||||||
|
obj.val(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
$.fn.addMask = function( obj , opacity, zindex) {
|
||||||
|
var newCss = {};
|
||||||
|
newCss.width = $(obj).width() + 'px';
|
||||||
|
newCss.height = $(obj).height() + 'px';
|
||||||
|
newCss.position = 'absolute';
|
||||||
|
newCss['-moz-opacity'] = opacity;
|
||||||
|
newCss.opacity = opacity;
|
||||||
|
newCss['z-index'] = zindex;
|
||||||
|
newCss.filter = 'alpha(Opacity=' + parseFloat(opacity, 10) * 100 + ')';
|
||||||
|
if (arguments.length > 3) {
|
||||||
|
if (arguments[3]) {
|
||||||
|
newCss.background = arguments[3];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newCss.background = '#777';
|
||||||
|
}
|
||||||
|
if( obj == document ){
|
||||||
|
newCss.top = '0px';
|
||||||
|
newCss.left = '0px';
|
||||||
|
}else{
|
||||||
|
var rect = $(obj).get(0).getBoundingClientRect();
|
||||||
|
newCss.top = rect.top + 'px';
|
||||||
|
newCss.left = rect.left + 'px';
|
||||||
|
}
|
||||||
|
var className;
|
||||||
|
if (arguments.length > 3) {
|
||||||
|
className = arguments[3];
|
||||||
|
} else {
|
||||||
|
className = 'js-mask';
|
||||||
|
}
|
||||||
|
var maskDiv = $('<div></div>');
|
||||||
|
maskDiv.addClass(className);
|
||||||
|
maskDiv.css(newCss);
|
||||||
|
maskDiv.appendTo(this);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
})(jQuery, afterAjax);
|
83
lib/BaseController.class.php
Executable file
83
lib/BaseController.class.php
Executable file
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
class BaseController{
|
||||||
|
public $tplParams = array();
|
||||||
|
public $layout = NULL;
|
||||||
|
public $layoutTpl = true;
|
||||||
|
function __construct(){
|
||||||
|
//if token is expires clear it
|
||||||
|
if( $_SESSION['expiresTime'] && $_SESSION['expiresTime'] <= time() ){
|
||||||
|
$_SESSION = array();
|
||||||
|
}
|
||||||
|
if(isset($_GET['tokenString'])){
|
||||||
|
$tokenString=explode(".", $_GET['tokenString']);
|
||||||
|
$token= json_decode(base64_decode($tokenString[1]) , true );
|
||||||
|
}
|
||||||
|
if($token['oauth_token']){
|
||||||
|
Weibo::init( c('akey') , c('skey') ,$tokenInfo['oauth_token'] );
|
||||||
|
Weibo::setIp('202.110.0.5');
|
||||||
|
$res = Weibo::show_user_by_id( $tokenInfo['user_id'] );
|
||||||
|
if( $res && !isset( $res['error_code'] ) ){
|
||||||
|
foreach ($res as $key => $value) {
|
||||||
|
$_SESSION[$key] = $value;
|
||||||
|
}
|
||||||
|
$_SESSION['__SINA']['TOKEN'] = $tokenInfo['oauth_token'];
|
||||||
|
$_SESSION['expiresTime'] = $tokenInfo['expires'] + time();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
Weibo::init( c('akey') , c('skey') ,$_SESSION['__SINA']['TOKEN'] );
|
||||||
|
Weibo::setIp('202.110.0.5');
|
||||||
|
}
|
||||||
|
//init weibo Class
|
||||||
|
}
|
||||||
|
protected function _add( $key , $value = NULL ){
|
||||||
|
if( $value == NULL && is_array($key) ){
|
||||||
|
$this->tplParams += $key;
|
||||||
|
}else{
|
||||||
|
$this->tplParams[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected function showMessage( $message , $type = 'notice' , $show = true ){
|
||||||
|
$message = '<message type="'.$type.'">'.$message.'</message>';
|
||||||
|
if( $show ){
|
||||||
|
echo $message;
|
||||||
|
}else{
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected function render( $tplName = NULL , $data = array() ){
|
||||||
|
if( $data && is_array( $data ) ){
|
||||||
|
$data = array_merge( $data , $this->tplParams );
|
||||||
|
}else{
|
||||||
|
$data = $this->tplParams;
|
||||||
|
}
|
||||||
|
if( !$tplName ){
|
||||||
|
$tpl = $tplName?$tplName:get_class($this);
|
||||||
|
if( Url::getMethod() != c('default_method') ){
|
||||||
|
$tpl .= '_'.Url::getMethod();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$tpl = $tplName;
|
||||||
|
}
|
||||||
|
|
||||||
|
render( $data , $tpl , $this->layout , $this->layoutTpl );
|
||||||
|
}
|
||||||
|
protected function getAjax( $method , $extra = array() ){
|
||||||
|
if( !method_exists( $this , $method ) ) die('Ajax method is not exists' );
|
||||||
|
//save info
|
||||||
|
$url = Url::getUrl();
|
||||||
|
|
||||||
|
$extra['method'] = $method;
|
||||||
|
$GLOBALS['__isAjax'] = true;
|
||||||
|
|
||||||
|
Url::setUrl( Url::make($extra) );
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$this->$method();
|
||||||
|
$html = ob_get_clean();
|
||||||
|
//replace back
|
||||||
|
unset($GLOBALS['__isAjax']);
|
||||||
|
Url::setUrl( $url );
|
||||||
|
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
}
|
99
lib/app.function.php
Executable file
99
lib/app.function.php
Executable file
@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
function checkLogin(){
|
||||||
|
if( !isLogin() ){
|
||||||
|
$back = $_SERVER['REQUEST_URI']?:'/';
|
||||||
|
if( v('ajax') && isset( $_SERVER['HTTP_REFERER'])&&$_SERVER['HTTP_REFERER'] ){
|
||||||
|
$back = $_SERVER['HTTP_REFERER'];
|
||||||
|
}
|
||||||
|
$state = NULL;
|
||||||
|
if( IFCookie::isNeedFix() ){
|
||||||
|
$sid = session_id();
|
||||||
|
$state = $sid;
|
||||||
|
$back .= '&'.IFCookie::SESSIONSTR.'='.$sid;
|
||||||
|
}
|
||||||
|
$_SESSION['backUrl'] = $back;
|
||||||
|
$aurl = Weibo::getAuthorizeURL( c('callback') , 'code' , $state );
|
||||||
|
header("Location: ".$aurl);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function isLogin(){
|
||||||
|
if( isset( $_GET['viewer'] ) ){
|
||||||
|
if( $_GET['viewer'] == '' || $_GET['viewer'] != $_SESSION['id'] ){
|
||||||
|
$_SESSION = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( $_SESSION['id'] ){
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getPager( $page , $page_all , $old = array() ,$custom = array() ){
|
||||||
|
if( $page_all <= 1 ){
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if( $custom && is_array($custom) ){
|
||||||
|
$custom = '&'.http_build_query($custom);
|
||||||
|
}elseif( $custom ){
|
||||||
|
$custom = '&'.$custom;
|
||||||
|
}else{
|
||||||
|
$custom = NULL;
|
||||||
|
}
|
||||||
|
$pre = $next = $middle = '';
|
||||||
|
$left_num = $right_num = 0;
|
||||||
|
$left_more = $right_more = false;
|
||||||
|
if( $page > 1 ){
|
||||||
|
$pre = '<li class="pref" ><a href="'.Url::make( 'page='.($page - 1).$custom , $old ).'" title="上一页">上一页</a></li>';
|
||||||
|
}
|
||||||
|
if( $page < $page_all ){
|
||||||
|
$next = '<li class="next" ><a href="'.Url::make( 'page='.($page + 1).$custom , $old ). '" title="下一页">下一页</a></li>';
|
||||||
|
}
|
||||||
|
if( $page_all <= 11 ){
|
||||||
|
/* 小于等于 11 页 */
|
||||||
|
$left_num = $page - 1;
|
||||||
|
$right_num = $page_all - $page;
|
||||||
|
}else{
|
||||||
|
if( $page > 6 ){
|
||||||
|
$left_more = true;
|
||||||
|
if( $page < $page_all - 5 ){
|
||||||
|
$right_more = true;
|
||||||
|
$left_num = 4;
|
||||||
|
$right_num = 4;
|
||||||
|
}else{
|
||||||
|
$right_more = false;
|
||||||
|
$right_num = $page_all - $page;
|
||||||
|
$left_num = 9 - $right_num;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$left_num = $page - 1;
|
||||||
|
$left_more = false;
|
||||||
|
$right_num = 9 - $left_num;
|
||||||
|
$right_more = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( $left_more ){
|
||||||
|
$middle .= '<li><a href="'.Url::make( 'page=1'.$custom , $old ).'">1</a></li>';
|
||||||
|
$middle .= '<li><a>...</a></li>';
|
||||||
|
}
|
||||||
|
for($j=$left_num;$j>0;$j--){
|
||||||
|
$i = $page - $j;
|
||||||
|
if( $i <= 0 ){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$middle .= '<li><a href="'.Url::make( 'page='.$i.$custom , $old ). '">' . $i .'</a></li>';
|
||||||
|
}
|
||||||
|
$middle .= '<li class="cur"><a>' . $page . '</a></li>';
|
||||||
|
for($j=1;$j<=$right_num;$j++){
|
||||||
|
$i = $page + $j;
|
||||||
|
if( $i > $page_all ){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$middle .= '<li><a href="'.Url::make( 'page='.$i.$custom , $old ).'">' . $i .'</a></li>';
|
||||||
|
}
|
||||||
|
if( $right_more ){
|
||||||
|
$middle .= '<li><a>...</a></li>';
|
||||||
|
$middle .= '<li><a href="'.Url::make( 'page='.$page_all.$custom , $old ).'">' . $page_all .'</a></li>';
|
||||||
|
}
|
||||||
|
return $pre.$middle.$next;
|
||||||
|
}
|
21
themes/default/layout.tpl.html
Executable file
21
themes/default/layout.tpl.html
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>Engine Title 请修改在 themes/default/layout.tpl.html 修改 </title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/core.css" media="all" />
|
||||||
|
<script type="text/javascript" src="http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/wExpress.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/core.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php
|
||||||
|
if(is_file(ROOT.'themes/default/'. $__showPage .'.tpl.html'))
|
||||||
|
include( ROOT.'themes/default/'. $__showPage .'.tpl.html' );
|
||||||
|
else
|
||||||
|
echo "<div>can't find $__showPage html file</div>";
|
||||||
|
|
||||||
|
?>
|
||||||
|
<script type="text/javascript" charset="utf-8" src="http://js.t.sinajs.cn/t4/enterprise/js/public/appframe/client.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
0
themes/default/main.tpl.html
Normal file
0
themes/default/main.tpl.html
Normal file
Loading…
Reference in New Issue
Block a user