You've already forked qlg.tsgz.moe
Init Repo
This commit is contained in:
306
extend/app_alipay/lotusphp_runtime/Autoloader/Autoloader.php
Executable file
306
extend/app_alipay/lotusphp_runtime/Autoloader/Autoloader.php
Executable file
@ -0,0 +1,306 @@
|
||||
<?php
|
||||
class LtAutoloader
|
||||
{
|
||||
public $conf = array(
|
||||
/**
|
||||
* 是否自动加载定义了函数的文件
|
||||
*
|
||||
* 可选项:
|
||||
* # true 自动加载
|
||||
* # false 跳过函数,只自动加载定义了class或者interface的文件
|
||||
*/
|
||||
"load_function" => true,
|
||||
|
||||
/**
|
||||
* 要扫描的文件类型
|
||||
*
|
||||
* 若该属性设置为array("php","inc","php3"),
|
||||
* 则扩展名为"php","inc","php3"的文件会被扫描,
|
||||
* 其它扩展名的文件会被忽略
|
||||
*/
|
||||
"allow_file_extension" => array("php", "inc"),
|
||||
|
||||
/**
|
||||
* 不扫描的目录
|
||||
*
|
||||
* 若该属性设置为array(".svn", ".setting"),
|
||||
* 则所有名为".setting"的目录也会被忽略
|
||||
*/
|
||||
"skip_dir_names" => array(".svn"),
|
||||
);
|
||||
|
||||
public $storeHandle;
|
||||
public $autoloadPath;
|
||||
protected $functionFileMapping;
|
||||
protected $fileStore;
|
||||
|
||||
public function init()
|
||||
{
|
||||
if (!is_object($this->storeHandle))
|
||||
{
|
||||
$this->storeHandle = new LtStoreMemory;
|
||||
$this->fileStore = new LtStoreFile;
|
||||
$this->fileStore->prefix = 'LtAutoloader-token-cache';
|
||||
$this->fileStore->useSerialize = true;
|
||||
$this->fileStore->init();
|
||||
}
|
||||
// Whether scanning directory
|
||||
if (0 == $this->storeHandle->get(".class_total") && 0 == $this->storeHandle->get(".function_total"))
|
||||
{
|
||||
$this->storeHandle->add(".class_total", 0);
|
||||
$this->storeHandle->add(".function_total", 0);
|
||||
$this->storeHandle->add(".functions", array(), 0);
|
||||
$autoloadPath = $this->preparePath($this->autoloadPath);
|
||||
foreach($autoloadPath as $key => $path)
|
||||
{
|
||||
if (is_file($path))
|
||||
{
|
||||
$this->addFileMap($path);
|
||||
unset($autoloadPath[$key]);
|
||||
}
|
||||
}
|
||||
$this->scanDirs($autoloadPath);
|
||||
unset($autoloadPath);
|
||||
}
|
||||
// Whether loading function files
|
||||
if ($this->conf["load_function"])
|
||||
{
|
||||
$this->loadFunction();
|
||||
}
|
||||
spl_autoload_register(array($this, "loadClass"));
|
||||
}
|
||||
|
||||
public function loadFunction()
|
||||
{
|
||||
if ($functionFiles = $this->storeHandle->get(".functions"))
|
||||
{
|
||||
foreach ($functionFiles as $functionFile)
|
||||
{
|
||||
include($functionFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function loadClass($className)
|
||||
{
|
||||
if ($classFile = $this->storeHandle->get(strtolower($className)))
|
||||
{
|
||||
include($classFile);
|
||||
}
|
||||
}
|
||||
|
||||
protected function convertPath($path)
|
||||
{
|
||||
$path = str_replace("\\", "/", $path);
|
||||
if (!is_readable($path))
|
||||
{
|
||||
trigger_error("Directory is not exists/readable: {$path}");
|
||||
return false;
|
||||
}
|
||||
$path = rtrim(realpath($path), '\\/');
|
||||
if ("WINNT" != PHP_OS && preg_match("/\s/i", $path))
|
||||
{
|
||||
trigger_error("Directory contains space/tab/newline is not supported: {$path}");
|
||||
return false;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* The string or an Multidimensional array into a one-dimensional array
|
||||
*
|
||||
* @param array $ or string $var
|
||||
* @return array one-dimensional array
|
||||
*/
|
||||
protected function preparePath($var)
|
||||
{
|
||||
$ret = array();
|
||||
if (!is_array($var))
|
||||
{
|
||||
$var = array($var);
|
||||
}
|
||||
$i = 0;
|
||||
while (isset($var[$i]))
|
||||
{
|
||||
if (!is_array($var[$i]) && $path = $this->convertPath($var[$i]))
|
||||
{
|
||||
$ret[] = $path;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($var[$i] as $v)
|
||||
{
|
||||
$var[] = $v;
|
||||
}
|
||||
}
|
||||
unset($var[$i]);
|
||||
$i ++;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using iterative algorithm scanning subdirectories
|
||||
* save autoloader filemap
|
||||
*
|
||||
* @param array $dirs one-dimensional
|
||||
* @return
|
||||
*/
|
||||
protected function scanDirs($dirs)
|
||||
{
|
||||
$i = 0;
|
||||
while (isset($dirs[$i]))
|
||||
{
|
||||
$dir = $dirs[$i];
|
||||
$files = scandir($dir);
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if (in_array($file, array(".", "..")) || in_array($file, $this->conf["skip_dir_names"]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$currentFile = $dir . DIRECTORY_SEPARATOR . $file;
|
||||
if (is_file($currentFile))
|
||||
{
|
||||
$this->addFileMap($currentFile);
|
||||
}
|
||||
else if (is_dir($currentFile))
|
||||
{
|
||||
// if $currentFile is a directory, pass through the next loop.
|
||||
$dirs[] = $currentFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("$currentFile is not a file or a directory.");
|
||||
}
|
||||
} //end foreach
|
||||
unset($dirs[$i]);
|
||||
$i ++;
|
||||
} //end while
|
||||
}
|
||||
|
||||
protected function parseLibNames($src)
|
||||
{
|
||||
$libNames = array();
|
||||
$tokens = token_get_all($src);
|
||||
$level = 0;
|
||||
$found = false;
|
||||
$name = '';
|
||||
foreach ($tokens as $token)
|
||||
{
|
||||
if (is_string($token))
|
||||
{
|
||||
if ('{' == $token)
|
||||
{
|
||||
$level ++;
|
||||
}
|
||||
else if ('}' == $token)
|
||||
{
|
||||
$level --;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list($id, $text) = $token;
|
||||
if (T_CURLY_OPEN == $id || T_DOLLAR_OPEN_CURLY_BRACES == $id)
|
||||
{
|
||||
$level ++;
|
||||
}
|
||||
if (0 < $level)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch ($id)
|
||||
{
|
||||
case T_STRING:
|
||||
if ($found)
|
||||
{
|
||||
$libNames[strtolower($name)][] = $text;
|
||||
$found = false;
|
||||
}
|
||||
break;
|
||||
case T_CLASS:
|
||||
case T_INTERFACE:
|
||||
case T_FUNCTION:
|
||||
$found = true;
|
||||
$name = $text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $libNames;
|
||||
}
|
||||
|
||||
protected function addClass($className, $file)
|
||||
{
|
||||
$key = strtolower($className);
|
||||
if ($existedClassFile = $this->storeHandle->get($key))
|
||||
{
|
||||
trigger_error("duplicate class [$className] found in:\n$existedClassFile\n$file\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->storeHandle->add($key, $file);
|
||||
$this->storeHandle->update(".class_total", $this->storeHandle->get(".class_total") + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function addFunction($functionName, $file)
|
||||
{
|
||||
$functionName = strtolower($functionName);
|
||||
if (isset($this->functionFileMapping[$functionName]))
|
||||
{
|
||||
$existedFunctionFile = $this->functionFileMapping[$functionName];
|
||||
trigger_error("duplicate function [$functionName] found in:\n$existedFunctionFile\n$file\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->functionFileMapping[$functionName] = $file;
|
||||
$this->storeHandle->update(".functions", array_unique(array_values($this->functionFileMapping)));
|
||||
$this->storeHandle->update(".function_total", count($this->functionFileMapping));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function addFileMap($file)
|
||||
{
|
||||
if (!in_array(pathinfo($file, PATHINFO_EXTENSION), $this->conf["allow_file_extension"]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$libNames = array();
|
||||
if ($this->fileStore instanceof LtStore)
|
||||
{
|
||||
$cachedFileLastModified = (int) @filemtime($this->fileStore->getFilePath($file));
|
||||
if ($cachedFileLastModified < filemtime($file) || !is_array(($libNames = $this->fileStore->get($file))))
|
||||
{
|
||||
$libNames = $this->parseLibNames(trim(file_get_contents($file)));
|
||||
if (0 < $cachedFileLastModified)
|
||||
{
|
||||
$this->fileStore->update($file, $libNames);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->fileStore->add($file, $libNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$libNames = $this->parseLibNames(trim(file_get_contents($file)));
|
||||
}
|
||||
|
||||
foreach ($libNames as $libType => $libArray)
|
||||
{
|
||||
$method = "function" == $libType ? "addFunction" : "addClass";
|
||||
foreach ($libArray as $libName)
|
||||
{
|
||||
$this->$method($libName, $file);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
9
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapter.php
Executable file
9
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapter.php
Executable file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
interface LtCacheAdapter
|
||||
{
|
||||
public function connect($hostConf);
|
||||
public function add($key, $value, $ttl = 0, $tableName, $connectionResource);
|
||||
public function del($key, $tableName, $connectionResource);
|
||||
public function get($key, $tableName, $connectionResource);
|
||||
public function update($key, $value, $ttl = 0, $tableName, $connectionResource);
|
||||
}
|
40
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterApc.php
Executable file
40
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterApc.php
Executable file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
class LtCacheAdapterApc implements LtCacheAdapter
|
||||
{
|
||||
public function connect($hostConf)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function add($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
return apc_add($this->getRealKey($tableName, $key), $value, $ttl);
|
||||
}
|
||||
|
||||
public function del($key, $tableName, $connectionResource)
|
||||
{
|
||||
return apc_delete($this->getRealKey($tableName, $key));
|
||||
}
|
||||
|
||||
public function get($key, $tableName, $connectionResource)
|
||||
{
|
||||
return apc_fetch($this->getRealKey($tableName, $key));
|
||||
}
|
||||
|
||||
public function update($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
if ($this->del($key, $tableName, $connectionResource))
|
||||
{
|
||||
return $this->add($key, $value, $ttl, $tableName, $connectionResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getRealKey($tableName, $key)
|
||||
{
|
||||
return $tableName . "-" . $key;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
class LtCacheAdapterEAccelerator implements LtCacheAdapter
|
||||
{
|
||||
public function connect($hostConf)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function add($key, $value, $ttl=0, $tableName, $connectionResource)
|
||||
{
|
||||
$value = serialize($value); //eAccelerator doesn't serialize object
|
||||
return eaccelerator_put($this->getRealKey($tableName, $key), $value, $ttl);
|
||||
}
|
||||
|
||||
public function del($key, $tableName, $connectionResource)
|
||||
{
|
||||
return eaccelerator_rm($this->getRealKey($tableName, $key));
|
||||
}
|
||||
|
||||
public function get($key, $tableName, $connectionResource)
|
||||
{
|
||||
$value = eaccelerator_get($this->getRealKey($tableName, $key));
|
||||
if (!empty($value))
|
||||
{
|
||||
return unserialize($value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function update($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
if ($this->del($key, $tableName, $connectionResource))
|
||||
{
|
||||
return $this->add($key, $value, $ttl, $tableName, $connectionResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getRealKey($tableName, $key)
|
||||
{
|
||||
return $tableName . "-" . $key;
|
||||
}
|
||||
}
|
68
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterFile.php
Executable file
68
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterFile.php
Executable file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
class LtCacheAdapterFile implements LtCacheAdapter
|
||||
{
|
||||
public function connect($hostConf)
|
||||
{
|
||||
$fileStore = new LtStoreFile;
|
||||
$fileStore->prefix = 'LtCache-file';
|
||||
$fileStore->useSerialize = true;
|
||||
$fileStore->init();
|
||||
return $fileStore;
|
||||
}
|
||||
|
||||
public function add($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
if (0 != $ttl)
|
||||
{
|
||||
$ttl += time();
|
||||
}
|
||||
if (true == $connectionResource->add($this->getRealKey($tableName, $key), array("ttl" => $ttl, "value" => $value)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->get($key,$tableName,$connectionResource))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->del($key,$tableName,$connectionResource);
|
||||
return $connectionResource->add($this->getRealKey($tableName, $key), array("ttl" => $ttl, "value" => $value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function del($key, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->del($this->getRealKey($tableName, $key));
|
||||
}
|
||||
|
||||
public function get($key, $tableName, $connectionResource)
|
||||
{
|
||||
$cachedArray = $connectionResource->get($this->getRealKey($tableName, $key));
|
||||
if (is_array($cachedArray) && (0 == $cachedArray["ttl"] || $cachedArray["ttl"] > time()))
|
||||
{
|
||||
return $cachedArray["value"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function update($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
if (0 != $ttl)
|
||||
{
|
||||
$ttl += time();
|
||||
}
|
||||
return $connectionResource->update($this->getRealKey($tableName, $key), array("ttl" => $ttl, "value" => $value));
|
||||
}
|
||||
|
||||
protected function getRealKey($tableName, $key)
|
||||
{
|
||||
return $tableName . "-" . $key;
|
||||
}
|
||||
}
|
33
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcache.php
Executable file
33
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcache.php
Executable file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
class LtCacheAdapterMemcache implements LtCacheAdapter
|
||||
{
|
||||
public function connect($hostConf)
|
||||
{
|
||||
return memcache_connect($hostConf["host"], $hostConf["port"]);
|
||||
}
|
||||
|
||||
public function add($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->add($this->getRealKey($tableName, $key), $value, false, $ttl);
|
||||
}
|
||||
|
||||
public function del($key, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->delete($this->getRealKey($tableName, $key), 0);
|
||||
}
|
||||
|
||||
public function get($key, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->get($this->getRealKey($tableName, $key));
|
||||
}
|
||||
|
||||
public function update($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->replace($this->getRealKey($tableName, $key), $value, false, $ttl);
|
||||
}
|
||||
|
||||
protected function getRealKey($tableName, $key)
|
||||
{
|
||||
return $tableName . "-" . $key;
|
||||
}
|
||||
}
|
35
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcached.php
Executable file
35
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcached.php
Executable file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
class LtCacheAdapterMemcached implements LtCacheAdapter
|
||||
{
|
||||
public function connect($hostConf)
|
||||
{
|
||||
$connectionResource = new Memcached();
|
||||
$connectionResource->addServer($hostConf["host"], $hostConf["port"]);
|
||||
return $connectionResource;
|
||||
}
|
||||
|
||||
public function add($key, $value, $ttl=0, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->add($this->getRealKey($tableName, $key), $value, $ttl);
|
||||
}
|
||||
|
||||
public function del($key, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->delete($this->getRealKey($tableName, $key));
|
||||
}
|
||||
|
||||
public function get($key, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->get($this->getRealKey($tableName, $key));
|
||||
}
|
||||
|
||||
public function update($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->replace($this->getRealKey($tableName, $key), $value, $ttl);
|
||||
}
|
||||
|
||||
protected function getRealKey($tableName, $key)
|
||||
{
|
||||
return $tableName . "-" . $key;
|
||||
}
|
||||
}
|
55
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterPhps.php
Executable file
55
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterPhps.php
Executable file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
class LtCacheAdapterPhps implements LtCacheAdapter
|
||||
{
|
||||
public function connect($hostConf)
|
||||
{
|
||||
$fileStore = new LtStoreFile;
|
||||
if (isset($hostConf['host']) && is_string($hostConf['host']))
|
||||
{
|
||||
$fileStore->cacheFileRoot = $hostConf['host'];
|
||||
$fileStore->prefix = 'Ltcache-phps-';
|
||||
$fileStore->init();
|
||||
return $fileStore;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("Must set [host]");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function add($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->add($this->getRealKey($tableName, $key), $this->valueToString($value), $ttl);
|
||||
}
|
||||
|
||||
public function del($key, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->del($this->getRealKey($tableName, $key));
|
||||
}
|
||||
|
||||
public function get($key, $tableName, $connectionResource)
|
||||
{
|
||||
return $this->stringToValue($connectionResource->get($this->getRealKey($tableName, $key)));
|
||||
}
|
||||
|
||||
public function update($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
return $connectionResource->update($this->getRealKey($tableName, $key), $this->valueToString($value), $ttl);
|
||||
}
|
||||
|
||||
protected function getRealKey($tableName, $key)
|
||||
{
|
||||
return $tableName . "-" . $key;
|
||||
}
|
||||
|
||||
protected function valueToString($value)
|
||||
{
|
||||
return serialize($value);
|
||||
}
|
||||
|
||||
protected function stringToValue($str)
|
||||
{
|
||||
return unserialize($str);
|
||||
}
|
||||
}
|
43
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterXcache.php
Executable file
43
extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterXcache.php
Executable file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
class LtCacheAdapterXcache implements LtCacheAdapter
|
||||
{
|
||||
public function connect($hostConf)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function add($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
return xcache_set($this->getRealKey($tableName, $key), $value, $ttl);
|
||||
}
|
||||
|
||||
public function del($key, $tableName, $connectionResource)
|
||||
{
|
||||
return xcache_unset($this->getRealKey($tableName, $key));
|
||||
}
|
||||
|
||||
public function get($key, $tableName, $connectionResource)
|
||||
{
|
||||
$key = $this->getRealKey($tableName, $key);
|
||||
if (xcache_isset($key))
|
||||
{
|
||||
return xcache_get($key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function update($key, $value, $ttl = 0, $tableName, $connectionResource)
|
||||
{
|
||||
$key = $this->getRealKey($tableName, $key);
|
||||
if (xcache_isset($key))
|
||||
{
|
||||
return xcache_set($key, $value, $ttl);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getRealKey($tableName, $key)
|
||||
{
|
||||
return $tableName . "-" . $key;
|
||||
}
|
||||
}
|
76
extend/app_alipay/lotusphp_runtime/Cache/Cache.php
Executable file
76
extend/app_alipay/lotusphp_runtime/Cache/Cache.php
Executable file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
class LtCache
|
||||
{
|
||||
public $configHandle;
|
||||
|
||||
public $group;
|
||||
public $node;
|
||||
|
||||
protected $ch;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->ch = new LtCacheHandle;
|
||||
$this->ch->configHandle = $this->configHandle;
|
||||
$this->ch->init();
|
||||
$this->ch->group = $this->getGroup();
|
||||
$this->ch->node = $this->getNode();
|
||||
}
|
||||
|
||||
public function getTDG($tableName)
|
||||
{
|
||||
$tdg = new LtCacheTableDataGateway;
|
||||
$tdg->tableName = $tableName;
|
||||
$tdg->ch = $this->ch;
|
||||
return $tdg;
|
||||
}
|
||||
|
||||
public function changeNode($node)
|
||||
{
|
||||
$this->node = $node;
|
||||
$this->dbh->node = $node;
|
||||
}
|
||||
|
||||
protected function getGroup()
|
||||
{
|
||||
if ($this->group)
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
$servers = $this->configHandle->get("cache.servers");
|
||||
if (1 == count($servers))
|
||||
{
|
||||
return key($servers);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getNode()
|
||||
{
|
||||
if ($this->node)
|
||||
{
|
||||
return $this->node;
|
||||
}
|
||||
$servers = $this->configHandle->get("cache.servers");
|
||||
if (1 == count($servers[$this->getGroup()]))
|
||||
{
|
||||
return key($servers[$this->getGroup()]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
14
extend/app_alipay/lotusphp_runtime/Cache/CacheAdapterFactory.php
Executable file
14
extend/app_alipay/lotusphp_runtime/Cache/CacheAdapterFactory.php
Executable file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
class LtCacheAdapterFactory
|
||||
{
|
||||
public function getConnectionAdapter($adapter)
|
||||
{
|
||||
$adapterClassName = "LtCacheAdapter" . ucfirst($adapter);
|
||||
if(!class_exists($adapterClassName))
|
||||
{
|
||||
trigger_error("Invalid adapter: $adapter");
|
||||
return null;
|
||||
}
|
||||
return new $adapterClassName;
|
||||
}
|
||||
}
|
49
extend/app_alipay/lotusphp_runtime/Cache/CacheConfigBuilder.php
Executable file
49
extend/app_alipay/lotusphp_runtime/Cache/CacheConfigBuilder.php
Executable file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
class LtCacheConfigBuilder
|
||||
{
|
||||
protected $servers = array();
|
||||
|
||||
protected $defaultConfig = array(
|
||||
"adapter" => "phps", //apc,xcach,ea; file, phps; memcached
|
||||
//"prefix" => ""
|
||||
//"host" => "localhost", //some ip, hostname
|
||||
//"port" => 3306,
|
||||
);
|
||||
|
||||
public function addSingleHost($hostConfig)
|
||||
{
|
||||
$this->addHost("group_0", "node_0", "master", $hostConfig);
|
||||
}
|
||||
|
||||
public function addHost($groupId, $nodeId = "node_0", $role = "master", $hostConfig)
|
||||
{
|
||||
if (isset($this->servers[$groupId][$nodeId][$role]))
|
||||
{//以相同role的第一个host为默认配置
|
||||
$ref = $this->servers[$groupId][$nodeId][$role][0];
|
||||
}
|
||||
else if ("slave" == $role && isset($this->servers[$groupId][$nodeId]["master"]))
|
||||
{//slave host以master的第一个host为默认配置
|
||||
$ref = $this->servers[$groupId][$nodeId]["master"][0];
|
||||
}
|
||||
else if (isset($this->servers[$groupId]) && count($this->servers[$groupId]))
|
||||
{//以本group第一个node的master第一个host为默认配置
|
||||
$refNode = key($this->servers[$groupId]);
|
||||
$ref = $this->servers[$groupId][$refNode]["master"][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($hostConfig["adapter"]))
|
||||
{
|
||||
trigger_error("No db adapter specified");
|
||||
}
|
||||
$ref = $this->defaultConfig;
|
||||
}
|
||||
$conf = array_merge($ref, $hostConfig);
|
||||
$this->servers[$groupId][$nodeId][$role][] = $conf;
|
||||
}
|
||||
|
||||
public function getServers()
|
||||
{
|
||||
return $this->servers;
|
||||
}
|
||||
}
|
52
extend/app_alipay/lotusphp_runtime/Cache/CacheConnectionManager.php
Executable file
52
extend/app_alipay/lotusphp_runtime/Cache/CacheConnectionManager.php
Executable file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
class LtCacheConnectionManager
|
||||
{
|
||||
public $configHandle;
|
||||
protected $connectionAdapter;
|
||||
|
||||
public function getConnection($group, $node, $role)
|
||||
{
|
||||
if ($connection = $this->getNewConnection($group, $node, $role))
|
||||
{
|
||||
return array(
|
||||
"connectionAdapter" => $this->connectionAdapter,
|
||||
"connectionResource" => $connection
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("no cache server can be connected");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getNewConnection($group, $node, $role)
|
||||
{
|
||||
$servers = $this->configHandle->get("cache.servers");
|
||||
$hostTotal = count($servers[$group][$node][$role]);
|
||||
$hostIndexArray = array_keys($servers[$group][$node][$role]);
|
||||
while ($hostTotal)
|
||||
{
|
||||
$hashNumber = substr(microtime(),7,1) % $hostTotal;
|
||||
$hostConfig = $servers[$group][$node][$role][$hostIndexArray[$hashNumber]];
|
||||
$cacheFactory = new LtCacheAdapterFactory;
|
||||
$this->connectionAdapter = $cacheFactory->getConnectionAdapter($hostConfig["adapter"]);
|
||||
if ($connection = $this->connectionAdapter->connect($hostConfig))
|
||||
{
|
||||
return $connection;
|
||||
}
|
||||
else
|
||||
{
|
||||
//trigger_error('connection fail', E_USER_WARNING);
|
||||
//delete the unavailable server
|
||||
for ($i = $hashNumber; $i < $hostTotal - 1; $i ++)
|
||||
{
|
||||
$hostIndexArray[$i] = $hostIndexArray[$i+1];
|
||||
}
|
||||
unset($hostIndexArray[$hostTotal-1]);
|
||||
$hostTotal --;
|
||||
}//end else
|
||||
}//end while
|
||||
return false;
|
||||
}
|
||||
}
|
52
extend/app_alipay/lotusphp_runtime/Cache/CacheHandle.php
Executable file
52
extend/app_alipay/lotusphp_runtime/Cache/CacheHandle.php
Executable file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
class LtCacheHandle
|
||||
{
|
||||
public $configHandle;
|
||||
public $group;
|
||||
public $node;
|
||||
public $role = "master";
|
||||
public $connectionManager;
|
||||
public $connectionResource;
|
||||
protected $connectionAdapter;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->connectionManager = new LtCacheConnectionManager;
|
||||
$this->connectionManager->configHandle =$this->configHandle;
|
||||
}
|
||||
|
||||
public function add($key, $value, $ttl = 0, $tableName)
|
||||
{
|
||||
$this->initConnection();
|
||||
return $this->connectionAdapter->add($key, $value, $ttl, $tableName, $this->connectionResource);
|
||||
}
|
||||
|
||||
public function del($key, $tableName)
|
||||
{
|
||||
$this->initConnection();
|
||||
return $this->connectionAdapter->del($key, $tableName, $this->connectionResource);
|
||||
}
|
||||
|
||||
public function get($key, $tableName)
|
||||
{
|
||||
$this->initConnection();
|
||||
return $this->connectionAdapter->get($key, $tableName, $this->connectionResource);
|
||||
}
|
||||
|
||||
public function update($key, $value, $ttl = 0, $tableName)
|
||||
{
|
||||
$this->initConnection();
|
||||
return $this->connectionAdapter->update($key, $value, $ttl, $tableName, $this->connectionResource);
|
||||
}
|
||||
|
||||
protected function initConnection()
|
||||
{
|
||||
$connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role);
|
||||
$this->connectionAdapter = $connectionInfo["connectionAdapter"];
|
||||
$this->connectionResource = $connectionInfo["connectionResource"];
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
class LtCacheTableDataGateway
|
||||
{
|
||||
public $tableName;
|
||||
|
||||
public $ch;
|
||||
|
||||
public function add($key, $value, $ttl = 0)
|
||||
{
|
||||
return $this->ch->add($key, $value, $ttl, $this->tableName);
|
||||
}
|
||||
|
||||
public function del($key)
|
||||
{
|
||||
return $this->ch->del($key, $this->tableName);
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
{
|
||||
return $this->ch->get($key, $this->tableName);
|
||||
}
|
||||
|
||||
public function update($key, $value, $ttl = 0)
|
||||
{
|
||||
return $this->ch->update($key, $value, $ttl, $this->tableName);
|
||||
}
|
||||
}
|
91
extend/app_alipay/lotusphp_runtime/Captcha/Captcha.php
Executable file
91
extend/app_alipay/lotusphp_runtime/Captcha/Captcha.php
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
class LtCaptcha
|
||||
{
|
||||
public $configHandle;
|
||||
public $storeHandle;
|
||||
|
||||
public $imageEngine;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if (!is_object($this->storeHandle))
|
||||
{
|
||||
$this->storeHandle = new LtStoreFile;
|
||||
$this->storeHandle->prefix = 'LtCaptcha-seed-';
|
||||
$this->storeHandle->init();
|
||||
}
|
||||
}
|
||||
|
||||
public function getImageResource($seed)
|
||||
{
|
||||
if (empty($seed))
|
||||
{
|
||||
trigger_error("empty seed");
|
||||
return false;
|
||||
}
|
||||
if (!is_object($this->imageEngine))
|
||||
{
|
||||
if ($imageEngine = $this->configHandle->get("captcha.image_engine"))
|
||||
{
|
||||
if (class_exists($imageEngine))
|
||||
{
|
||||
$this->imageEngine = new $imageEngine;
|
||||
$this->imageEngine->conf = $this->configHandle->get("captcha.image_engine_conf");
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("captcha.image_engine : $imageEngine not exists");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("empty captcha.image_engine");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$word = $this->generateRandCaptchaWord($seed);
|
||||
$this->storeHandle->add($seed, $word);
|
||||
return $this->imageEngine->drawImage($word);
|
||||
}
|
||||
|
||||
public function verify($seed, $userInput)
|
||||
{
|
||||
if ($word = $this->storeHandle->get($seed))
|
||||
{
|
||||
$this->storeHandle->del($seed);
|
||||
return $userInput === $word;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function generateRandCaptchaWord()
|
||||
{
|
||||
$allowChars = $this->configHandle->get("captcha.allow_chars");
|
||||
$length = $this->configHandle->get("captcha.length");
|
||||
$allowedSymbolsLength = strlen($allowChars) - 1;
|
||||
$captchaWord = "";
|
||||
for ($i = 0; $i < $length; $i ++)
|
||||
{
|
||||
$captchaWord .= $allowChars[mt_rand(0, $allowedSymbolsLength)];
|
||||
}
|
||||
return $captchaWord;
|
||||
}
|
||||
}
|
197
extend/app_alipay/lotusphp_runtime/Captcha/CaptchaImageEngine.php
Executable file
197
extend/app_alipay/lotusphp_runtime/Captcha/CaptchaImageEngine.php
Executable file
@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* Lotus Captcha component is inspired by "cool-php-captcha" project
|
||||
* http://code.google.com/p/cool-php-captcha
|
||||
*/
|
||||
class LtCaptchaImageEngine
|
||||
{
|
||||
public $conf;
|
||||
|
||||
protected $maxWordLength = 9;
|
||||
|
||||
/**
|
||||
* * Background color in RGB-array
|
||||
*/
|
||||
protected $backgroundColor = array(255, 255, 255);
|
||||
|
||||
/**
|
||||
* * Foreground colors in RGB-array
|
||||
*/
|
||||
protected $colors = array(
|
||||
array(27, 78, 181), // blue
|
||||
array(22, 163, 35), // green
|
||||
array(214, 36, 7), // red
|
||||
);
|
||||
|
||||
/**
|
||||
* * Shadow color in RGB-array or null
|
||||
*/
|
||||
protected $shadowColor = null; //array(0, 0, 0);
|
||||
|
||||
/**
|
||||
* Font configuration
|
||||
*
|
||||
* - font: TTF file
|
||||
* - spacing: relative pixel space between character
|
||||
* - minSize: min font size
|
||||
* - maxSize: max font size
|
||||
*/
|
||||
protected $fonts = array('Antykwa' => array('spacing' => -3, 'minSize' => 27, 'maxSize' => 30, 'font' => 'AntykwaBold.ttf'),
|
||||
'Candice' => array('spacing' => -1.5, 'minSize' => 28, 'maxSize' => 31, 'font' => 'Candice.ttf'),
|
||||
'DingDong' => array('spacing' => -2, 'minSize' => 24, 'maxSize' => 30, 'font' => 'Ding-DongDaddyO.ttf'),
|
||||
'Duality' => array('spacing' => -2, 'minSize' => 30, 'maxSize' => 38, 'font' => 'Duality.ttf'),
|
||||
'Jura' => array('spacing' => -2, 'minSize' => 28, 'maxSize' => 32, 'font' => 'Jura.ttf'),
|
||||
'StayPuft' => array('spacing' => -1.5, 'minSize' => 28, 'maxSize' => 32, 'font' => 'StayPuft.ttf'),
|
||||
'Times' => array('spacing' => -2, 'minSize' => 28, 'maxSize' => 34, 'font' => 'TimesNewRomanBold.ttf'),
|
||||
'VeraSans' => array('spacing' => -1, 'minSize' => 20, 'maxSize' => 28, 'font' => 'VeraSansBold.ttf'),
|
||||
);
|
||||
|
||||
/**
|
||||
* * Wave configuracion in X and Y axes
|
||||
*/
|
||||
protected $Yperiod = 12;
|
||||
protected $Yamplitude = 14;
|
||||
protected $Xperiod = 11;
|
||||
protected $Xamplitude = 5;
|
||||
|
||||
/**
|
||||
* * GD image
|
||||
*/
|
||||
protected $im;
|
||||
|
||||
public function drawImage($text)
|
||||
{
|
||||
/**
|
||||
* * Initialization
|
||||
*/
|
||||
$this->ImageAllocate();
|
||||
|
||||
$fontcfg = $this->fonts[array_rand($this->fonts)];
|
||||
$this->WriteText($text, $fontcfg);
|
||||
|
||||
/**
|
||||
* * Transformations
|
||||
*/
|
||||
$this->WaveImage();
|
||||
if ($this->conf['blur'] && function_exists('imagefilter'))
|
||||
{
|
||||
imagefilter($this->im, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
}
|
||||
$this->ReduceImage();
|
||||
return $this->im;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the image resources
|
||||
*/
|
||||
protected function ImageAllocate()
|
||||
{
|
||||
// Cleanup
|
||||
if (!empty($this->im))
|
||||
{
|
||||
imagedestroy($this->im);
|
||||
}
|
||||
|
||||
$this->im = imagecreatetruecolor($this->conf['width'] * $this->conf['scale'], $this->conf['height'] * $this->conf['scale']);
|
||||
// Background color
|
||||
$this->GdBgColor = imagecolorallocate($this->im,
|
||||
$this->backgroundColor[0],
|
||||
$this->backgroundColor[1],
|
||||
$this->backgroundColor[2]
|
||||
);
|
||||
imagefilledrectangle($this->im, 0, 0, $this->conf['width'] * $this->conf['scale'], $this->conf['height'] * $this->conf['scale'], $this->GdBgColor);
|
||||
// Foreground color
|
||||
$color = $this->colors[mt_rand(0, sizeof($this->colors)-1)];
|
||||
$this->GdFgColor = imagecolorallocate($this->im, $color[0], $color[1], $color[2]);
|
||||
// Shadow color
|
||||
if (!empty($this->shadowColor) && is_array($this->shadowColor) && sizeof($this->shadowColor) >= 3)
|
||||
{
|
||||
$this->GdShadowColor = imagecolorallocate($this->im,
|
||||
$this->shadowColor[0],
|
||||
$this->shadowColor[1],
|
||||
$this->shadowColor[2]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Text insertion
|
||||
*/
|
||||
protected function WriteText($text, $fontcfg = array())
|
||||
{
|
||||
if (empty($fontcfg))
|
||||
{
|
||||
// Select the font configuration
|
||||
$fontcfg = $this->fonts[array_rand($this->fonts)];
|
||||
}
|
||||
// Full path of font file
|
||||
$fontfile = dirname(__FILE__) . '/fonts/' . $fontcfg['font'];
|
||||
|
||||
/**
|
||||
* * Increase font-size for shortest words: 9% for each glyp missing
|
||||
*/
|
||||
$lettersMissing = $this->maxWordLength - strlen($text);
|
||||
$fontSizefactor = 1 + ($lettersMissing * 0.09);
|
||||
// Text generation (char by char)
|
||||
$x = 20 * $this->conf['scale'];
|
||||
$y = round(($this->conf['height'] * 27 / 40) * $this->conf['scale']);
|
||||
$length = strlen($text);
|
||||
for ($i = 0; $i < $length; $i++)
|
||||
{
|
||||
$degree = rand($this->conf['max_rotation'] * -1, $this->conf['max_rotation']);
|
||||
$fontsize = rand($fontcfg['minSize'], $fontcfg['maxSize']) * $this->conf['scale'] * $fontSizefactor;
|
||||
$letter = substr($text, $i, 1);
|
||||
|
||||
if ($this->shadowColor)
|
||||
{
|
||||
$coords = imagettftext($this->im, $fontsize, $degree,
|
||||
$x + $this->conf['scale'], $y + $this->conf['scale'],
|
||||
$this->GdShadowColor, $fontfile, $letter);
|
||||
}
|
||||
$coords = imagettftext($this->im, $fontsize, $degree,
|
||||
$x, $y,
|
||||
$this->GdFgColor, $fontfile, $letter);
|
||||
$x += ($coords[2] - $x) + ($fontcfg['spacing'] * $this->conf['scale']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wave filter
|
||||
*/
|
||||
protected function WaveImage()
|
||||
{
|
||||
// X-axis wave generation
|
||||
$xp = $this->conf['scale'] * $this->Xperiod * rand(1, 3);
|
||||
$k = rand(0, 100);
|
||||
for ($i = 0; $i < ($this->conf['width'] * $this->conf['scale']); $i++)
|
||||
{
|
||||
imagecopy($this->im, $this->im,
|
||||
$i-1, sin($k + $i / $xp) * ($this->conf['scale'] * $this->Xamplitude),
|
||||
$i, 0, 1, $this->conf['height'] * $this->conf['scale']);
|
||||
}
|
||||
// Y-axis wave generation
|
||||
$k = rand(0, 100);
|
||||
$yp = $this->conf['scale'] * $this->Yperiod * rand(1, 2);
|
||||
for ($i = 0; $i < ($this->conf['height'] * $this->conf['scale']); $i++)
|
||||
{
|
||||
imagecopy($this->im, $this->im,
|
||||
sin($k + $i / $yp) * ($this->conf['scale'] * $this->Yamplitude), $i-1,
|
||||
0, $i, $this->conf['width'] * $this->conf['scale'], 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the image to the final size
|
||||
*/
|
||||
protected function ReduceImage()
|
||||
{
|
||||
$imResampled = imagecreatetruecolor($this->conf['width'], $this->conf['height']);
|
||||
imagecopyresampled($imResampled, $this->im,
|
||||
0, 0, 0, 0,
|
||||
$this->conf['width'], $this->conf['height'],
|
||||
$this->conf['width'] * $this->conf['scale'], $this->conf['height'] * $this->conf['scale']
|
||||
);
|
||||
imagedestroy($this->im);
|
||||
$this->im = $imResampled;
|
||||
}
|
||||
}
|
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/AntykwaBold.ttf
Executable file
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/AntykwaBold.ttf
Executable file
Binary file not shown.
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/Candice.ttf
Executable file
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/Candice.ttf
Executable file
Binary file not shown.
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/Ding-DongDaddyO.ttf
Executable file
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/Ding-DongDaddyO.ttf
Executable file
Binary file not shown.
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/Duality.ttf
Executable file
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/Duality.ttf
Executable file
Binary file not shown.
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/Jura.ttf
Executable file
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/Jura.ttf
Executable file
Binary file not shown.
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/StayPuft.ttf
Executable file
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/StayPuft.ttf
Executable file
Binary file not shown.
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/TimesNewRomanBold.ttf
Executable file
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/TimesNewRomanBold.ttf
Executable file
Binary file not shown.
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/VeraSansBold.ttf
Executable file
BIN
extend/app_alipay/lotusphp_runtime/Captcha/fonts/VeraSansBold.ttf
Executable file
Binary file not shown.
84
extend/app_alipay/lotusphp_runtime/Config.php
Executable file
84
extend/app_alipay/lotusphp_runtime/Config.php
Executable file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
class LtConfig
|
||||
{
|
||||
public $storeHandle;
|
||||
protected $conf;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (!is_object($this->storeHandle))
|
||||
{
|
||||
$this->storeHandle = new LtStoreMemory;
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
//don't removeme, I am the placeholder
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
{
|
||||
$storedConfig = $this->storeHandle->get($key);
|
||||
if ($storedConfig instanceof LtConfigExpression)
|
||||
{
|
||||
$str = $storedConfig->__toString();
|
||||
if ($storedConfig->autoRetrived)
|
||||
{
|
||||
eval("\$value=$str;");
|
||||
return $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $storedConfig;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 警告
|
||||
* 这里会包含两个用户定义的配置文件,为了不和配置文件里的变量名发生重名
|
||||
* 本方法不定义和使用变量名
|
||||
*/
|
||||
public function loadConfigFile($configFile)
|
||||
{
|
||||
if (0 == $this->storeHandle->get(".config_total"))
|
||||
{
|
||||
if (null === $configFile || !is_file($configFile))
|
||||
{
|
||||
trigger_error("no config file specified or invalid config file");
|
||||
}
|
||||
$this->conf = include($configFile);
|
||||
if (!is_array($this->conf))
|
||||
{
|
||||
trigger_error("config file do NOT return array: $configFile");
|
||||
}
|
||||
elseif (!empty($this->conf))
|
||||
{
|
||||
if (0 == $this->storeHandle->get(".config_total"))
|
||||
{
|
||||
$this->storeHandle->add(".config_total", 0);
|
||||
}
|
||||
$this->addConfig($this->conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function addConfig($configArray)
|
||||
{
|
||||
foreach($configArray as $key => $value)
|
||||
{
|
||||
if (!$this->storeHandle->update($key, $value))
|
||||
{
|
||||
if ($this->storeHandle->add($key, $value))
|
||||
{
|
||||
$this->storeHandle->update(".config_total", $this->storeHandle->get(".config_total") + 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
extend/app_alipay/lotusphp_runtime/ConfigExpression.php
Executable file
17
extend/app_alipay/lotusphp_runtime/ConfigExpression.php
Executable file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
class LtConfigExpression
|
||||
{
|
||||
private $_expression;
|
||||
public $autoRetrived;
|
||||
|
||||
public function __construct($string, $autoRetrived = true)
|
||||
{
|
||||
$this->_expression = (string) $string;
|
||||
$this->autoRetrived = $autoRetrived;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->_expression;
|
||||
}
|
||||
}
|
136
extend/app_alipay/lotusphp_runtime/Cookie/Cookie.php
Executable file
136
extend/app_alipay/lotusphp_runtime/Cookie/Cookie.php
Executable file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
class LtCookie
|
||||
{
|
||||
public $configHandle;
|
||||
private $secretKey;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->secretKey = $this->configHandle->get("cookie.secret_key");
|
||||
if(empty($this->secretKey))
|
||||
{
|
||||
trigger_error("cookie.secret_key empty");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt the encrypted cookie
|
||||
*
|
||||
* @param string $encryptedText
|
||||
* @return string
|
||||
*/
|
||||
protected function decrypt($encryptedText)
|
||||
{
|
||||
$key = $this->secretKey;
|
||||
$cryptText = base64_decode($encryptedText);
|
||||
$ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
|
||||
$iv = mcrypt_create_iv($ivSize, MCRYPT_RAND);
|
||||
$decryptText = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $cryptText, MCRYPT_MODE_ECB, $iv);
|
||||
return trim($decryptText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt the cookie
|
||||
*
|
||||
* @param string $plainText
|
||||
* @return string
|
||||
*/
|
||||
protected function encrypt($plainText)
|
||||
{
|
||||
$key = $this->secretKey;
|
||||
$ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
|
||||
$iv = mcrypt_create_iv($ivSize, MCRYPT_RAND);
|
||||
$encryptText = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $plainText, MCRYPT_MODE_ECB, $iv);
|
||||
return trim(base64_encode($encryptText));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cookie value to deleted with $name
|
||||
*
|
||||
* @param array $args
|
||||
* @return boolean
|
||||
*/
|
||||
public function delCookie($name, $path = '/', $domain = null)
|
||||
{
|
||||
if (isset($_COOKIE[$name]))
|
||||
{
|
||||
if (is_array($_COOKIE[$name]))
|
||||
{
|
||||
foreach($_COOKIE[$name] as $k => $v)
|
||||
{
|
||||
setcookie($name . '[' . $k . ']', '', time() - 86400, $path, $domain);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setcookie($name, '', time() - 86400, $path, $domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cookie value with $name
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCookie($name)
|
||||
{
|
||||
$ret = null;
|
||||
if (isset($_COOKIE[$name]))
|
||||
{
|
||||
if (is_array($_COOKIE[$name]))
|
||||
{
|
||||
$ret = array();
|
||||
foreach($_COOKIE[$name] as $k => $v)
|
||||
{
|
||||
$v = $this->decrypt($v);
|
||||
$ret[$k] = $v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = $this->decrypt($_COOKIE[$name]);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cookie
|
||||
*
|
||||
* @param array $args
|
||||
* @return boolean
|
||||
*/
|
||||
public function setCookie($name, $value = '', $expire = null, $path = '/', $domain = null, $secure = 0)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
foreach($value as $k => $v)
|
||||
{
|
||||
$v = $this->encrypt($v);
|
||||
setcookie($name . '[' . $k . ']', $v, $expire, $path, $domain, $secure);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = $this->encrypt($value);
|
||||
setcookie($name, $value, $expire, $path, $domain, $secure);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
interface LtDbConnectionAdapter
|
||||
{
|
||||
/**
|
||||
* @todo 兼容使用Unix Domain Socket方式连接数据库(即:可以不指定port)
|
||||
*/
|
||||
public function connect($connConf);
|
||||
public function exec($sql, $connResource);
|
||||
public function query($sql, $connResource);
|
||||
public function lastInsertId($connResource);
|
||||
public function escape($sql, $connResource);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
class LtDbConnectionAdapterMysql implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
return mysql_connect($connConf["host"] . ":" . $connConf["port"], $connConf["username"], $connConf["password"]);
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
return mysql_query($sql, $connResource) ? mysql_affected_rows($connResource) : false;
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
$result = mysql_query($sql, $connResource);
|
||||
$rows = array();
|
||||
while($row = mysql_fetch_assoc($result))
|
||||
{
|
||||
$rows[] = $row;
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
return mysql_insert_id($connResource);
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
return mysql_real_escape_string($sql, $connResource);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
class LtDbConnectionAdapterMysqli implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
return new mysqli($connConf["host"], $connConf["username"], $connConf["password"], $connConf["dbname"], $connConf["port"]);
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
$connResource->query($sql);
|
||||
return $connResource->affected_rows;
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
$rows = array();
|
||||
$result = $connResource->query($sql);
|
||||
while($row = $result->fetch_assoc())
|
||||
{
|
||||
$rows[] = $row;
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
return $connResource->insert_id;
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
return mysqli_real_escape_string($connResource, $sql);
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
class LtDbConnectionAdapterPdo implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
// $option = array(PDO::ATTR_PERSISTENT => true);
|
||||
if (isset($connConf['pconnect']) && true == $connConf['pconnect'])
|
||||
{
|
||||
$option[PDO::ATTR_PERSISTENT] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$option[PDO::ATTR_PERSISTENT] = false;
|
||||
}
|
||||
switch ($connConf['adapter'])
|
||||
{
|
||||
case "pdo_mysql":
|
||||
$dsn = "mysql:host={$connConf['host']};dbname={$connConf['dbname']}";
|
||||
break;
|
||||
case "pdo_sqlite":
|
||||
$connConf["host"] = rtrim($connConf["host"], '\\/') . DIRECTORY_SEPARATOR;
|
||||
if (!is_dir($connConf["host"]))
|
||||
{
|
||||
if (!@mkdir($connConf["host"], 0777, true))
|
||||
{
|
||||
trigger_error("Can not create {$connConf['host']}");
|
||||
}
|
||||
}
|
||||
$dsn = "{$connConf['sqlite_version']}:{$connConf['host']}{$connConf['dbname']}";
|
||||
break;
|
||||
case "pdo_pgsql":
|
||||
$dsn = "pgsql:host={$connConf['host']} port={$connConf['port']} dbname={$connConf['dbname']} user={$connConf['username']} password={$connConf['password']}";
|
||||
break;
|
||||
case "odbc":
|
||||
$dsn = "odbc:" . $connConf["host"];
|
||||
break;
|
||||
}
|
||||
return new PDO($dsn, $connConf['username'], $connConf['password'], $option);
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
return $connResource->exec($sql);
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
return $connResource->query($sql)->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @todo pgsql support
|
||||
*/
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
return $connResource->lastInsertId();
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
// quote返回值带最前面和最后面的单引号, 这里去掉, DbHandler中加
|
||||
return trim($connResource->quote($sql), "'");
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
class LtDbConnectionAdapterPgsql implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
if (isset($connConf['pconnect']) && true == $connConf['pconnect'])
|
||||
{
|
||||
$func = 'pg_pconnect';
|
||||
}
|
||||
else
|
||||
{
|
||||
$func = 'pg_connect';
|
||||
}
|
||||
return $func("host={$connConf['host']} port={$connConf['port']} user={$connConf['username']} password={$connConf['password']}");
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
$result = pg_query($connResource, $sql);
|
||||
return pg_affected_rows($result);
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
$result = pg_query($connResource, $sql);
|
||||
return pg_fetch_all($result);
|
||||
}
|
||||
|
||||
// SELECT CURRVAL(
|
||||
// pg_get_serial_sequence('my_tbl_name','id_col_name'));"
|
||||
// ------------------------------------------------------
|
||||
// CREATE FUNCTION last_insert_id() RETURNS bigint AS $$
|
||||
// SELECT lastval();
|
||||
// $$ LANGUAGE SQL VOLATILE;
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
$result = pg_query($connResource, "SELECT lastval()");
|
||||
$row = pg_fetch_array($result, 0, PGSQL_NUM);
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
return pg_escape_string($sql);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Sqlite 预定义了类 SQLiteDatabase 本实现没有使用。
|
||||
* 这里使用的全部是过程函数。
|
||||
* 无论是函数还是类,本实现只支持sqlite的2.x系列版本。
|
||||
* php5.3新增扩展sqlite3用来支持3.x版本。
|
||||
* PDO则同时支持2.x和3.x版本。
|
||||
*/
|
||||
class LtDbConnectionAdapterSqlite implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
if (isset($connConf['pconnect']) && true == $connConf['pconnect'])
|
||||
{
|
||||
$func = 'sqlite_popen';
|
||||
}
|
||||
else
|
||||
{
|
||||
$func = 'sqlite_open';
|
||||
}
|
||||
$connConf["host"] = rtrim($connConf["host"], '\\/') . DIRECTORY_SEPARATOR;
|
||||
if(!is_dir($connConf["host"]))
|
||||
{
|
||||
if(!@mkdir($connConf["host"], 0777, true))
|
||||
{
|
||||
trigger_error("Can not create {$connConf['host']}");
|
||||
}
|
||||
}
|
||||
$error = '';
|
||||
$connResource = $func($connConf["host"] . $connConf["dbname"], 0666, $error);
|
||||
if (!$connResource)
|
||||
{
|
||||
trigger_error($error, E_USER_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $connResource;
|
||||
}
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
if(empty($sql))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
sqlite_exec($connResource, $sql);
|
||||
// echo '<pre>';
|
||||
// print_r(debug_backtrace());
|
||||
// debug_print_backtrace();
|
||||
// echo '</pre>';
|
||||
// delete from table 结果为0,原因未知。
|
||||
// 使用 delete from table where 1 能返回正确结果
|
||||
return sqlite_changes($connResource);
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
$result = sqlite_query($connResource, $sql, SQLITE_ASSOC);
|
||||
return sqlite_fetch_all($result, SQLITE_ASSOC);
|
||||
}
|
||||
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
return sqlite_last_insert_rowid($connResource);
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
return sqlite_escape_string($sql);
|
||||
}
|
||||
}
|
31
extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapter.php
Executable file
31
extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapter.php
Executable file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
interface LtDbSqlAdapter
|
||||
{
|
||||
/**
|
||||
* Return SQL statements
|
||||
*/
|
||||
public function setCharset($charset);
|
||||
public function setSchema($schema);
|
||||
|
||||
public function showSchemas($database);
|
||||
public function showTables($schema);
|
||||
public function showFields($table);
|
||||
|
||||
public function beginTransaction();
|
||||
public function commit();
|
||||
public function rollBack();
|
||||
|
||||
public function limit($limit, $offset);
|
||||
|
||||
/**
|
||||
* Retrive recordset
|
||||
*/
|
||||
public function getSchemas($queryResult);
|
||||
public function getTables($queryResult);
|
||||
public function getFields($queryResult);
|
||||
|
||||
/**
|
||||
* Parse SQL
|
||||
*/
|
||||
public function detectQueryType($sql);
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
class LtDbSqlAdapterMysql implements LtDbSqlAdapter
|
||||
{
|
||||
public function setCharset($charset)
|
||||
{
|
||||
return "SET NAMES " . str_replace('-', '', $charset);
|
||||
}
|
||||
public function setSchema($schema)
|
||||
{
|
||||
return "USE $schema";
|
||||
}
|
||||
|
||||
public function showSchemas($database)
|
||||
{
|
||||
return "SHOW DATABASES";
|
||||
}
|
||||
public function showTables($schema)
|
||||
{
|
||||
return "SHOW TABLES";
|
||||
}
|
||||
public function showFields($table)
|
||||
{
|
||||
return "DESCRIBE $table";
|
||||
}
|
||||
|
||||
public function beginTransaction()
|
||||
{
|
||||
return "START TRANSACTION";
|
||||
}
|
||||
public function commit()
|
||||
{
|
||||
return "COMMIT";
|
||||
}
|
||||
public function rollBack()
|
||||
{
|
||||
return "ROLLBACK";
|
||||
}
|
||||
|
||||
public function limit($limit, $offset)
|
||||
{
|
||||
return " LIMIT $limit OFFSET $offset";
|
||||
}
|
||||
public function getSchemas($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getTables($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getFields($queryResult)
|
||||
{
|
||||
foreach ($queryResult as $key => $value)
|
||||
{
|
||||
$fields[$value['Field']]['name'] = $value['Field'];
|
||||
$fields[$value['Field']]['type'] = $value['Type'];
|
||||
/*
|
||||
* not null is NO or empty, null is YES
|
||||
*/
|
||||
$fields[$value['Field']]['notnull'] = (bool) ($value['Null'] != 'YES');
|
||||
$fields[$value['Field']]['default'] = $value['Default'];
|
||||
$fields[$value['Field']]['primary'] = (strtolower($value['Key']) == 'pri');
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
public function detectQueryType($sql)
|
||||
{
|
||||
if (preg_match("/^\s*SELECT|^\s*EXPLAIN|^\s*SHOW|^\s*DESCRIBE/i", $sql))
|
||||
{
|
||||
$ret = 'SELECT';
|
||||
}
|
||||
else if (preg_match("/^\s*INSERT/i", $sql))
|
||||
{
|
||||
$ret = 'INSERT';
|
||||
}
|
||||
else if (preg_match("/^\s*UPDATE|^\s*DELETE|^\s*REPLACE/i", $sql))
|
||||
{
|
||||
$ret = 'CHANGE_ROWS';
|
||||
}
|
||||
else if (preg_match("/^\s*USE|^\s*SET/i", $sql))
|
||||
{
|
||||
$ret = 'SET_SESSION_VAR';
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = 'OTHER';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
class LtDbSqlAdapterPgsql implements LtDbSqlAdapter
|
||||
{
|
||||
public function setCharset($charset)
|
||||
{
|
||||
return "SET client_encoding TO '$charset'";
|
||||
}
|
||||
public function setSchema($schema)
|
||||
{
|
||||
return "SET search_path TO $schema";
|
||||
}
|
||||
|
||||
public function beginTransaction()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
public function commit()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
public function rollBack()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public function showSchemas($database)
|
||||
{
|
||||
|
||||
}
|
||||
public function showTables($schema)
|
||||
{
|
||||
return "SELECT case when n.nspname='public' then c.relname else n.nspname||'.'||c.relname end as relname
|
||||
FROM pg_class c join pg_namespace n on (c.relnamespace=n.oid)
|
||||
WHERE c.relkind = 'r'
|
||||
AND n.nspname NOT IN ('information_schema','pg_catalog')
|
||||
AND n.nspname NOT LIKE 'pg_temp%'
|
||||
AND n.nspname NOT LIKE 'pg_toast%'
|
||||
ORDER BY relname";
|
||||
}
|
||||
public function showFields($table)
|
||||
{
|
||||
return "SELECT a.attnum, a.attname AS field, t.typname AS type,
|
||||
format_type(a.atttypid, a.atttypmod) AS complete_type,
|
||||
a.attnotnull AS isnotnull,
|
||||
( SELECT 't' FROM pg_index
|
||||
WHERE c.oid = pg_index.indrelid
|
||||
AND pg_index.indkey[0] = a.attnum
|
||||
AND pg_index.indisprimary = 't') AS pri,
|
||||
(SELECT pg_attrdef.adsrc FROM pg_attrdef
|
||||
WHERE c.oid = pg_attrdef.adrelid
|
||||
AND pg_attrdef.adnum=a.attnum) AS default
|
||||
FROM pg_attribute a, pg_class c, pg_type t
|
||||
WHERE c.relname = '$table'
|
||||
AND a.attnum > 0
|
||||
AND a.attrelid = c.oid
|
||||
AND a.atttypid = t.oid
|
||||
ORDER BY a.attnum";
|
||||
}
|
||||
|
||||
public function limit($limit, $offset)
|
||||
{
|
||||
return " LIMIT $limit OFFSET $offset";
|
||||
}
|
||||
|
||||
public function getSchemas($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getTables($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getFields($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function detectQueryType($sql)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
120
extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterSqlite.php
Executable file
120
extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterSqlite.php
Executable file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
class LtDbSqlAdapterSqlite implements LtDbSqlAdapter
|
||||
{
|
||||
public function setCharset($charset)
|
||||
{
|
||||
// return 'PRAGMA encoding = "' . $charset . '"';
|
||||
return '';
|
||||
}
|
||||
public function setSchema($schema)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function beginTransaction()
|
||||
{
|
||||
return 'BEGIN TRANSACTION';
|
||||
}
|
||||
|
||||
public function commit()
|
||||
{
|
||||
return 'COMMIT TRANSACTION';
|
||||
}
|
||||
|
||||
public function rollBack()
|
||||
{
|
||||
return 'ROLLBACK TRANSACTION';
|
||||
}
|
||||
|
||||
public function showSchemas($database)
|
||||
{
|
||||
//return "SHOW DATABASES";
|
||||
return '';
|
||||
}
|
||||
public function showTables($schema)
|
||||
{
|
||||
// 临时表及其索引不在 SQLITE_MASTER 表中而在 SQLITE_TEMP_MASTER 中出现
|
||||
return "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name";
|
||||
}
|
||||
public function showFields($table)
|
||||
{
|
||||
return "PRAGMA table_info('" . $table . "')";
|
||||
|
||||
}
|
||||
public function limit($limit, $offset)
|
||||
{
|
||||
return " LIMIT $limit OFFSET $offset";
|
||||
}
|
||||
|
||||
public function getSchemas($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getTables($queryResult)
|
||||
{
|
||||
return $queryResult;
|
||||
}
|
||||
public function getFields($queryResult)
|
||||
{
|
||||
$fields = array();
|
||||
foreach ($queryResult as $key => $value)
|
||||
{
|
||||
// 字段名
|
||||
$fields[$value['name']]['name'] = $value['name'];
|
||||
// 字段类型
|
||||
$fulltype = $value['type'];
|
||||
$size = null;
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
if (preg_match('/^([^\(]+)\(\s*(\d+)\s*,\s*(\d+)\s*\)$/',$fulltype, $matches))
|
||||
{
|
||||
$type = $matches[1];
|
||||
$precision = $matches[2];
|
||||
$scale = $matches[3]; // aka precision
|
||||
}
|
||||
elseif (preg_match('/^([^\(]+)\(\s*(\d+)\s*\)$/',$fulltype, $matches))
|
||||
{
|
||||
$type = $matches[1];
|
||||
$size = $matches[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = $fulltype;
|
||||
}
|
||||
|
||||
$fields[$value['name']]['type'] = $type;
|
||||
/**
|
||||
* not null is 99, null is 0
|
||||
*/
|
||||
$fields[$value['name']]['notnull'] = (bool) ($value['notnull'] != 0);
|
||||
$fields[$value['name']]['default'] = $value['dflt_value'];
|
||||
$fields[$value['name']]['primary'] = (bool) ($value['pk'] == 1 && strtoupper($fulltype) == 'INTEGER');
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
public function detectQueryType($sql)
|
||||
{
|
||||
if (preg_match("/^\s*SELECT|^\s*PRAGMA/i", $sql))
|
||||
{
|
||||
$ret = 'SELECT';
|
||||
}
|
||||
else if (preg_match("/^\s*INSERT/i", $sql))
|
||||
{
|
||||
$ret = 'INSERT';
|
||||
}
|
||||
else if (preg_match("/^\s*UPDATE|^\s*DELETE|^\s*REPLACE/i", $sql))
|
||||
{
|
||||
$ret = 'CHANGE_ROWS';
|
||||
}
|
||||
else if (preg_match("/^\s*USE|^\s*SET/i", $sql))
|
||||
{
|
||||
$ret = 'SET_SESSION_VAR';
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = 'OTHER';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
91
extend/app_alipay/lotusphp_runtime/DB/Db.php
Executable file
91
extend/app_alipay/lotusphp_runtime/DB/Db.php
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
class LtDb
|
||||
{
|
||||
public $configHandle;
|
||||
|
||||
public $group;
|
||||
public $node;
|
||||
protected $dbh;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->dbh = new LtDbHandle;
|
||||
$this->dbh->configHandle = $this->configHandle;
|
||||
$this->dbh->group = $this->getGroup();
|
||||
$this->dbh->node = $this->getNode();
|
||||
$this->dbh->init();
|
||||
}
|
||||
|
||||
public function getDbHandle()
|
||||
{
|
||||
return $this->dbh;
|
||||
}
|
||||
|
||||
public function getTDG($tableName)
|
||||
{
|
||||
$tg = new LtDbTableDataGateway;
|
||||
$tg->configHandle = $this->configHandle;
|
||||
$tg->tableName = $tableName;
|
||||
$tg->createdColumn = 'created';
|
||||
$tg->modifiedColumn = 'modified';
|
||||
$tg->dbh = $this->dbh;
|
||||
return $tg;
|
||||
}
|
||||
|
||||
public function getSqlMapClient()
|
||||
{
|
||||
$smc = new LtDbSqlMapClient;
|
||||
$smc->configHandle = $this->configHandle;
|
||||
$smc->dbh = $this->dbh;
|
||||
return $smc;
|
||||
}
|
||||
|
||||
public function changeNode($node)
|
||||
{
|
||||
$this->node = $node;
|
||||
$this->dbh->node = $node;
|
||||
}
|
||||
|
||||
protected function getGroup()
|
||||
{
|
||||
if ($this->group)
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
$servers = $this->configHandle->get("db.servers");
|
||||
if (1 == count($servers))
|
||||
{
|
||||
return key($servers);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getNode()
|
||||
{
|
||||
if ($this->node)
|
||||
{
|
||||
return $this->node;
|
||||
}
|
||||
$servers = $this->configHandle->get("db.servers");
|
||||
if (1 == count($servers[$this->getGroup()]))
|
||||
{
|
||||
return key($servers[$this->getGroup()]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
15
extend/app_alipay/lotusphp_runtime/DB/DbAdapterFactory.php
Executable file
15
extend/app_alipay/lotusphp_runtime/DB/DbAdapterFactory.php
Executable file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
class LtDbAdapterFactory
|
||||
{
|
||||
public function getConnectionAdapter($connectionAdapterType)
|
||||
{
|
||||
$LtDbConnectionAdapter = "LtDbConnectionAdapter" . ucfirst($connectionAdapterType);
|
||||
return new $LtDbConnectionAdapter;
|
||||
}
|
||||
|
||||
public function getSqlAdapter($sqlAdapterType)
|
||||
{
|
||||
$LtDbSqlAdapter = "LtDbSqlAdapter" . ucfirst($sqlAdapterType);
|
||||
return new $LtDbSqlAdapter;
|
||||
}
|
||||
}
|
122
extend/app_alipay/lotusphp_runtime/DB/DbConfigBuilder.php
Executable file
122
extend/app_alipay/lotusphp_runtime/DB/DbConfigBuilder.php
Executable file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
class LtDbConfigBuilder
|
||||
{
|
||||
protected $servers = array();
|
||||
|
||||
protected $tables = array();
|
||||
|
||||
protected $adapters = array(
|
||||
//"php_ext" => array("connection_adapter" => "", "sql_adapter" => "")
|
||||
"pgsql" => array("connection_adapter" => "pgsql", "sql_adapter" => "pgsql"),
|
||||
"pdo_pgsql" => array("connection_adapter" => "pdo", "sql_adapter" => "pgsql"),
|
||||
"oci" => array("connection_adapter" => "oci", "sql_adapter" => "oracle"),
|
||||
"pdo_oci" => array("connection_adapter" => "pdo", "sql_adapter" => "oracle"),
|
||||
"mssql" => array("connection_adapter" => "mssql", "sql_adapter" => "mssql"),
|
||||
"pdo_dblib" => array("connection_adapter" => "pdo", "sql_adapter" => "mssql"),
|
||||
"mysql" => array("connection_adapter" => "mysql", "sql_adapter" => "mysql"),
|
||||
"mysqli" => array("connection_adapter" => "mysqli", "sql_adapter" => "mysql"),
|
||||
"pdo_mysql" => array("connection_adapter" => "pdo", "sql_adapter" => "mysql"),
|
||||
"sqlite" => array("connection_adapter" => "sqlite", "sql_adapter" => "sqlite"),
|
||||
"sqlite3" => array("connection_adapter" => "sqlite3", "sql_adapter" => "sqlite"),
|
||||
"pdo_sqlite" => array("connection_adapter" => "pdo", "sql_adapter" => "sqlite"),
|
||||
);
|
||||
|
||||
protected $defaultConfig = array(
|
||||
"host" => "localhost", //some ip, hostname
|
||||
//"port" => 3306,
|
||||
"username" => "root",
|
||||
"password" => null,
|
||||
//"adapter" => "mysql", //mysql,mysqli,pdo_mysql,sqlite,pdo_sqlite
|
||||
"charset" => "UTF-8",
|
||||
"pconnect" => true, //true,false
|
||||
"connection_ttl" => 3600, //any seconds
|
||||
"dbname" => null, //default dbname
|
||||
"schema" => null, //default schema
|
||||
"connection_adapter" => null,
|
||||
"sql_adapter" => null,
|
||||
);
|
||||
|
||||
protected $defaultAdapterConfigs = array(
|
||||
"pgsql" => array(
|
||||
"port" => 5432,
|
||||
),
|
||||
"oracle" => array(
|
||||
"port" => 1521,
|
||||
),
|
||||
"mssql" => array(
|
||||
"port" => 1433,
|
||||
),
|
||||
"mysql" => array(
|
||||
"port" => 3306,
|
||||
"pconnect" => false,
|
||||
"connection_ttl" => 30,
|
||||
),
|
||||
);
|
||||
|
||||
public function addSingleHost($hostConfig)
|
||||
{
|
||||
$this->addHost("group_0", "node_0", "master", $hostConfig);
|
||||
}
|
||||
|
||||
public function addHost($groupId, $nodeId = "node_0", $role = "master", $hostConfig)
|
||||
{
|
||||
if (isset($this->servers[$groupId][$nodeId][$role]))
|
||||
{//以相同role的第一个host为默认配置
|
||||
$ref = $this->servers[$groupId][$nodeId][$role][0];
|
||||
}
|
||||
else if ("slave" == $role && isset($this->servers[$groupId][$nodeId]["master"]))
|
||||
{//slave host以master的第一个host为默认配置
|
||||
$ref = $this->servers[$groupId][$nodeId]["master"][0];
|
||||
}
|
||||
else if (isset($this->servers[$groupId]) && count($this->servers[$groupId]))
|
||||
{//以本group第一个node的master第一个host为默认配置
|
||||
$refNode = key($this->servers[$groupId]);
|
||||
$ref = $this->servers[$groupId][$refNode]["master"][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($hostConfig["adapter"]))
|
||||
{
|
||||
trigger_error("No db adapter specified");
|
||||
}
|
||||
$ref = $this->defaultConfig;
|
||||
if (isset($this->defaultAdapterConfigs[$this->adapters[$hostConfig["adapter"]]["sql_adapter"]]))
|
||||
{
|
||||
$ref = array_merge($ref, $this->defaultAdapterConfigs[$this->adapters[$hostConfig["adapter"]]["sql_adapter"]]);
|
||||
}
|
||||
}
|
||||
$conf = array_merge($ref, $hostConfig);
|
||||
$conf = array_merge($conf, $this->adapters[$conf["adapter"]]);
|
||||
$conf = $this->convertDbnameToSchema($conf);
|
||||
$this->servers[$groupId][$nodeId][$role][] = $conf;
|
||||
}
|
||||
|
||||
public function getServers()
|
||||
{
|
||||
return $this->servers;
|
||||
}
|
||||
|
||||
public function getTables()
|
||||
{
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
public function buildTablesConfig()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert dbname to schema for: FrontBase, MySQL, mSQL, MS SQL Server, MaxDB, Sybase
|
||||
* See: http://www.php.net/manual-lookup.php?pattern=_select_db
|
||||
*/
|
||||
protected function convertDbnameToSchema($conf)
|
||||
{
|
||||
if (preg_match("/fbsql|mysql|msql|mssql|maxdb|sybase/i", $conf["sql_adapter"]) && isset($conf["dbname"]))
|
||||
{
|
||||
$conf["schema"] = $conf["dbname"];
|
||||
$conf["dbname"] = null;
|
||||
}
|
||||
return $conf;
|
||||
}
|
||||
}
|
117
extend/app_alipay/lotusphp_runtime/DB/DbConnectionManager.php
Executable file
117
extend/app_alipay/lotusphp_runtime/DB/DbConnectionManager.php
Executable file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
class LtDbConnectionManager
|
||||
{
|
||||
/**
|
||||
* Connection management
|
||||
* array(
|
||||
* "connection" => connection resource id,
|
||||
* "expire_time" => expire time,
|
||||
* "schema" => default schema name,
|
||||
* "charset" => char set / encoding
|
||||
* )
|
||||
*/
|
||||
static public $connectionPool;
|
||||
public $configHandle;
|
||||
protected $connectionAdapter;
|
||||
protected $sqlAdapter;
|
||||
private $servers;
|
||||
|
||||
public function getConnection($group, $node, $role = "master")
|
||||
{
|
||||
if(empty($this->servers))
|
||||
{
|
||||
$this->servers = $this->configHandle->get("db.servers");
|
||||
}
|
||||
if (($connection = $this->getNewConnection($group, $node, $role)) ||($connection = $this->getCachedConnection($group, $node, $role)))
|
||||
{
|
||||
return array(
|
||||
"connectionAdapter" => $this->connectionAdapter,
|
||||
"connectionResource" => $connection
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("db server can not be connected: group=$group, node=$node, role=$role", E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getConnectionKey($connConf)
|
||||
{
|
||||
return $connConf['adapter'] . $connConf['host'] . $connConf['port'] . $connConf['username'] . $connConf['dbname'];
|
||||
}
|
||||
|
||||
protected function saveConnection($connConf, $connection, $ttl)
|
||||
{
|
||||
$connectionInfo = array(
|
||||
"connection" => $connection,
|
||||
"expire_time" => time() + $ttl,
|
||||
"schema" => $connConf["schema"],
|
||||
"charset" => $connConf["charset"],
|
||||
);
|
||||
self::$connectionPool[$this->getConnectionKey($connConf)] = $connectionInfo;
|
||||
}
|
||||
|
||||
protected function getCachedConnection($group, $node, $role)
|
||||
{
|
||||
foreach($this->servers[$group][$node][$role] as $hostConfig)
|
||||
{
|
||||
$key = $this->getConnectionKey($hostConfig);
|
||||
if(isset(self::$connectionPool[$key]) && time() < self::$connectionPool[$key]['expire_time'])
|
||||
{//cached connection resource FOUND
|
||||
$connectionInfo = self::$connectionPool[$key];
|
||||
if ($connectionInfo["schema"] != $hostConfig["schema"] || $connectionInfo["charset"] != $hostConfig["charset"])
|
||||
{//检查当前schema和charset与用户要操作的目标不一致
|
||||
$hostConfig = $this->servers[$group][$node][$role][$hostIndexArray[$hashNumber]];
|
||||
$dbFactory = new LtDbAdapterFactory;
|
||||
$this->connectionAdapter = $dbFactory->getConnectionAdapter($hostConfig["connection_adapter"]);
|
||||
$this->sqlAdapter = $dbFactory->getSqlAdapter($hostConfig["sql_adapter"]);
|
||||
if ($connectionInfo["schema"] != $hostConfig["schema"])
|
||||
{
|
||||
$this->connectionAdapter->exec($this->sqlAdapter->setSchema($hostConfig["schema"]), $connectionInfo["connection"]);
|
||||
}
|
||||
if ($connectionInfo["charset"] != $hostConfig["charset"])
|
||||
{
|
||||
$this->connectionAdapter->exec($this->sqlAdapter->setCharset($hostConfig["charset"]), $connectionInfo["connection"]);
|
||||
}
|
||||
$this->saveConnection($hostConfig, $connectionInfo["connection"], $hostConfig["connection_ttl"]);
|
||||
}
|
||||
return $connectionInfo["connection"];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getNewConnection($group, $node, $role)
|
||||
{
|
||||
$hostTotal = count($this->servers[$group][$node][$role]);
|
||||
$hostIndexArray = array_keys($this->servers[$group][$node][$role]);
|
||||
while ($hostTotal)
|
||||
{
|
||||
$hashNumber = substr(microtime(),7,1) % $hostTotal;
|
||||
$hostConfig = $this->servers[$group][$node][$role][$hostIndexArray[$hashNumber]];
|
||||
$dbFactory = new LtDbAdapterFactory;
|
||||
$this->connectionAdapter = $dbFactory->getConnectionAdapter($hostConfig["connection_adapter"]);
|
||||
$this->sqlAdapter = $dbFactory->getSqlAdapter($hostConfig["sql_adapter"]);
|
||||
if ($connection = $this->connectionAdapter->connect($hostConfig))
|
||||
{
|
||||
$this->connectionAdapter->exec($this->sqlAdapter->setSchema($hostConfig["schema"]), $connection);
|
||||
$this->connectionAdapter->exec($this->sqlAdapter->setCharset($hostConfig["charset"]), $connection);
|
||||
$this->saveConnection($hostConfig, $connection, $hostConfig["connection_ttl"]);
|
||||
return $connection;
|
||||
}
|
||||
else
|
||||
{
|
||||
//trigger_error('connection fail', E_USER_WARNING);
|
||||
//delete the unavailable server
|
||||
for ($i = $hashNumber; $i < $hostTotal - 1; $i ++)
|
||||
{
|
||||
$hostIndexArray[$i] = $hostIndexArray[$i+1];
|
||||
}
|
||||
unset($hostIndexArray[$hostTotal-1]);
|
||||
$hostTotal --;
|
||||
}//end else
|
||||
}//end while
|
||||
return false;
|
||||
}
|
||||
}
|
200
extend/app_alipay/lotusphp_runtime/DB/DbHandle.php
Executable file
200
extend/app_alipay/lotusphp_runtime/DB/DbHandle.php
Executable file
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
class LtDbHandle
|
||||
{
|
||||
public $configHandle;
|
||||
public $group;
|
||||
public $node;
|
||||
public $role = "master";
|
||||
public $connectionAdapter;
|
||||
public $connectionResource;
|
||||
public $sqlAdapter;
|
||||
protected $connectionManager;
|
||||
private $servers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if(empty($this->servers))
|
||||
{
|
||||
$this->servers = $this->configHandle->get("db.servers");
|
||||
}
|
||||
$this->connectionManager = new LtDbConnectionManager;
|
||||
$this->connectionManager->configHandle = $this->configHandle;
|
||||
$this->sqlAdapter = $this->getCurrentSqlAdapter();
|
||||
$connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role);
|
||||
$this->connectionAdapter = $connectionInfo["connectionAdapter"];
|
||||
$this->connectionResource = $connectionInfo["connectionResource"];
|
||||
}
|
||||
|
||||
/**
|
||||
* Trancaction methods
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
return $this->connectionAdapter->exec($this->sqlAdapter->beginTransaction(), $this->connectionResource);
|
||||
}
|
||||
|
||||
public function commit()
|
||||
{
|
||||
return $this->connectionAdapter->exec($this->sqlAdapter->commit(), $this->connectionResource);
|
||||
}
|
||||
|
||||
public function rollBack()
|
||||
{
|
||||
return $this->connectionAdapter->exec($this->sqlAdapter->rollBack(), $this->connectionResource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an sql query
|
||||
*
|
||||
* @param $sql
|
||||
* @param $bind
|
||||
* @param $forceUseMaster
|
||||
* @return false on query failed
|
||||
* --sql type-- --return value--
|
||||
* SELECT, SHOW, DESECRIBE, EXPLAIN rowset or NULL when no record found
|
||||
* INSERT the ID generated for an AUTO_INCREMENT column
|
||||
* UPDATE, DELETE, REPLACE affected count
|
||||
* USE, DROP, ALTER, CREATE, SET etc true
|
||||
* @notice 每次只能执行一条SQL
|
||||
* 不要通过此接口执行USE DATABASE, SET NAMES这样的语句
|
||||
*/
|
||||
public function query($sql, $bind = null, $forceUseMaster = false)
|
||||
{
|
||||
$sql = trim($sql);
|
||||
if (empty($sql))
|
||||
{
|
||||
trigger_error('Empty the SQL statement');
|
||||
}
|
||||
$queryType = $this->sqlAdapter->detectQueryType($sql);
|
||||
switch ($queryType)
|
||||
{
|
||||
case "SELECT":
|
||||
if (!$forceUseMaster && isset($this->servers[$this->group][$this->node]["slave"]))
|
||||
{
|
||||
$this->role = "slave";
|
||||
}
|
||||
$queryMethod = "select";
|
||||
break;
|
||||
case "INSERT":
|
||||
$this->role = "master";
|
||||
$queryMethod = "insert";
|
||||
break;
|
||||
case "CHANGE_ROWS":
|
||||
$this->role = "master";
|
||||
$queryMethod = "changeRows";
|
||||
break;
|
||||
case "SET_SESSION_VAR":
|
||||
$queryMethod = "setSessionVar";
|
||||
break;
|
||||
case "OTHER":
|
||||
default:
|
||||
$this->role = "master";
|
||||
$queryMethod = "other";
|
||||
break;
|
||||
}
|
||||
$connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role);
|
||||
$this->connectionAdapter = $connectionInfo["connectionAdapter"];
|
||||
$this->connectionResource = $connectionInfo["connectionResource"];
|
||||
if (is_array($bind) && 0 < count($bind))
|
||||
{
|
||||
$sql = $this->bindParameter($sql, $bind);
|
||||
}
|
||||
return $this->$queryMethod($sql, $this->connectionResource);
|
||||
}
|
||||
/**
|
||||
* function posted by renlu
|
||||
*/
|
||||
public function escape($str)
|
||||
{
|
||||
return $this->connectionAdapter->escape($str, $this->connectionResource);
|
||||
}
|
||||
/**
|
||||
* function posted by renlu
|
||||
*/
|
||||
public function insertid()
|
||||
{
|
||||
return $this->connectionAdapter->lastInsertId($this->connectionResource);
|
||||
}
|
||||
/**
|
||||
* Generate complete sql from sql template (with placeholder) and parameter
|
||||
*
|
||||
* @param $sql
|
||||
* @param $parameter
|
||||
* @return string
|
||||
* @todo 兼容pgsql等其它数据库,pgsql的某些数据类型不接受单引号引起来的值
|
||||
*/
|
||||
public function bindParameter($sql, $parameter)
|
||||
{
|
||||
// 注意替换结果尾部加一个空格
|
||||
$sql = preg_replace("/:([a-zA-Z0-9_\-\x7f-\xff][a-zA-Z0-9_\-\x7f-\xff]*)\s*([,\)]?)/", "\x01\x02\x03\\1\x01\x02\x03\\2 ", $sql);
|
||||
foreach($parameter as $key => $value)
|
||||
{
|
||||
$find[] = "\x01\x02\x03$key\x01\x02\x03";
|
||||
if ($value instanceof LtDbSqlExpression)
|
||||
{
|
||||
$replacement[] = $value->__toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
$replacement[] = "'" . $this->connectionAdapter->escape($value, $this->connectionResource) . "'";
|
||||
}
|
||||
}
|
||||
$sql = str_replace($find, $replacement, $sql);
|
||||
return $sql;
|
||||
}
|
||||
|
||||
protected function getCurrentSqlAdapter()
|
||||
{
|
||||
$factory = new LtDbAdapterFactory;
|
||||
$host = key($this->servers[$this->group][$this->node][$this->role]);
|
||||
return $factory->getSqlAdapter($this->servers[$this->group][$this->node][$this->role][$host]["sql_adapter"]);
|
||||
}
|
||||
|
||||
protected function select($sql, $connResource)
|
||||
{
|
||||
$result = $this->connectionAdapter->query($sql, $connResource);
|
||||
if (empty($result))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
protected function insert($sql, $connResource)
|
||||
{
|
||||
if ($result = $this->connectionAdapter->exec($sql, $connResource))
|
||||
{
|
||||
return $this->connectionAdapter->lastInsertId($connResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
protected function changeRows($sql, $connResource)
|
||||
{
|
||||
return $this->connectionAdapter->exec($sql, $connResource);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @todo 更新连接缓存
|
||||
*/
|
||||
protected function setSessionVar($sql, $connResource)
|
||||
{
|
||||
return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true;
|
||||
}
|
||||
|
||||
protected function other($sql, $connResource)
|
||||
{
|
||||
return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true;
|
||||
}
|
||||
}
|
15
extend/app_alipay/lotusphp_runtime/DB/DbSqlExpression.php
Executable file
15
extend/app_alipay/lotusphp_runtime/DB/DbSqlExpression.php
Executable file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
class LtDbSqlExpression
|
||||
{
|
||||
private $_expression;
|
||||
|
||||
public function __construct($string)
|
||||
{
|
||||
$this->_expression = (string) $string;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->_expression;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* 加工工厂类由开发者自行开发,继承自这个类
|
||||
*/
|
||||
abstract class LtAbstractDbSqlMapFilterObject {
|
||||
|
||||
// query()方法返回的结果集,用于加工的原料
|
||||
public $result;
|
||||
|
||||
/**
|
||||
* 需要被继承,实现逻辑的操作类,输入query()方法返回的结果集
|
||||
* 经过处理后返回开发者定义的对象或结构
|
||||
*/
|
||||
abstract protected function process();
|
||||
}
|
||||
|
14
extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/DbSqlMapClient.php
Executable file
14
extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/DbSqlMapClient.php
Executable file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
class LtDbSqlMapClient
|
||||
{
|
||||
public $configHandle;
|
||||
public $dbh;
|
||||
|
||||
public function execute($mapId, $bind = null)
|
||||
{
|
||||
$sqlMap = $this->configHandle->get($this->dbh->group . "." . $mapId);
|
||||
$forceUseMaster = isset($sqlMap["force_use_master"]) ? $sqlMap["force_use_master"] : false;
|
||||
return $this->dbh->query($sqlMap["sql"], $bind, $forceUseMaster);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* 用于加工DB句柄query方法返回的数组
|
||||
* 开发者在一次会话中可配置多个Filter
|
||||
*/
|
||||
class LtDbSqlMapResultFactory {
|
||||
// Filter列表
|
||||
public $filters;
|
||||
public $configHandle;
|
||||
|
||||
public function init() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 工厂入口,sql map client调用的方法
|
||||
* 在这个方法中调用开发者自定义的
|
||||
* LtAbstractSqlMapFilterObject.process()方法
|
||||
* 可配置多个process方法
|
||||
*/
|
||||
public function run() {
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,300 @@
|
||||
<?php
|
||||
/**
|
||||
* Database Table abstract
|
||||
*
|
||||
* @todo pretty join support
|
||||
*/
|
||||
class LtDbTableDataGateway
|
||||
{
|
||||
public $configHandle;
|
||||
public $dbh;
|
||||
/**
|
||||
* The created field name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $createdColumn;
|
||||
|
||||
/**
|
||||
* The modified field name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $modifiedColumn;
|
||||
|
||||
/**
|
||||
* The table name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $tableName;
|
||||
|
||||
/**
|
||||
* The fields array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fields;
|
||||
|
||||
/**
|
||||
* The primary key
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey;
|
||||
protected $servers;
|
||||
|
||||
/**
|
||||
* Build table's field list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildFieldList()
|
||||
{
|
||||
if (!empty($this->fields))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
$servers = $this->configHandle->get('db.servers');
|
||||
$group = $this->dbh->group;
|
||||
$node = $this->dbh->node;
|
||||
$role = $this->dbh->role;
|
||||
$table = $this->tableName;
|
||||
$host = key($servers[$group][$node][$role]);
|
||||
$key = md5($group . $node . $role . $table . $host . $table);
|
||||
if (!$value = $this->configHandle->get($key))
|
||||
{
|
||||
$sql = $this->dbh->sqlAdapter->showFields($this->tableName);
|
||||
$rs = $this->dbh->query($sql);
|
||||
$this->fields = $this->dbh->sqlAdapter->getFields($rs);
|
||||
foreach($this->fields as $field)
|
||||
{
|
||||
if ($field['primary'] == 1)
|
||||
{
|
||||
$this->primaryKey = $field['name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$value['fields'] = $this->fields;
|
||||
$value['primaryKey'] = $this->primaryKey;
|
||||
$this->configHandle->addConfig(array($key => $value));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->fields = $value['fields'];
|
||||
$this->primaryKey = $value['primaryKey'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A shortcut to SELECT COUNT(*) FROM table WHERE condition
|
||||
*
|
||||
* @param array $args
|
||||
* @return integer
|
||||
* @example count(array('expression' => 'id < :id', 'value' => array('id' => 10)));
|
||||
*/
|
||||
public function count($args = null)
|
||||
{
|
||||
$selectTemplate = 'SELECT COUNT(*) AS total FROM %s%s';
|
||||
$where = isset($args['where']['expression']) ? ' WHERE ' . $args['where']['expression'] : '';
|
||||
$bind = isset($args['where']['value']) ? $args['where']['value'] : array();
|
||||
$join = isset($args['join']) ? ' ' . $args['join'] : '';
|
||||
$sql = sprintf($selectTemplate, $this->tableName, $join . $where);
|
||||
$queryResult = $this->dbh->query($sql, $bind);
|
||||
return $queryResult[0]['total'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a row by primary key
|
||||
*
|
||||
* @param string $primaryKeyId
|
||||
* @return string
|
||||
* @example delete(10);
|
||||
*/
|
||||
public function delete($primaryKeyId)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$where['expression'] = $this->primaryKey . '=:' . $this->primaryKey;
|
||||
$where['value'][$this->primaryKey] = $primaryKeyId;
|
||||
return $this->deleteRows($where);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete many rows from table
|
||||
* Please use this method carefully!
|
||||
*
|
||||
* @param array $args
|
||||
* @return integer
|
||||
* @example deleteRows(array('expression' => "id > :id", 'value' => array('id' => 2)));
|
||||
*/
|
||||
public function deleteRows($args = null)
|
||||
{
|
||||
$deleteTemplate = 'DELETE FROM %s%s';
|
||||
$where = isset($args['expression']) ? ' WHERE ' . $args['expression'] : '';
|
||||
$bind = isset($args['value']) ? $args['value'] : array();
|
||||
$sql = sprintf($deleteTemplate, $this->tableName, $where);
|
||||
return $this->dbh->query($sql, $bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch one row from table by primary key
|
||||
*
|
||||
* @param string $primaryKeyId
|
||||
* @param array $args
|
||||
* @param boolean $useSlave
|
||||
* @return array
|
||||
* @example fetch(10)
|
||||
*/
|
||||
public function fetch($primaryKeyId, $args = null, $useSlave = true)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$fetchRowsArgs['where']['expression'] = $this->tableName . '.' . $this->primaryKey . '=:' . $this->primaryKey;
|
||||
$fetchRowsArgs['where']['value'][$this->primaryKey] = $primaryKeyId;
|
||||
$fetchRowsArgs['fields'] = isset($args['fields']) ? $args['fields'] : null;
|
||||
$fetchRowsArgs['join'] = isset($args['join']) ? $args['join'] : null;
|
||||
$fetchResult = $this->fetchRows($fetchRowsArgs, $useSlave);
|
||||
return $fetchResult ? $fetchResult[0] : $fetchResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch many rows from table
|
||||
*
|
||||
* @param array $args
|
||||
* @param boolean $useSlave
|
||||
* @return array
|
||||
* @example fetchRows(array('where' => array('expression' => "id > :id", 'value' => array('id' => 2))));
|
||||
*/
|
||||
public function fetchRows($args = null, $useSlave = true)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$selectTemplate = 'SELECT %s FROM %s%s';
|
||||
$fields = isset($args['fields']) ? $args['fields'] : '*';
|
||||
$where = isset($args['where']['expression']) ? ' WHERE ' . $args['where']['expression'] : '';
|
||||
$bind = isset($args['where']['value']) ? $args['where']['value'] : array();
|
||||
$join = isset($args['join']) ? ' ' . $args['join'] : '';
|
||||
$orderby = isset($args['orderby']) ? ' ORDER BY ' . $args['orderby'] : '';
|
||||
$groupby = isset($args['groupby']) ? ' GROUP BY ' . $args['groupby'] : '';
|
||||
$sql = sprintf($selectTemplate, $fields, $this->tableName, $join . $where . $groupby . $orderby);
|
||||
if (isset($args['limit']))
|
||||
{
|
||||
$offset = isset($args['offset']) ? $args['offset'] : 0;
|
||||
$sql = $sql . ' ' . $this->dbh->sqlAdapter->limit($args['limit'], $offset);
|
||||
}
|
||||
return $this->dbh->query($sql, $bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert one row into table, then return the inserted row's pk
|
||||
*
|
||||
* @param array $args
|
||||
* @return string
|
||||
* @example insert(array('name' => 'lily', 'age' => '12'));
|
||||
*/
|
||||
public function insert($args = null)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$insertTemplate = 'INSERT INTO %s (%s) VALUES (%s)';
|
||||
$fields = array();
|
||||
$placeHolders = array();
|
||||
foreach($args as $field => $value)
|
||||
{
|
||||
if (isset($this->fields[$field]))
|
||||
{
|
||||
$fields[] = $field;
|
||||
$placeholders[] = ":$field";
|
||||
$values[$field] = $value;
|
||||
}
|
||||
}
|
||||
if (isset($this->fields[$this->createdColumn]) && !isset($args[$this->createdColumn]))
|
||||
{
|
||||
$fields[] = $this->createdColumn;
|
||||
$placeholders[] = ':' . $this->createdColumn;
|
||||
$values[$this->createdColumn] = time();
|
||||
}
|
||||
if (isset($this->fields[$this->modifiedColumn]) && !isset($args[$this->modifiedColumn]))
|
||||
{
|
||||
$fields[] = $this->modifiedColumn;
|
||||
$placeholders[] = ':' . $this->modifiedColumn;
|
||||
$values[$this->modifiedColumn] = time();
|
||||
}
|
||||
$sql = sprintf($insertTemplate, $this->tableName, implode(",", $fields), implode(",", $placeholders));
|
||||
$bind = $values;
|
||||
$queryResult = $this->dbh->query($sql, $bind);
|
||||
return isset($args[$this->primaryKey]) ? $args[$this->primaryKey] : $queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update one row by primary key
|
||||
*
|
||||
* @param string $primaryKeyId
|
||||
* @param array $args
|
||||
* @return integer
|
||||
* @example update(1, array('name' => 'lily', 'age' => '18'));
|
||||
*/
|
||||
public function update($primaryKeyId, $args = null)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$where['expression'] = $this->primaryKey . '=:' . $this->primaryKey;
|
||||
$where['value'][$this->primaryKey] = $primaryKeyId;
|
||||
return $this->updateRows($where, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update manay rows
|
||||
* Please use this method carefully!
|
||||
*
|
||||
* @param array $where
|
||||
* @param array $args
|
||||
* @return integer
|
||||
* @example updateRows(array('expression' => "id > :id", 'value' => array('id' => 2)), array('name' => 'kiwi', 'age' => '1'));
|
||||
*/
|
||||
public function updateRows($where, $args = null)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$updateTemplate = 'UPDATE %s SET %s%s';
|
||||
$fields = array();
|
||||
$bindParameters = array();
|
||||
$placeholderStyle = isset($where['value']) && array_key_exists(0, $where['value']) ? 'questionMark' : 'named';
|
||||
foreach($args as $field => $value)
|
||||
{
|
||||
if (isset($this->fields[$field]))
|
||||
{
|
||||
if ($args[$field] instanceof DbExpression)
|
||||
{
|
||||
$fields[] = "$field=" . $args[$field]->__toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ('named' == $placeholderStyle)
|
||||
{
|
||||
$fields[] = "$field=:$field";
|
||||
$bindParameters[$field] = $args[$field];
|
||||
}
|
||||
else
|
||||
{
|
||||
$fields[] = "$field=?";
|
||||
$bindParameters[] = $args[$field];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($this->fields[$this->modifiedColumn]) && !isset($args[$this->modifiedColumn]))
|
||||
{
|
||||
if ('named' == $placeholderStyle)
|
||||
{
|
||||
$fields[] = $this->modifiedColumn . '=:' . $this->modifiedColumn;
|
||||
$bindParameters[$this->modifiedColumn] = time();
|
||||
}
|
||||
else
|
||||
{
|
||||
$fields[] = $this->modifiedColumn . '=?';
|
||||
$bindParameters[] = time();
|
||||
}
|
||||
}
|
||||
$whereCause = isset($where['expression']) ? ' WHERE ' . $where['expression'] : '';
|
||||
$bind = isset($where['value']) ? array_merge($bindParameters, $where['value']) : $bindParameters;
|
||||
$sql = sprintf($updateTemplate, $this->tableName, implode(",", $fields), $whereCause);
|
||||
return $this->dbh->query($sql, $bind);
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
<?php
|
@ -0,0 +1 @@
|
||||
<?php
|
16
extend/app_alipay/lotusphp_runtime/Inflector/Inflector.php
Executable file
16
extend/app_alipay/lotusphp_runtime/Inflector/Inflector.php
Executable file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
class LtInflector
|
||||
{
|
||||
public $conf = array("separator" => "_");
|
||||
|
||||
public function camelize($uncamelized_words)
|
||||
{
|
||||
$uncamelized_words = $this->conf["separator"] . str_replace($this->conf["separator"] , " ", strtolower($uncamelized_words));
|
||||
return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $this->conf["separator"] );
|
||||
}
|
||||
|
||||
public function uncamelize($camelCaps)
|
||||
{
|
||||
return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $this->conf["separator"] . "$2", $camelCaps));
|
||||
}
|
||||
}
|
42
extend/app_alipay/lotusphp_runtime/Logger/Logger.php
Executable file
42
extend/app_alipay/lotusphp_runtime/Logger/Logger.php
Executable file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
class LtLogger
|
||||
{
|
||||
public $conf = array(
|
||||
"separator" => "\t",
|
||||
"log_file" => ""
|
||||
);
|
||||
|
||||
private $fileHandle;
|
||||
|
||||
protected function getFileHandle()
|
||||
{
|
||||
if (null === $this->fileHandle)
|
||||
{
|
||||
if (empty($this->conf["log_file"]))
|
||||
{
|
||||
trigger_error("no log file spcified.");
|
||||
}
|
||||
$logDir = dirname($this->conf["log_file"]);
|
||||
if (!is_dir($logDir))
|
||||
{
|
||||
mkdir($logDir, 0777, true);
|
||||
}
|
||||
$this->fileHandle = fopen($this->conf["log_file"], "a");
|
||||
}
|
||||
return $this->fileHandle;
|
||||
}
|
||||
|
||||
public function log($logData)
|
||||
{
|
||||
if ("" == $logData || array() == $logData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (is_array($logData))
|
||||
{
|
||||
$logData = implode($this->conf["separator"], $logData);
|
||||
}
|
||||
$logData = $logData. "\n";
|
||||
fwrite($this->getFileHandle(), $logData);
|
||||
}
|
||||
}
|
157
extend/app_alipay/lotusphp_runtime/Lotus.php
Executable file
157
extend/app_alipay/lotusphp_runtime/Lotus.php
Executable file
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
class Lotus
|
||||
{
|
||||
/**
|
||||
* Lotus Option array
|
||||
*
|
||||
* @var array array(
|
||||
* "proj_dir" =>
|
||||
* "app_name" =>
|
||||
* "autoload_dir" =>
|
||||
* );
|
||||
*/
|
||||
public $option;
|
||||
public $devMode = true;
|
||||
public $defaultStoreDir;
|
||||
|
||||
protected $proj_dir;
|
||||
protected $app_dir;
|
||||
protected $data_dir;
|
||||
protected $lotusRuntimeDir;
|
||||
protected $coreCacheHandle;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->lotusRuntimeDir = dirname(__FILE__) . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$underMVC = false;
|
||||
if (isset($this->option["proj_dir"]) && !empty($this->option["proj_dir"]))
|
||||
{
|
||||
$this->proj_dir = rtrim($this->option["proj_dir"], '\\/') . '/';
|
||||
if (isset($this->option["app_name"]) && !empty($this->option["app_name"]))
|
||||
{
|
||||
$this->app_dir = $this->proj_dir . "app/" . $this->option["app_name"] . "/";
|
||||
$this->data_dir = $this->proj_dir . "data/" . $this->option["app_name"] . "/";
|
||||
$underMVC = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("Lotus option [app_name] is missing.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load core component
|
||||
*/
|
||||
require_once $this->lotusRuntimeDir . "Store.php";
|
||||
require_once $this->lotusRuntimeDir . "StoreMemory.php";
|
||||
require_once $this->lotusRuntimeDir . "StoreFile.php";
|
||||
|
||||
if ($this->defaultStoreDir)
|
||||
{
|
||||
if ($defaultStoreDir = realpath($this->defaultStoreDir))
|
||||
{
|
||||
LtStoreFile::$defaultStoreDir = $defaultStoreDir;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("invalid [default store dir]: " . $this->defaultStoreDir);
|
||||
}
|
||||
}
|
||||
if (!$this->devMode)
|
||||
{
|
||||
/**
|
||||
* accelerate LtAutoloader, LtConfig
|
||||
*/
|
||||
$this->coreCacheHandle = new LtStoreFile;
|
||||
$prefix = sprintf("%u", crc32(serialize($this->app_dir)));
|
||||
$this->coreCacheHandle->prefix = 'Lotus-' . $prefix;
|
||||
$this->coreCacheHandle->useSerialize = true;
|
||||
$this->coreCacheHandle->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Autoloader, do this before init all other lotusphp component.
|
||||
*/
|
||||
$this->prepareAutoloader();
|
||||
|
||||
/**
|
||||
* init Config
|
||||
*/
|
||||
$this->prepareConfig();
|
||||
|
||||
/**
|
||||
* Run dispatcher when under MVC mode
|
||||
*/
|
||||
if ($underMVC)
|
||||
{
|
||||
$this->runMVC();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload all lotus components and user-defined libraries;
|
||||
*/
|
||||
protected function prepareAutoloader()
|
||||
{
|
||||
require_once $this->lotusRuntimeDir . "Autoloader/Autoloader.php";
|
||||
$autoloader = new LtAutoloader;
|
||||
$autoloader->autoloadPath[] = $this->lotusRuntimeDir;
|
||||
if (isset($this->option["autoload_dir"]))
|
||||
{
|
||||
$autoloader->autoloadPath[] = $this->option["autoload_dir"];
|
||||
}
|
||||
if ($this->proj_dir)
|
||||
{
|
||||
is_dir($this->proj_dir . 'lib') && $autoloader->autoloadPath[] = $this->proj_dir . 'lib';
|
||||
is_dir($this->app_dir . 'action') && $autoloader->autoloadPath[] = $this->app_dir . 'action';
|
||||
is_dir($this->app_dir . 'lib') && $autoloader->autoloadPath[] = $this->app_dir . 'lib';
|
||||
}
|
||||
|
||||
if (!$this->devMode)
|
||||
{
|
||||
$autoloader->storeHandle = $this->coreCacheHandle;
|
||||
}
|
||||
$autoloader->init();
|
||||
}
|
||||
|
||||
protected function prepareConfig()
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton('LtConfig');
|
||||
if (!$this->devMode)
|
||||
{
|
||||
$configFile = 'conf/conf.php';
|
||||
$this->configHandle->storeHandle = $this->coreCacheHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
$configFile = 'conf/conf_dev.php';
|
||||
}
|
||||
$this->configHandle->init();
|
||||
if ($this->app_dir && is_file($this->app_dir . $configFile))
|
||||
{
|
||||
$this->configHandle->loadConfigFile($this->app_dir . $configFile);
|
||||
}
|
||||
}
|
||||
|
||||
protected function runMVC()
|
||||
{
|
||||
$router = LtObjectUtil::singleton('LtRouter');
|
||||
$router->init();
|
||||
$dispatcher = LtObjectUtil::singleton('LtDispatcher');
|
||||
$dispatcher->viewDir = $this->app_dir . 'view/';
|
||||
$dispatcher->viewTplDir = $this->data_dir . 'templateView/';
|
||||
if (!$this->devMode)
|
||||
{
|
||||
$dispatcher->viewTplAutoCompile = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$dispatcher->viewTplAutoCompile = true;
|
||||
}
|
||||
$dispatcher->dispatchAction($router->module, $router->action);
|
||||
}
|
||||
}
|
236
extend/app_alipay/lotusphp_runtime/MVC/Action.php
Executable file
236
extend/app_alipay/lotusphp_runtime/MVC/Action.php
Executable file
@ -0,0 +1,236 @@
|
||||
<?php
|
||||
/**
|
||||
* The Action class
|
||||
*/
|
||||
abstract class LtAction
|
||||
{
|
||||
/**
|
||||
* The context object
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $context;
|
||||
|
||||
public $viewDir;
|
||||
public $viewTplDir;
|
||||
public $viewTplAutoCompile;
|
||||
|
||||
/**
|
||||
* The dtd config for validator
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dtds = array();
|
||||
|
||||
/**
|
||||
* The Access Control List
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $acl;
|
||||
|
||||
/**
|
||||
* The current user's roles
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $roles = array();
|
||||
|
||||
/**
|
||||
* A flag to indicate if subclass call LtAction::__construct()
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $constructed = false;
|
||||
|
||||
/**
|
||||
* The response type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $responseType = "html";
|
||||
|
||||
/**
|
||||
* Result properties
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
protected $message;
|
||||
|
||||
public $data;
|
||||
|
||||
protected $view;
|
||||
|
||||
protected $layout;
|
||||
|
||||
/**
|
||||
* The constructor function, initialize the URI property
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->constructed = true;
|
||||
}
|
||||
|
||||
public function executeChain()
|
||||
{
|
||||
if (!$this->constructed)
|
||||
{
|
||||
//DebugHelper::debug('SUBCLASS_NOT_CALL_PARENT_CONSTRUCTOR', array('class' => $actionClassName));
|
||||
trigger_error('SUBCLASS_NOT_CALL_PARENT_CONSTRUCTOR');
|
||||
}
|
||||
$this->afterConstruct();
|
||||
$validateResult = $this->validateInput();
|
||||
if (0 == $validateResult["error_total"])
|
||||
{
|
||||
if ($this->checkPrivilege())
|
||||
{
|
||||
$this->beforeExecute();
|
||||
$this->execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->code = 403;
|
||||
$this->message = "Access denied";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->code = 407;
|
||||
$this->message = "Invalid input";
|
||||
$this->data['error_messages'] = $validateResult["error_messages"];
|
||||
}
|
||||
$this->writeResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do something after subClass::__construct().
|
||||
*/
|
||||
protected function afterConstruct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the data from client
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function validateInput()
|
||||
{
|
||||
$validateResult = array("error_total" => 0, "error_messages" => array());
|
||||
if (!empty($this->dtds) && class_exists('LtValidator'))
|
||||
{
|
||||
$validator = new LtValidator;
|
||||
$validator->init();
|
||||
foreach ($this->dtds as $variable => $dtd)
|
||||
{
|
||||
$from = isset($dtd->from) ? $dtd->from : 'request';
|
||||
|
||||
foreach ($dtd->rules as $ruleKey => $ruleValue)
|
||||
{
|
||||
if ($ruleValue instanceof ConfigExpression)
|
||||
{
|
||||
eval('$_ruleValue = ' . $ruleValue->__toString());
|
||||
$dtd->rules[$ruleKey] = $_ruleValue;
|
||||
}
|
||||
}
|
||||
$error_messages = $validator->validate($this->context->$from($variable), $dtd);
|
||||
if (!empty($error_messages))
|
||||
{
|
||||
$validateResult['error_total'] ++;
|
||||
$validateResult['error_messages'][$variable] = $error_messages;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $validateResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current user have privilege to do this
|
||||
*
|
||||
* @return boolen
|
||||
*/
|
||||
protected function checkPrivilege()
|
||||
{
|
||||
$allow = true;
|
||||
if (!empty($this->roles) && class_exists('LtRbac'))
|
||||
{
|
||||
$module = $this->context->uri["module"];
|
||||
$action = $this->context->uri["action"];
|
||||
$roles = array_merge(array("*"), $this->roles);
|
||||
$rbac = new LtRbac();
|
||||
$rbac->init();
|
||||
$allow = $rbac->checkAcl($roles, "$module/$action");
|
||||
}
|
||||
return $allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do something before subClass::execute().
|
||||
*/
|
||||
protected function beforeExecute()
|
||||
{
|
||||
}
|
||||
|
||||
protected function execute()
|
||||
{
|
||||
}
|
||||
|
||||
protected function writeResponse()
|
||||
{
|
||||
switch ($this->responseType)
|
||||
{
|
||||
case 'json':
|
||||
echo json_encode(array("code" => $this->code,
|
||||
"message" => $this->message,
|
||||
"data" => $this->data
|
||||
));
|
||||
exit; //
|
||||
break;
|
||||
case 'tpl':
|
||||
if (null === $this->view)
|
||||
{
|
||||
$this->view = new LtTemplateView;
|
||||
}
|
||||
$this->view->component = false; // 是否组件
|
||||
$this->view->context = $this->context;
|
||||
$this->view->code = $this->code;
|
||||
$this->view->message = $this->message;
|
||||
$this->view->data = $this->data;
|
||||
$this->view->layoutDir = $this->viewDir . "layout/";
|
||||
$this->view->layout = $this->layout;
|
||||
$this->view->templateDir = $this->viewDir;
|
||||
$this->view->compiledDir = $this->viewTplDir;
|
||||
$this->view->autoCompile = $this->viewTplAutoCompile;
|
||||
if (empty($this->template))
|
||||
{
|
||||
$this->template = $this->context->uri["module"] . "-" . $this->context->uri["action"];
|
||||
}
|
||||
$this->view->template = $this->template;
|
||||
$this->view->render();
|
||||
break;
|
||||
|
||||
case 'html':
|
||||
case 'wml':
|
||||
default:
|
||||
if (null === $this->view)
|
||||
{
|
||||
$this->view = new LtView;
|
||||
}
|
||||
$this->view->context = $this->context;
|
||||
$this->view->code = $this->code;
|
||||
$this->view->message = $this->message;
|
||||
$this->view->data = $this->data;
|
||||
$this->view->layoutDir = $this->viewDir . "layout/";
|
||||
$this->view->layout = $this->layout;
|
||||
$this->view->templateDir = $this->viewDir;
|
||||
if (empty($this->template))
|
||||
{
|
||||
$this->template = $this->context->uri["module"] . "-" . $this->context->uri["action"];
|
||||
}
|
||||
$this->view->template = $this->template;
|
||||
$this->view->render();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
134
extend/app_alipay/lotusphp_runtime/MVC/Component.php
Executable file
134
extend/app_alipay/lotusphp_runtime/MVC/Component.php
Executable file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* The Component class
|
||||
*/
|
||||
abstract class LtComponent
|
||||
{
|
||||
/**
|
||||
* The context object
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $context;
|
||||
|
||||
public $viewDir;
|
||||
public $viewTplDir;
|
||||
public $viewTplAutoCompile;
|
||||
/**
|
||||
* A flag to indicate if subclass call LtComponent::__construct()
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $constructed = false;
|
||||
/**
|
||||
* The response type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $responseType = "html";
|
||||
|
||||
/**
|
||||
* Result properties
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
protected $message;
|
||||
|
||||
public $data;
|
||||
|
||||
protected $view;
|
||||
|
||||
protected $layout;
|
||||
|
||||
/**
|
||||
* The constructor function
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->constructed = true;
|
||||
}
|
||||
public function executeChain()
|
||||
{
|
||||
if (!$this->constructed)
|
||||
{
|
||||
//DebugHelper::debug('SUBCLASS_NOT_CALL_PARENT_CONSTRUCTOR', array('class' => $actionClassName));
|
||||
}
|
||||
$this->afterConstruct();
|
||||
$this->beforeExecute();
|
||||
$this->execute();
|
||||
$this->writeResponse();
|
||||
}
|
||||
|
||||
protected function afterConstruct()
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* Do something before subClass::execute().
|
||||
*/
|
||||
protected function beforeExecute()
|
||||
{
|
||||
}
|
||||
|
||||
protected function execute()
|
||||
{
|
||||
}
|
||||
|
||||
protected function writeResponse()
|
||||
{
|
||||
switch ($this->responseType)
|
||||
{
|
||||
case 'json':
|
||||
echo json_encode(array("code" => $this->code,
|
||||
"message" => $this->message,
|
||||
"data" => $this->data
|
||||
));
|
||||
exit;
|
||||
break;
|
||||
case 'tpl':
|
||||
if (null === $this->view)
|
||||
{
|
||||
$this->view = new LtTemplateView;
|
||||
}
|
||||
$this->view->component = true; // 是否组件
|
||||
$this->view->context = $this->context;
|
||||
$this->view->code = $this->code;
|
||||
$this->view->message = $this->message;
|
||||
$this->view->data = $this->data;
|
||||
$this->view->layoutDir = $this->viewDir . "layout/";
|
||||
$this->view->layout = $this->layout;
|
||||
$this->view->templateDir = $this->viewDir . "component/";
|
||||
$this->view->compiledDir = $this->viewTplDir . "component/";
|
||||
$this->view->autoCompile = $this->viewTplAutoCompile;
|
||||
if (empty($this->template))
|
||||
{
|
||||
$this->template = $this->context->uri["module"] . "-" . $this->context->uri["action"];
|
||||
}
|
||||
$this->view->template = $this->template;
|
||||
$this->view->render();
|
||||
break;
|
||||
|
||||
case 'html':
|
||||
case 'wml':
|
||||
default:
|
||||
if (null === $this->view)
|
||||
{
|
||||
$this->view = new LtView;
|
||||
}
|
||||
$this->view->context = $this->context;
|
||||
$this->view->code = $this->code;
|
||||
$this->view->message = $this->message;
|
||||
$this->view->data = $this->data;
|
||||
$this->view->layoutDir = $this->viewDir . "layout/";
|
||||
$this->view->layout = $this->layout;
|
||||
$this->view->templateDir = $this->viewDir . "component/";
|
||||
if (empty($this->template))
|
||||
{
|
||||
$this->template = $this->context->uri["module"] . "-" . $this->context->uri["action"];
|
||||
}
|
||||
$this->view->template = $this->template;
|
||||
$this->view->render();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
98
extend/app_alipay/lotusphp_runtime/MVC/Context.php
Executable file
98
extend/app_alipay/lotusphp_runtime/MVC/Context.php
Executable file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
class LtContext
|
||||
{
|
||||
/**
|
||||
* The uri property
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $uri;
|
||||
|
||||
protected $strip;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* return the client input in $_SERVER['argv']
|
||||
*
|
||||
* @param integer $offset
|
||||
* @return string
|
||||
*/
|
||||
public function argv($offset)
|
||||
{
|
||||
return isset($_SERVER['argv']) && isset($_SERVER['argv'][$offset]) ? $_SERVER['argv'][$offset] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the client input in $_FILES
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function file($name)
|
||||
{
|
||||
return isset($_FILES[$name]) ? $_FILES[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the client input in $_GET
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
return isset($_GET[$name]) ? $_GET[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the client input in $_POST
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function post($name)
|
||||
{
|
||||
return isset($_POST[$name]) ? $_POST[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the client input in $_REQUEST
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function request($name)
|
||||
{
|
||||
return isset($_REQUEST[$name]) ? $_REQUEST[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the client input in $_SERVER
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function server($name)
|
||||
{
|
||||
if ('REMOTE_ADDR' == $name)
|
||||
{
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
|
||||
{
|
||||
$clientIp = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$clientIp = $_SERVER[$name];
|
||||
}
|
||||
return $clientIp;
|
||||
}
|
||||
else
|
||||
{
|
||||
return isset($_SERVER[$name]) ? $_SERVER[$name] : null;
|
||||
}
|
||||
}
|
||||
}
|
74
extend/app_alipay/lotusphp_runtime/MVC/Dispatcher.php
Executable file
74
extend/app_alipay/lotusphp_runtime/MVC/Dispatcher.php
Executable file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* The Dispatcher class
|
||||
*/
|
||||
class LtDispatcher
|
||||
{
|
||||
public $viewDir;
|
||||
public $viewTplDir;
|
||||
public $viewTplAutoCompile;
|
||||
public $data;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected function _dispatch($module, $action, $context = null, $classType = "Action")
|
||||
{
|
||||
$classType = ucfirst($classType);
|
||||
$actionClassName = $module . $action . $classType;
|
||||
if (!class_exists($actionClassName))
|
||||
{
|
||||
//DebugHelper::debug("{$classType}_CLASS_NOT_FOUND", array(strtolower($classType) => $action));
|
||||
trigger_error("{$actionClassName} CLASS NOT FOUND! module={$module} action={$action} classType={$classType}");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!($context instanceof LtContext))
|
||||
{
|
||||
$newContext = new LtContext;
|
||||
}
|
||||
else
|
||||
{
|
||||
$newContext = clone $context;
|
||||
}
|
||||
$newContext->uri['module'] = $module;
|
||||
$newContext->uri[strtolower($classType)] = $action;
|
||||
$actionInstance = new $actionClassName();
|
||||
$actionInstance->context = $newContext;
|
||||
$actionInstance->viewDir = $this->viewDir;
|
||||
$actionInstance->viewTplDir = $this->viewTplDir; // 模板编译目录
|
||||
$actionInstance->viewTplAutoCompile = $this->viewTplAutoCompile;
|
||||
$actionInstance->executeChain();
|
||||
$this->data = $actionInstance->data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disptach the module/action calling.
|
||||
*
|
||||
* @param $module string
|
||||
* @param $action string
|
||||
* @return void
|
||||
* @todo allow one action dispatch another action
|
||||
*/
|
||||
public function dispatchAction($module, $action, $context = null)
|
||||
{
|
||||
$this->_dispatch($module, $action, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disptach the module/component calling.
|
||||
*
|
||||
* @param $module string
|
||||
* @param $component string
|
||||
* @param $data mixed
|
||||
* @return void
|
||||
*/
|
||||
public function dispatchComponent($module, $component, $context = null)
|
||||
{
|
||||
$cloneOfContext = clone $context;
|
||||
$this->_dispatch($module, $component, $cloneOfContext, "Component");
|
||||
}
|
||||
}
|
385
extend/app_alipay/lotusphp_runtime/MVC/TemplateView.php
Executable file
385
extend/app_alipay/lotusphp_runtime/MVC/TemplateView.php
Executable file
@ -0,0 +1,385 @@
|
||||
<?php
|
||||
class LtTemplateView
|
||||
{
|
||||
public $layout;
|
||||
public $layoutDir;
|
||||
|
||||
public $template;
|
||||
public $templateDir;
|
||||
public $compiledDir;
|
||||
|
||||
public $autoCompile; // bool
|
||||
public $component; // bool
|
||||
private $tpl_include_files;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
/**
|
||||
* 自动编译通过对比文件修改时间确定是否编译,
|
||||
* 当禁止自动编译时, 需要手工删除编译后的文件来重新编译.
|
||||
*
|
||||
* 支持component include自动编译
|
||||
*/
|
||||
$this->autoCompile = true;
|
||||
$this->component = false;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
if (empty($this->compiledDir))
|
||||
{
|
||||
$this->compiledDir = dirname($this->templateDir) . "/viewTpl/";
|
||||
}
|
||||
if (!empty($this->layout))
|
||||
{
|
||||
include $this->template(true);
|
||||
}
|
||||
else if ($this->component)
|
||||
{
|
||||
return; // 模板内使用{component module action}合并文件
|
||||
}
|
||||
else
|
||||
{
|
||||
include $this->template();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回编译后的模板路径, 如果不存在则编译生成并返回路径.
|
||||
* 如果文件存在且允许自动编译, 则对比模板文件和编译后的文件修改时间
|
||||
* 当修改模板后自支重新编译
|
||||
*
|
||||
* @param bool $islayout 是否使用布局
|
||||
* @return string 返回编译后的模板路径
|
||||
*/
|
||||
public function template($islayout = false)
|
||||
{
|
||||
$this->layoutDir = rtrim($this->layoutDir, '\\/') . '/';
|
||||
$this->compiledDir = rtrim($this->compiledDir, '\\/') . '/';
|
||||
$this->templateDir = rtrim($this->templateDir, '\\/') . '/';
|
||||
|
||||
if ($islayout)
|
||||
{
|
||||
$tplfile = $this->layoutDir . $this->layout . '.php';
|
||||
$objfile = $this->compiledDir . 'layout/' . $this->layout . '@' . $this->template . '.php';
|
||||
}
|
||||
else
|
||||
{
|
||||
$tplfile = $this->templateDir . $this->template . '.php';
|
||||
$objfile = $this->compiledDir . $this->template . '.php';
|
||||
}
|
||||
if (is_file($objfile))
|
||||
{
|
||||
if ($this->autoCompile)
|
||||
{
|
||||
$iscompile = true;
|
||||
$tpl_include_files = include($objfile);
|
||||
$last_modified_time = array();
|
||||
foreach($tpl_include_files as $f)
|
||||
{
|
||||
$last_modified_time[] = filemtime($f);
|
||||
}
|
||||
if (filemtime($objfile) == max($last_modified_time))
|
||||
{
|
||||
$iscompile = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iscompile = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 目标文件不存在,编译模板
|
||||
$iscompile = true;
|
||||
}
|
||||
if ($iscompile)
|
||||
{
|
||||
$this->tpl_include_files[] = $objfile;
|
||||
$this->tpl_include_files[] = $tplfile;
|
||||
$dir = pathinfo($objfile, PATHINFO_DIRNAME);
|
||||
if (!is_dir($dir))
|
||||
{
|
||||
if (!mkdir($dir, 0777, true))
|
||||
{
|
||||
trigger_error("Can not create $dir");
|
||||
}
|
||||
}
|
||||
$str = file_get_contents($tplfile);
|
||||
if (!$str)
|
||||
{
|
||||
trigger_error('Template file Not found or have no access!', E_USER_ERROR);
|
||||
}
|
||||
$str = $this->parse($str);
|
||||
if ($this->autoCompile)
|
||||
{
|
||||
$prefix = "<?php\r\nif(isset(\$iscompile)&&true==\$iscompile)\r\nreturn " . var_export(array_unique($this->tpl_include_files), true) . ";?>";
|
||||
$prefix = preg_replace("/([\r\n])+/", "\r\n", $prefix);
|
||||
$postfix = "\r\n<!--Template compilation time : " . date('Y-m-d H:i:s') . "-->\r\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$prefix = '';
|
||||
$postfix = '';
|
||||
}
|
||||
$str = $prefix . $str . $postfix;
|
||||
if (!file_put_contents($objfile, $str))
|
||||
{
|
||||
if (file_put_contents($objfile . '.tmp', $str))
|
||||
{
|
||||
copy($objfile . '.tmp', $objfile); // win下不能重命名已经存在的文件
|
||||
unlink($objfile . '.tmp');
|
||||
}
|
||||
}
|
||||
@chmod($objfile,0777);
|
||||
}
|
||||
return $objfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析{}内字符串,替换php代码
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
protected function parse($str)
|
||||
{
|
||||
$str = $this->removeComments($str);
|
||||
$str = $this->parseIncludeComponent($str);
|
||||
// 回车 换行
|
||||
$str = str_replace("{CR}", "<?php echo \"\\r\";?>", $str);
|
||||
$str = str_replace("{LF}", "<?php echo \"\\n\";?>", $str);
|
||||
// if else elseif
|
||||
$str = preg_replace("/\{if\s+(.+?)\}/", "<?php if(\\1) { ?>", $str);
|
||||
$str = preg_replace("/\{else\}/", "<?php } else { ?>", $str);
|
||||
$str = preg_replace("/\{elseif\s+(.+?)\}/", "<?php } elseif (\\1) { ?>", $str);
|
||||
$str = preg_replace("/\{\/if\}/", "<?php } ?>", $str);
|
||||
// loop
|
||||
$str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}/e", "\$this->addquote('<?php if(isset(\\1) && is_array(\\1)) foreach(\\1 as \\2) { ?>')", $str);
|
||||
$str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/e", "\$this->addquote('<?php if(isset(\\1) && is_array(\\1)) foreach(\\1 as \\2=>\\3) { ?>')", $str);
|
||||
$str = preg_replace("/\{\/loop\}/", "<?php } ?>", $str);
|
||||
// url生成
|
||||
$str = preg_replace("/\{url\(([^}]+)\)\}/", "<?php echo LtObjectUtil::singleton('LtUrl')->generate(\\1);?>", $str);
|
||||
|
||||
// 函数
|
||||
$str = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\s*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str);
|
||||
$str = preg_replace("/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \$\\1;?>", $str);
|
||||
// 变量
|
||||
/**
|
||||
* 放弃支持$name.name.name
|
||||
* $str = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\.([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "<?php echo \\1['\\2'];?>", $str);
|
||||
*/
|
||||
// 其它变量
|
||||
$str = preg_replace("/\{(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "<?php echo \\1;?>", $str);
|
||||
$str = preg_replace("/\{(\\$[a-zA-Z0-9_\.\[\]\'\"\$\x7f-\xff]+)\}/e", "\$this->addquote('<?php echo \\1;?>')", $str);
|
||||
// 类->属性 类->方法
|
||||
$str = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff][+\-\>\$\'\"\,\[\]\(\)a-zA-Z0-9_\x7f-\xff]+)\}/es", "\$this->addquote('<?php echo \\1;?>')", $str);
|
||||
// 常量
|
||||
$str = preg_replace("/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/", "<?php echo \\1;?>", $str);
|
||||
// 静态变量
|
||||
$str = preg_replace("/\{([a-zA-Z0-9_]*::?\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "<?php echo \\1;?>", $str);
|
||||
$str = preg_replace("/\{([a-zA-Z0-9_]*::?\\\$[a-zA-Z0-9_\.\[\]\'\"\$\x7f-\xff]+)\}/e", "\$this->addquote('<?php echo \\1;?>')", $str);
|
||||
|
||||
// 合并相邻php标记
|
||||
$str = preg_replace("/\?\>\s*\<\?php[\r\n\t ]*/", "", $str);
|
||||
/**
|
||||
* 删除空行
|
||||
* Dos和windows采用回车+换行CR/LF表示下一行,
|
||||
* 而UNIX/Linux采用换行符LF表示下一行,
|
||||
* 苹果机(MAC OS系统)则采用回车符CR表示下一行.
|
||||
* CR用符号 '\r'表示, 十进制ASCII代码是13, 十六进制代码为0x0D;
|
||||
* LF使用'\n'符号表示, ASCII代码是10, 十六制为0x0A.
|
||||
* 所以Windows平台上换行在文本文件中是使用 0d 0a 两个字节表示,
|
||||
* 而UNIX和苹果平台上换行则是使用0a或0d一个字节表示.
|
||||
*
|
||||
* 这里统一替换成windows平台回车换行, 第二参数考虑 \\1 保持原有
|
||||
*/
|
||||
$str = preg_replace("/([\r\n])+/", "\r\n", $str);
|
||||
// 删除第一行
|
||||
$str = preg_replace("/^[\r\n]+/", "", $str);
|
||||
// write
|
||||
$str = trim($str);
|
||||
return $str;
|
||||
}
|
||||
/**
|
||||
* 变量加上单引号
|
||||
* 如果是数字就不加单引号, 如果已经加上单引号或者双引号保持不变
|
||||
*/
|
||||
protected function addquote($var)
|
||||
{
|
||||
preg_match_all("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", $var, $vars);
|
||||
foreach($vars[1] as $k => $v)
|
||||
{
|
||||
if (is_numeric($v))
|
||||
{
|
||||
$var = str_replace($vars[0][$k], "[$v]", $var);
|
||||
}
|
||||
else
|
||||
{
|
||||
$var = str_replace($vars[0][$k], "['$v']", $var);
|
||||
}
|
||||
}
|
||||
return str_replace("\\\"", "\"", $var);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板中第一行可以写exit函数防止浏览
|
||||
* 删除行首尾空白, html javascript css注释
|
||||
*/
|
||||
protected function removeComments($str, $clear = false)
|
||||
{
|
||||
$str = str_replace(array('<?php exit?>', '<?php exit;?>'), array('', ''), $str);
|
||||
// 删除行首尾空白
|
||||
$str = preg_replace("/([\r\n]+)[\t ]+/s", "\\1", $str);
|
||||
$str = preg_replace("/[\t ]+([\r\n]+)/s", "\\1", $str);
|
||||
// 删除 {} 前后的 html 注释 <!-- -->
|
||||
$str = preg_replace("/\<\!\-\-\s*\{(.+?)\}\s*\-\-\>/s", "{\\1}", $str);
|
||||
$str = preg_replace("/\<\!\-\-\s*\-\-\>/s", "", $str);
|
||||
// 删除 html注释 存在 < { 就不删除
|
||||
$str = preg_replace("/\<\!\-\-\s*[^\<\{]*\s*\-\-\>/s", "", $str);
|
||||
if ($clear)
|
||||
{
|
||||
$str = $this->clear($str);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
/**
|
||||
* 清除一部分 style script内的注释
|
||||
* 多行注释内部存在 / 字符就不会清除
|
||||
*/
|
||||
protected function clear($str)
|
||||
{
|
||||
preg_match_all("|<script[^>]*>(.*)</script>|Usi", $str, $tvar);
|
||||
foreach($tvar[0] as $k => $v)
|
||||
{
|
||||
// 删除单行注释
|
||||
$v = preg_replace("/\/\/\s*[a-zA-Z0-9_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/", "", $v);
|
||||
// 删除多行注释
|
||||
$v = preg_replace("/\/\*[^\/]*\*\//s", "", $v);
|
||||
$str = str_replace($tvar[0][$k], $v, $str);
|
||||
}
|
||||
preg_match_all("|<style[^>]*>(.*)</style>|Usi", $str, $tvar);
|
||||
foreach($tvar[0] as $k => $v)
|
||||
{
|
||||
// 删除多行注释
|
||||
$v = preg_replace("/\/\*[^\/]*\*\//s", "", $v);
|
||||
$str = str_replace($tvar[0][$k], $v, $str);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @todo 注意相互引用的模板嵌套会导致死循环
|
||||
*/
|
||||
protected function parseIncludeComponent($str)
|
||||
{
|
||||
$count_include_component = preg_match_all("/\{include\s+(.+)\}/", $str, $tvar);
|
||||
$count_include_component += preg_match_all("/\{component\s+([a-zA-Z0-9\.\-_]+)\s+([a-zA-Z0-9\.\-_]+)\}/", $str, $tvar);
|
||||
unset($tvar);
|
||||
while ($count_include_component > 0)
|
||||
{
|
||||
$str = $this->parseInclude($str);
|
||||
$str = $this->parseComponent($str);
|
||||
$count_include_component = preg_match_all("/\{include\s+(.+)\}/", $str, $tvar);
|
||||
$count_include_component += preg_match_all("/\{component\s+([a-zA-Z0-9\.\-_]+)\s+([a-zA-Z0-9\.\-_]+)\}/", $str, $tvar);
|
||||
unset($tvar);
|
||||
}
|
||||
$str = $this->removeComments($str);
|
||||
return $str;
|
||||
}
|
||||
/**
|
||||
* 解析多个{include path/file}合并成一个文件
|
||||
*
|
||||
* @example {include 'debug_info'}
|
||||
* {include 'debug_info.php'}
|
||||
* {include "debug_info"}
|
||||
* {include "debug_info.php"}
|
||||
* {include $this->templateDir . $this->template}
|
||||
*/
|
||||
private function parseInclude($str)
|
||||
{
|
||||
$countSubTpl = preg_match_all("/\{include\s+(.+)\}/", $str, $tvar);
|
||||
while ($countSubTpl > 0)
|
||||
{
|
||||
foreach($tvar[1] as $k => $subfile)
|
||||
{
|
||||
eval("\$subfile = $subfile;");
|
||||
if (is_file($subfile))
|
||||
{
|
||||
$findfile = $subfile;
|
||||
}
|
||||
else if (is_file($subfile . '.php'))
|
||||
{
|
||||
$findfile = $subfile . '.php';
|
||||
}
|
||||
else if (is_file($this->templateDir . $subfile))
|
||||
{
|
||||
$findfile = $this->templateDir . $subfile;
|
||||
}
|
||||
else if (is_file($this->templateDir . $subfile . '.php'))
|
||||
{
|
||||
$findfile = $this->templateDir . $subfile . '.php';
|
||||
}
|
||||
else
|
||||
{
|
||||
$findfile = '';
|
||||
}
|
||||
|
||||
if (!empty($findfile))
|
||||
{
|
||||
$subTpl = file_get_contents($findfile);
|
||||
$this->tpl_include_files[] = $findfile;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 找不到文件
|
||||
$subTpl = 'SubTemplate not found:' . $subfile;
|
||||
}
|
||||
$str = str_replace($tvar[0][$k], $subTpl, $str);
|
||||
}
|
||||
$countSubTpl = preg_match_all("/\{include\s+(.+)\}/", $str, $tvar);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析多个{component module action}合并成一个文件
|
||||
*/
|
||||
private function parseComponent($str)
|
||||
{
|
||||
$countCom = preg_match_all("/\{component\s+([a-zA-Z0-9\.\-_]+)\s+([a-zA-Z0-9\.\-_]+)\}/", $str, $tvar);
|
||||
while ($countCom > 0)
|
||||
{
|
||||
$i = 0;
|
||||
while ($i < $countCom)
|
||||
{
|
||||
$comfile = $this->templateDir . "component/" . $tvar[1][$i] . '-' . $tvar[2][$i] . '.php';
|
||||
if (is_file($comfile))
|
||||
{
|
||||
$subTpl = file_get_contents($comfile);
|
||||
$this->tpl_include_files[] = $comfile;
|
||||
}
|
||||
else
|
||||
{
|
||||
$subTpl = 'SubTemplate not found:' . $comfile;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
$module = $tvar[1][$i];
|
||||
$action = $tvar[2][$i];
|
||||
$subTpl = "<?php
|
||||
\$dispatcher = LtObjectUtil::singleton('LtDispatcher');
|
||||
\$dispatcher->dispatchComponent('$module', '$action', \$this->context);
|
||||
\$comdata = \$dispatcher->data;
|
||||
unset(\$dispatcher);
|
||||
?>
|
||||
" . $subTpl;
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
$str = str_replace($tvar[0][$i], $subTpl, $str);
|
||||
$i++;
|
||||
}
|
||||
$countCom = preg_match_all("/\{component\s+([a-zA-Z0-9\.\-_]+)\s+([a-zA-Z0-9\.\-_]+)\}/", $str, $tvar);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
26
extend/app_alipay/lotusphp_runtime/MVC/View.php
Executable file
26
extend/app_alipay/lotusphp_runtime/MVC/View.php
Executable file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* The View class
|
||||
*/
|
||||
class LtView
|
||||
{
|
||||
public $layoutDir;
|
||||
|
||||
public $templateDir;
|
||||
|
||||
public $layout;
|
||||
|
||||
public $template;
|
||||
|
||||
public function render()
|
||||
{
|
||||
if (!empty($this->layout))
|
||||
{
|
||||
include($this->layoutDir . $this->layout . '.php');
|
||||
}
|
||||
else
|
||||
{
|
||||
include($this->templateDir . $this->template . '.php');
|
||||
}
|
||||
}
|
||||
}
|
33
extend/app_alipay/lotusphp_runtime/ObjectUtil/ObjectUtil.php
Executable file
33
extend/app_alipay/lotusphp_runtime/ObjectUtil/ObjectUtil.php
Executable file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
class LtObjectUtil
|
||||
{
|
||||
static $instances;
|
||||
|
||||
static public function singleton($className, $autoInited = true)
|
||||
{
|
||||
if (empty($className))
|
||||
{
|
||||
trigger_error('empty class name');
|
||||
return false;
|
||||
}
|
||||
$key = strtolower($className);
|
||||
if (isset(self::$instances[$key]))
|
||||
{
|
||||
return self::$instances[$key];
|
||||
}
|
||||
else if (class_exists($className))
|
||||
{
|
||||
$newInstance = new $className;
|
||||
if ($autoInited && method_exists($newInstance, 'init'))
|
||||
{
|
||||
$newInstance->init();
|
||||
}
|
||||
self::$instances[$key] = $newInstance;
|
||||
return $newInstance;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
226
extend/app_alipay/lotusphp_runtime/Pagination/Pagination.php
Executable file
226
extend/app_alipay/lotusphp_runtime/Pagination/Pagination.php
Executable file
@ -0,0 +1,226 @@
|
||||
<?php
|
||||
class LtPagination
|
||||
{
|
||||
public $configHandle;
|
||||
public $conf;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->conf = $this->configHandle->get("pagination.pager");
|
||||
if (empty($this->conf))
|
||||
{
|
||||
$this->conf['per_page'] = 25; //每个页面中希望展示的项目数量
|
||||
$this->conf['num_links_show'] = 9; //数字链接显示数量
|
||||
$this->conf['num_point_start_end'] = 2; //“点”前边和后边的链接数量
|
||||
$this->conf['show_first'] = true;
|
||||
$this->conf['show_prev'] = true;
|
||||
$this->conf['show_next'] = true;
|
||||
$this->conf['show_last'] = true;
|
||||
$this->conf['show_goto'] = false;
|
||||
$this->conf['show_info'] = false;
|
||||
$this->conf['show_point'] = true;
|
||||
$this->conf['show_empty_button'] = false;
|
||||
|
||||
$this->conf['first_text'] = 'First';
|
||||
$this->conf['prev_text'] = 'Prev';
|
||||
$this->conf['next_text'] = 'Next';
|
||||
$this->conf['last_text'] = 'Last';
|
||||
$this->conf['point_text'] = '...';
|
||||
|
||||
$this->conf['full_tag_open'] = '<div class="pages">';
|
||||
$this->conf['full_tag_close'] = '</div>';
|
||||
$this->conf['num_tag_open'] = '';
|
||||
$this->conf['num_tag_close'] = '';
|
||||
$this->conf['link_tag_open'] = '<a href=":url">';
|
||||
$this->conf['link_tag_close'] = '</a>';
|
||||
$this->conf['link_tag_cur_open'] = '<strong>';
|
||||
$this->conf['link_tag_cur_close'] = '</strong>';
|
||||
$this->conf['button_tag_open'] = '<a href=":url" style="font-weight:bold">';
|
||||
$this->conf['button_tag_close'] = '</a>';
|
||||
$this->conf['button_tag_empty_open'] = '<span>';
|
||||
$this->conf['button_tag_empty_close'] = '</span>';
|
||||
$this->conf['point_tag_open'] = '<span>';
|
||||
$this->conf['point_tag_close'] = '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param $page int 当前页
|
||||
* @param $count int 这个数值是你查询数据库得到的数据总量
|
||||
* @param $url string 字串中使用 :page 表示页参数 不在意位置 如/a/:page/c/e
|
||||
*/
|
||||
public function pager($page, $count, $url)
|
||||
{
|
||||
$per_page = empty($this->conf['per_page']) ? 25 : $this->conf['per_page'];
|
||||
$pagecount = ceil($count / $per_page);
|
||||
$pager = $this->renderPager($page, $pagecount, $url);
|
||||
if ($this->conf['show_goto'])
|
||||
{
|
||||
$pager .= $this->renderButton('goto', $page, $pagecount, $url);
|
||||
}
|
||||
if ($this->conf['show_info'])
|
||||
{
|
||||
$pager .= $this->renderButton('info', $page, $pagecount, $url);
|
||||
}
|
||||
return $this->conf['full_tag_open'] . $pager . $this->conf['full_tag_close'];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param $pagenumber int 当前页
|
||||
* @param $pagecount int 总页数
|
||||
* @return string
|
||||
*/
|
||||
public function renderPager($pagenumber, $pagecount, $baseurl = '?page=:page')
|
||||
{
|
||||
$baseurl = urldecode($baseurl);
|
||||
$pager = $this->conf['num_tag_open'];
|
||||
|
||||
$pager .= $this->renderButton('first', $pagenumber, $pagecount, $baseurl);
|
||||
$pager .= $this->renderButton('prev', $pagenumber, $pagecount, $baseurl);
|
||||
|
||||
$startPoint = 1;
|
||||
$endPoint = $this->conf['num_links_show'];
|
||||
$num_links = ceil($this->conf['num_links_show'] / 2) - 1;
|
||||
if ($pagenumber > $num_links)
|
||||
{
|
||||
$startPoint = $pagenumber - $num_links;
|
||||
$endPoint = $pagenumber + $num_links;
|
||||
}
|
||||
|
||||
if ($endPoint > $pagecount)
|
||||
{
|
||||
$startPoint = $pagecount + 1 - $this->conf['num_links_show'];
|
||||
$endPoint = $pagecount;
|
||||
}
|
||||
|
||||
if ($startPoint < 1)
|
||||
{
|
||||
$startPoint = 1;
|
||||
}
|
||||
|
||||
$currentButton = '';
|
||||
if ($this->conf['show_point'])
|
||||
{
|
||||
for($page = 1; $page < $startPoint; $page++)
|
||||
{
|
||||
$url = str_replace(':page', $page, $baseurl);
|
||||
if ($page > $this->conf['num_point_start_end'])
|
||||
{
|
||||
$currentButton .= $this->conf['point_tag_open'] . $this->conf['point_text'] . $this->conf['point_tag_close'];
|
||||
break;
|
||||
}
|
||||
$currentButton .= str_replace(':url', $url, $this->conf['link_tag_open']) . $page . $this->conf['link_tag_close'];
|
||||
}
|
||||
}
|
||||
for ($page = $startPoint; $page <= $endPoint; $page++)
|
||||
{
|
||||
$url = str_replace(':page', $page, $baseurl);
|
||||
if ($page == $pagenumber)
|
||||
{
|
||||
$currentButton .= $this->conf['link_tag_cur_open'] . $page . $this->conf['link_tag_cur_close'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$currentButton .= str_replace(':url', $url, $this->conf['link_tag_open']) . $page . $this->conf['link_tag_close'];
|
||||
}
|
||||
}
|
||||
if ($this->conf['show_point'])
|
||||
{
|
||||
$page = $pagecount - $this->conf['num_point_start_end'];
|
||||
if ($page > $endPoint)
|
||||
{
|
||||
$currentButton .= $this->conf['point_tag_open'] . $this->conf['point_text'] . $this->conf['point_tag_close'];
|
||||
}
|
||||
|
||||
for($page += 1; $page >= $endPoint && $page <= $pagecount; $page++)
|
||||
{
|
||||
if ($page == $endPoint) continue;
|
||||
$url = str_replace(':page', $page, $baseurl);
|
||||
$currentButton .= str_replace(':url', $url, $this->conf['link_tag_open']) . $page . $this->conf['link_tag_close'];
|
||||
}
|
||||
}
|
||||
$pager .= $currentButton;
|
||||
$pager .= $this->renderButton('next', $pagenumber, $pagecount, $baseurl);
|
||||
$pager .= $this->renderButton('last', $pagenumber, $pagecount, $baseurl);
|
||||
$pager .= $this->conf['num_tag_close'];
|
||||
|
||||
return $pager;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param $buttonLabel string 显示文字
|
||||
* @param $pagenumber int 当前页
|
||||
* @param $pagecount int 总页数
|
||||
* @return string
|
||||
*/
|
||||
public function renderButton($buttonLabel, $pagenumber, $pagecount, $baseurl = '?page=:page')
|
||||
{
|
||||
$baseurl = urldecode($baseurl);
|
||||
$destPage = 1;
|
||||
if ('goto' == $buttonLabel)
|
||||
{
|
||||
$button = "goto <input type=\"text\" size=\"3\" onkeydown=\"javascript: if(event.keyCode==13){ location='{$baseurl}'.replace(':page',this.value);return false;}\" />";
|
||||
return $button;
|
||||
}
|
||||
if ('info' == $buttonLabel)
|
||||
{
|
||||
$button = " $pagenumber/$pagecount ";
|
||||
return $button;
|
||||
}
|
||||
switch ($buttonLabel)
|
||||
{
|
||||
case "first":
|
||||
$destPage = 1;
|
||||
$bottenText = $this->conf['first_text'];
|
||||
break;
|
||||
case "prev":
|
||||
$destPage = $pagenumber - 1;
|
||||
$bottenText = $this->conf['prev_text'];
|
||||
break;
|
||||
case "next":
|
||||
$destPage = $pagenumber + 1;
|
||||
$bottenText = $this->conf['next_text'];
|
||||
break;
|
||||
case "last":
|
||||
$destPage = $pagecount;
|
||||
$bottenText = $this->conf['last_text'];
|
||||
break;
|
||||
}
|
||||
$url = str_replace(':page', $destPage, $baseurl);
|
||||
$button = str_replace(':url', $url, $this->conf['button_tag_open']) . $bottenText . $this->conf['button_tag_close'];
|
||||
|
||||
if ($buttonLabel == "first" || $buttonLabel == "prev")
|
||||
{
|
||||
if ($pagenumber <= 1)
|
||||
{
|
||||
$button = $this->conf['show_empty_button'] ? $this->conf['button_tag_empty_open'] . $bottenText . $this->conf['button_tag_empty_close'] : '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($pagenumber >= $pagecount)
|
||||
{
|
||||
$button = $this->conf['show_empty_button'] ? $this->conf['button_tag_empty_open'] . $bottenText . $this->conf['button_tag_empty_close'] : '';
|
||||
}
|
||||
}
|
||||
return $button;
|
||||
}
|
||||
}
|
87
extend/app_alipay/lotusphp_runtime/RBAC/Rbac.php
Executable file
87
extend/app_alipay/lotusphp_runtime/RBAC/Rbac.php
Executable file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
class LtRbac {
|
||||
|
||||
public $configHandle;
|
||||
|
||||
protected $acl;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->acl = $this->configHandle->get('rbac.acl');
|
||||
}
|
||||
|
||||
public function checkAcl($roles, $resource)
|
||||
{
|
||||
$allow = false;
|
||||
// deny priority
|
||||
foreach (array("allow", "deny") as $operation)
|
||||
{
|
||||
foreach($roles as $role)
|
||||
{
|
||||
if (isset($this->acl[$operation][$role]))
|
||||
{
|
||||
// everyone *
|
||||
if (in_array($resource, $this->acl[$operation]['*']))
|
||||
{
|
||||
$allow = "allow" == $operation ? true : false;
|
||||
break;
|
||||
}
|
||||
if (in_array($resource, $this->acl[$operation][$role]))
|
||||
{
|
||||
$allow = "allow" == $operation ? true : false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$res = explode('/', trim($resource, '/'));
|
||||
for ($i = count($res)-1; $i >= 0; $i--)
|
||||
{
|
||||
$res[$i] = '*';
|
||||
$tmp = implode('/', $res);
|
||||
if (in_array($tmp, $this->acl[$operation][$role]))
|
||||
{
|
||||
$allow = "allow" == $operation ? true : false;
|
||||
break;
|
||||
}
|
||||
unset($res[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $allow;
|
||||
}
|
||||
/*
|
||||
private function __set($p,$v)
|
||||
{
|
||||
$this->$p = $v;
|
||||
}
|
||||
|
||||
private function __get($p)
|
||||
{
|
||||
if(isset($this->$p))
|
||||
{
|
||||
return($this->$p);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
194
extend/app_alipay/lotusphp_runtime/Router/Router.php
Executable file
194
extend/app_alipay/lotusphp_runtime/Router/Router.php
Executable file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* The Router class
|
||||
*/
|
||||
class LtRouter
|
||||
{
|
||||
public $configHandle;
|
||||
public $routingTable;
|
||||
public $module;
|
||||
public $action;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil"))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->routingTable = $this->configHandle->get("router.routing_table");
|
||||
if (empty($this->routingTable))
|
||||
{
|
||||
$this->routingTable = array('pattern' => ":module/:action/*",
|
||||
'default' => array('module' => 'default', 'action' => 'index'),
|
||||
'reqs' => array('module' => '[a-zA-Z0-9\.\-_]+',
|
||||
'action' => '[a-zA-Z0-9\.\-_]+'
|
||||
),
|
||||
'varprefix' => ':',
|
||||
'delimiter' => '/',
|
||||
'postfix' => '',
|
||||
'protocol' => 'PATH_INFO', // REWRITE STANDARD
|
||||
);
|
||||
}
|
||||
|
||||
$delimiter = $this->routingTable['delimiter'];
|
||||
$postfix = $this->routingTable['postfix'];
|
||||
$protocol = strtoupper($this->routingTable['protocol']);
|
||||
$module = '';
|
||||
$action = '';
|
||||
$params = array();
|
||||
// HTTP HTTPS
|
||||
if (isset($_SERVER['SERVER_PROTOCOL']))
|
||||
{
|
||||
if (isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO']))
|
||||
{
|
||||
// 忽略后缀
|
||||
$url = rtrim($_SERVER['PATH_INFO'], "$postfix");
|
||||
$url = explode($delimiter, trim($url, "/"));
|
||||
}
|
||||
else if (isset($_SERVER['REQUEST_URI']))
|
||||
{
|
||||
if ('REWRITE' == $protocol)
|
||||
{
|
||||
if (0 == strcmp($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']))
|
||||
{
|
||||
$url = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = substr($_SERVER['REQUEST_URI'], strlen(pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME)));
|
||||
$url = rtrim($url, "$postfix");
|
||||
$url = explode($delimiter, trim($url, "/"));
|
||||
}
|
||||
}
|
||||
else if ('PATH_INFO' == $protocol)
|
||||
{
|
||||
$url = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME']));
|
||||
$url = rtrim($url, "$postfix");
|
||||
$url = explode($delimiter, trim($url, "/"));
|
||||
}
|
||||
else //STANDARD
|
||||
{
|
||||
$url = array();
|
||||
foreach($_GET as $v)
|
||||
{
|
||||
$url[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = array();
|
||||
foreach($_GET as $v)
|
||||
{
|
||||
$url[] = $v;
|
||||
}
|
||||
}
|
||||
$params = $this->matchingRoutingTable($url);
|
||||
$module = $params['module'];
|
||||
$action = $params['action'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// CLI
|
||||
$i = 0;
|
||||
while (isset($_SERVER['argv'][$i]) && isset($_SERVER['argv'][$i + 1]))
|
||||
{
|
||||
if (("-m" == $_SERVER['argv'][$i] || "--module" == $_SERVER['argv'][$i]))
|
||||
{
|
||||
$module = $_SERVER['argv'][$i + 1];
|
||||
}
|
||||
else if (("-a" == $_SERVER['argv'][$i] || "--action" == $_SERVER['argv'][$i]))
|
||||
{
|
||||
$action = $_SERVER['argv'][$i + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = $_SERVER['argv'][$i];
|
||||
$params[$key] = $_SERVER['argv'][$i + 1];
|
||||
}
|
||||
$i = $i + 2;
|
||||
}
|
||||
}
|
||||
// 如果$_GET中不存在配置的变量则添加
|
||||
foreach($params as $k => $v)
|
||||
{
|
||||
!isset($_GET[$k]) && $_GET[$k] = $v;
|
||||
}
|
||||
$this->module = $module;
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* url 匹配路由表
|
||||
*
|
||||
* @param $ [string|array] $url
|
||||
* @return
|
||||
* @todo 修复导致$_GET多出属性的BUG
|
||||
* @todo 如果是rewrite或者path_info模式,可能需要unset module和action两个$_GET变量
|
||||
*/
|
||||
public function matchingRoutingTable($url)
|
||||
{
|
||||
$ret = $this->routingTable['default']; //初始化返回值为路由默认值
|
||||
$reqs = $this->routingTable['reqs'];
|
||||
$delimiter = $this->routingTable['delimiter'];
|
||||
$varprefix = $this->routingTable['varprefix'];
|
||||
$postfix = $this->routingTable['postfix'];
|
||||
$pattern = explode($delimiter, trim($this->routingTable['pattern'], $delimiter));
|
||||
|
||||
/**
|
||||
* 预处理url
|
||||
*/
|
||||
if (is_string($url))
|
||||
{
|
||||
$url = rtrim($url, $postfix); //忽略后缀
|
||||
$url = explode($delimiter, trim($url, $delimiter));
|
||||
}
|
||||
|
||||
foreach($pattern as $k => $v)
|
||||
{
|
||||
if ($v[0] == $varprefix)
|
||||
{
|
||||
// 变量
|
||||
$varname = substr($v, 1);
|
||||
// 匹配变量
|
||||
if (isset($url[$k]))
|
||||
{
|
||||
if (isset($reqs[$varname]))
|
||||
{
|
||||
$regex = "/^{$reqs[$varname]}\$/i";
|
||||
if (preg_match($regex, $url[$k]))
|
||||
{
|
||||
$ret[$varname] = $url[$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($v[0] == '*')
|
||||
{
|
||||
// 通配符
|
||||
$pos = $k;
|
||||
while (isset($url[$pos]) && isset($url[$pos + 1]))
|
||||
{
|
||||
$ret[$url[$pos ++]] = urldecode($url[$pos]);
|
||||
$pos++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 静态
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
56
extend/app_alipay/lotusphp_runtime/Session/Session.php
Executable file
56
extend/app_alipay/lotusphp_runtime/Session/Session.php
Executable file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
class LtSession
|
||||
{
|
||||
public $storeHandle;
|
||||
public $configHandle;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if(!$sessionSavePath = $this->configHandle->get("session.save_path"))
|
||||
{
|
||||
$sessionSavePath = '/tmp/Lotus/session/';
|
||||
}
|
||||
if (!is_object($this->storeHandle))
|
||||
{
|
||||
ini_set('session.save_handler', 'files');
|
||||
if (!is_dir($sessionSavePath))
|
||||
{
|
||||
if (!@mkdir($sessionSavePath, 0777, true))
|
||||
{
|
||||
trigger_error("Can not create $sessionSavePath");
|
||||
}
|
||||
}
|
||||
session_save_path($sessionSavePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->storeHandle->conf = $this->configHandle->get("session.conf");
|
||||
$this->storeHandle->init();
|
||||
session_set_save_handler(
|
||||
array(&$this->storeHandle, 'open'),
|
||||
array(&$this->storeHandle, 'close'),
|
||||
array(&$this->storeHandle, 'read'),
|
||||
array(&$this->storeHandle, 'write'),
|
||||
array(&$this->storeHandle, 'destroy'),
|
||||
array(&$this->storeHandle, 'gc')
|
||||
);
|
||||
}
|
||||
//session_start();
|
||||
//header("Cache-control: private"); // to overcome/fix a bug in IE 6.x
|
||||
}
|
||||
}
|
10
extend/app_alipay/lotusphp_runtime/Session/SessionStore
Executable file
10
extend/app_alipay/lotusphp_runtime/Session/SessionStore
Executable file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
Interface LtSessionStore
|
||||
{
|
||||
public function open($save_path, $name);
|
||||
public function close();
|
||||
public function read($id);
|
||||
public function write($id, $data);
|
||||
public function destroy($id);
|
||||
public function gc($maxlifetime=0);
|
||||
}
|
1
extend/app_alipay/lotusphp_runtime/Session/Store/SessionStoreFile.php
Executable file
1
extend/app_alipay/lotusphp_runtime/Session/Store/SessionStoreFile.php
Executable file
@ -0,0 +1 @@
|
||||
<?php
|
@ -0,0 +1 @@
|
||||
<?php
|
1
extend/app_alipay/lotusphp_runtime/Session/Store/SessionStoreMysql.php
Executable file
1
extend/app_alipay/lotusphp_runtime/Session/Store/SessionStoreMysql.php
Executable file
@ -0,0 +1 @@
|
||||
<?php
|
142
extend/app_alipay/lotusphp_runtime/Session/Store/SessionStoreSqlite.php
Executable file
142
extend/app_alipay/lotusphp_runtime/Session/Store/SessionStoreSqlite.php
Executable file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
class LtSessionSqlite implements LtSessionStore
|
||||
{
|
||||
public $conf;
|
||||
|
||||
private $lifeTime; //session.gc_maxlifetime
|
||||
private $dbHandle;
|
||||
private $dbName;
|
||||
private $tableName;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// --
|
||||
}
|
||||
public function init()
|
||||
{
|
||||
if (isset($this->conf['gc_maxlifetime']))
|
||||
{
|
||||
$this->lifeTime = $this->conf['gc_maxlifetime'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->lifeTime = get_cfg_var("session.gc_maxlifetime");
|
||||
}
|
||||
if (isset($this->conf['table_name']))
|
||||
{
|
||||
$this->tableName = $this->conf['table_name'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->tableName = 'lotus_session';
|
||||
}
|
||||
if (isset($this->conf['db_name']))
|
||||
{
|
||||
$this->dbName = $this->conf['db_name'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dbName = '/tmp/Lotus/session/session_sqlite2.db';
|
||||
}
|
||||
|
||||
if (!$this->dbHandle = sqlite_open($this->dbName, 0666))
|
||||
{
|
||||
trigger_error('session sqlite db error');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function open($savePath, $sessName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
$this->gc($this->lifeTime);
|
||||
return @sqlite_close($this->dbHandle);
|
||||
}
|
||||
|
||||
public function read($sessID)
|
||||
{
|
||||
$res = sqlite_query("SELECT session_data AS d FROM $this->tableName
|
||||
WHERE session_id = '$sessID'
|
||||
AND session_expires > " . time(), $this->dbHandle);
|
||||
if ($row = sqlite_fetch_array($res, SQLITE_ASSOC))
|
||||
{
|
||||
return $row['d'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public function write($sessID, $sessData)
|
||||
{
|
||||
$newExp = time() + $this->lifeTime;
|
||||
$res = sqlite_query("SELECT * FROM $this->tableName
|
||||
WHERE session_id = '$sessID'", $this->dbHandle);
|
||||
if (sqlite_num_rows($res))
|
||||
{
|
||||
sqlite_exec("UPDATE $this->tableName
|
||||
SET session_expires = '$newExp',
|
||||
session_data = '$sessData'
|
||||
WHERE session_id = '$sessID'", $this->dbHandle);
|
||||
if (sqlite_changes($this->dbHandle))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlite_exec("INSERT INTO $this->tableName (
|
||||
session_id,
|
||||
session_expires,
|
||||
session_data)
|
||||
VALUES(
|
||||
'$sessID',
|
||||
'$newExp',
|
||||
'$sessData')", $this->dbHandle);
|
||||
if (sqlite_changes($this->dbHandle))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function destroy($sessID)
|
||||
{
|
||||
sqlite_exec("DELETE FROM $this->tableName WHERE session_id = '$sessID'", $this->dbHandle);
|
||||
if (sqlite_changes($this->dbHandle))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function gc($sessMaxLifeTime)
|
||||
{
|
||||
sqlite_exec("DELETE FROM $this->tableName WHERE session_expires < " . time(), $this->dbHandle);
|
||||
return sqlite_changes($this->dbHandle);
|
||||
}
|
||||
|
||||
public function runOnce()
|
||||
{
|
||||
$sql = "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' AND name='" . $this->tableName . "'";
|
||||
$res = sqlite_query($sql, $this->dbHandle);
|
||||
$row = sqlite_fetch_array($res, SQLITE_ASSOC);
|
||||
if (empty($row))
|
||||
{
|
||||
$sql = "CREATE TABLE $this->tableName (
|
||||
[session_id] VARCHAR(255) NOT NULL PRIMARY KEY,
|
||||
[session_expires] INTEGER DEFAULT '0' NOT NULL,
|
||||
[session_data] TEXT NULL
|
||||
)";
|
||||
return sqlite_exec($sql, $this->dbHandle);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
8
extend/app_alipay/lotusphp_runtime/Store.php
Executable file
8
extend/app_alipay/lotusphp_runtime/Store.php
Executable file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
Interface LtStore
|
||||
{
|
||||
public function add($key, $value);
|
||||
public function del($key);
|
||||
public function get($key);
|
||||
public function update($key, $value);
|
||||
}
|
125
extend/app_alipay/lotusphp_runtime/StoreFile.php
Executable file
125
extend/app_alipay/lotusphp_runtime/StoreFile.php
Executable file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
class LtStoreFile implements LtStore
|
||||
{
|
||||
public $storeDir;
|
||||
public $prefix = 'LtStore';
|
||||
public $useSerialize = false;
|
||||
static public $defaultStoreDir = "/tmp/LtStoreFile/";
|
||||
public function init()
|
||||
{
|
||||
/**
|
||||
* 目录不存在和是否可写在调用add是测试
|
||||
* @todo detect dir is exists and writable
|
||||
*/
|
||||
if (null == $this->storeDir)
|
||||
{
|
||||
$this->storeDir = self::$defaultStoreDir;
|
||||
}
|
||||
$this->storeDir = str_replace('\\', '/', $this->storeDir);
|
||||
$this->storeDir = rtrim($this->storeDir, '\\/') . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* 当key存在时:
|
||||
* 如果没有过期, 不更新值, 返回 false
|
||||
* 如果已经过期, 更新值, 返回 true
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function add($key, $value)
|
||||
{
|
||||
$file = $this->getFilePath($key);
|
||||
$cachePath = pathinfo($file, PATHINFO_DIRNAME);
|
||||
if (!is_dir($cachePath))
|
||||
{
|
||||
if (!@mkdir($cachePath, 0777, true))
|
||||
{
|
||||
trigger_error("Can not create $cachePath");
|
||||
}
|
||||
}
|
||||
if (is_file($file))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ($this->useSerialize)
|
||||
{
|
||||
$value = serialize($value);
|
||||
}
|
||||
$length = file_put_contents($file, '<?php exit;?>' . $value);
|
||||
return $length > 0 ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除不存在的key返回false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function del($key)
|
||||
{
|
||||
$file = $this->getFilePath($key);
|
||||
if (!is_file($file))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return @unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取不存在的key返回false
|
||||
* 已经过期返回false
|
||||
*
|
||||
* @return 成功返回数据,失败返回false
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
$file = $this->getFilePath($key);
|
||||
if (!is_file($file))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$str = file_get_contents($file);
|
||||
$value = substr($str, 13);
|
||||
if ($this->useSerialize)
|
||||
{
|
||||
$value = unserialize($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* key不存在 返回false
|
||||
* 不管有没有过期,都更新数据
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function update($key, $value)
|
||||
{
|
||||
$file = $this->getFilePath($key);
|
||||
if (!is_file($file))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->useSerialize)
|
||||
{
|
||||
$value = serialize($value);
|
||||
}
|
||||
$length = file_put_contents($file, '<?php exit;?>' . $value);
|
||||
return $length > 0 ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getFilePath($key)
|
||||
{
|
||||
$token = md5($key);
|
||||
return $this->storeDir .
|
||||
$this->prefix . '/' .
|
||||
substr($token, 0, 2) .'/' .
|
||||
substr($token, 2, 2) . '/' .
|
||||
$token . '.php';
|
||||
}
|
||||
}
|
54
extend/app_alipay/lotusphp_runtime/StoreMemory.php
Executable file
54
extend/app_alipay/lotusphp_runtime/StoreMemory.php
Executable file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
class LtStoreMemory implements LtStore
|
||||
{
|
||||
protected $stack;
|
||||
|
||||
public function add($key, $value)
|
||||
{
|
||||
if (isset($this->stack[$key]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->stack[$key] = $value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function del($key)
|
||||
{
|
||||
if (isset($this->stack[$key]))
|
||||
{
|
||||
unset($this->stack[$key]);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
{
|
||||
return isset($this->stack[$key]) ? $this->stack[$key] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* key不存在返回false
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function update($key, $value)
|
||||
{
|
||||
if (!isset($this->stack[$key]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->stack[$key] = $value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
142
extend/app_alipay/lotusphp_runtime/Url/Url.php
Executable file
142
extend/app_alipay/lotusphp_runtime/Url/Url.php
Executable file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
class LtUrl
|
||||
{
|
||||
public $configHandle;
|
||||
public $routingTable;
|
||||
public $baseUrl;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
public function init()
|
||||
{
|
||||
$this->routingTable = $this->configHandle->get("router.routing_table");
|
||||
if (empty($this->routingTable))
|
||||
{
|
||||
$this->routingTable = array('pattern' => ":module/:action/*",
|
||||
'default' => array('module' => 'default', 'action' => 'index'),
|
||||
'reqs' => array('module' => '[a-zA-Z0-9\.\-_]+',
|
||||
'action' => '[a-zA-Z0-9\.\-_]+'
|
||||
),
|
||||
'varprefix' => ':',
|
||||
'delimiter' => '/',
|
||||
'postfix' => '',
|
||||
'protocol' => 'PATH_INFO', // REWRITE STANDARD
|
||||
);
|
||||
}
|
||||
|
||||
$protocol = strtoupper($this->routingTable['protocol']);
|
||||
if ('REWRITE' == $protocol)
|
||||
{
|
||||
$this->baseUrl = pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME) . '/';
|
||||
}
|
||||
else if ('STANDARD' == $protocol)
|
||||
{
|
||||
$this->baseUrl = $_SERVER['PHP_SELF'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->baseUrl = '';
|
||||
}
|
||||
}
|
||||
|
||||
public function generate($module, $action, $args = array())
|
||||
{
|
||||
$args = array_merge(array('module' => $module, 'action' => $action), $args);
|
||||
$url = '';
|
||||
// $url = $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://';
|
||||
// $url .= $_SERVER['HTTP_HOST'];
|
||||
// $url .= $_SERVER['SERVER_PORT'] == '80' ? '' : ':'.$_SERVER['SERVER_PORT'];
|
||||
$url .= $this->baseUrl;
|
||||
$url .= $this->reverseMatchingRoutingTable($args);
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将变量反向匹配路由表, 返回匹配后的url
|
||||
*
|
||||
* @param array $params
|
||||
* @return string
|
||||
*/
|
||||
public function reverseMatchingRoutingTable($args)
|
||||
{
|
||||
$ret = $this->routingTable['pattern'];
|
||||
$default = $this->routingTable['default'];
|
||||
$reqs = $this->routingTable['reqs'];
|
||||
$delimiter = $this->routingTable['delimiter'];
|
||||
$varprefix = $this->routingTable['varprefix'];
|
||||
$postfix = $this->routingTable['postfix'];
|
||||
$protocol = strtoupper($this->routingTable['protocol']);
|
||||
if ('STANDARD' == $protocol)
|
||||
{
|
||||
return '?' . http_build_query($args, '', '&');
|
||||
}
|
||||
$pattern = explode($delimiter, trim($this->routingTable['pattern'], $delimiter));
|
||||
|
||||
foreach($pattern as $k => $v)
|
||||
{
|
||||
if ($v[0] == $varprefix)
|
||||
{
|
||||
// 变量
|
||||
$varname = substr($v, 1);
|
||||
// 匹配变量
|
||||
if (isset($args[$varname]))
|
||||
{
|
||||
$regex = "/^{$reqs[$varname]}\$/i";
|
||||
if (preg_match($regex, $args[$varname]))
|
||||
{
|
||||
$ret = str_replace($v, $args[$varname], $ret);
|
||||
unset($args[$varname]);
|
||||
}
|
||||
}
|
||||
else if (isset($default[$varname]))
|
||||
{
|
||||
$ret = str_replace($v, $default[$varname], $ret);
|
||||
}
|
||||
}
|
||||
else if ($v[0] == '*')
|
||||
{
|
||||
// 通配符
|
||||
$tmp = '';
|
||||
foreach($args as $key => $value)
|
||||
{
|
||||
if (!isset($default[$key]))
|
||||
{
|
||||
$tmp .= $key . $delimiter . rawurlencode($value) . $delimiter;
|
||||
}
|
||||
}
|
||||
$tmp = rtrim($tmp, $delimiter);
|
||||
$ret = str_replace($v, $tmp, $ret);
|
||||
$ret = rtrim($ret, $delimiter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 静态
|
||||
}
|
||||
}
|
||||
if ('REWRITE' == $protocol)
|
||||
{
|
||||
$ret = $ret . $postfix;
|
||||
}
|
||||
else if ('PATH_INFO' == $protocol)
|
||||
{
|
||||
$ret = $_SERVER['SCRIPT_NAME'] . $delimiter . $ret . $postfix;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = $ret . $postfix;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
174
extend/app_alipay/lotusphp_runtime/Validator/Validator.php
Executable file
174
extend/app_alipay/lotusphp_runtime/Validator/Validator.php
Executable file
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
class LtValidator
|
||||
{
|
||||
public $configHandle;
|
||||
protected $errorMessages;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->errorMessages = $this->configHandle->get('validator.error_messages');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an element
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array $dtd
|
||||
* @return array
|
||||
*/
|
||||
public function validate($value, $dtd)
|
||||
{
|
||||
$errorMessages = array();
|
||||
$label = $dtd->label;
|
||||
|
||||
if (is_array($dtd->rules) && count($dtd->rules))
|
||||
{
|
||||
$messages = isset($dtd->messages) ? $dtd->messages : array();
|
||||
foreach ($dtd->rules as $key => $val)
|
||||
{
|
||||
// callback_user_function
|
||||
if ('callback_' == substr($key, 0, 9))
|
||||
{
|
||||
$method = substr($key, 9);
|
||||
// 定义了过程函数
|
||||
if (function_exists($method))
|
||||
{
|
||||
if (!$method($value, $dtd->rules[$key]))
|
||||
{
|
||||
if (isset($this->errorMessages[$key]))
|
||||
{
|
||||
$messages[$key] = $this->errorMessages[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
$messages[$key] = "validator.error_messages[$key] empty";
|
||||
}
|
||||
$errorMessages[$key] = sprintf($messages[$key], $label, $dtd->rules[$key]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// 定义了类方法
|
||||
$rc = new ReflectionClass($val);
|
||||
if ($rc->hasMethod($method))
|
||||
{
|
||||
$rcMethod = $rc->getMethod($method);
|
||||
if ($rcMethod->isStatic())
|
||||
{
|
||||
$ret = $rcMethod->invoke(null, $value, $dtd->rules[$key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 非静态方法需要一个实例 有待考虑单例
|
||||
$rcInstance = $rc->newInstance();
|
||||
$ret = $rcMethod->invoke($rcInstance, $value, $dtd->rules[$key]);
|
||||
}
|
||||
if (!$ret)
|
||||
{
|
||||
if (isset($this->errorMessages[$key]))
|
||||
{
|
||||
$messages[$key] = $this->errorMessages[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
$messages[$key] = "validator.error_messages[$key] empty";
|
||||
}
|
||||
$errorMessages[$key] = sprintf($messages[$key], $label, $dtd->rules[$key]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// end callback_user_function
|
||||
$validateFunction = '_' . $key;
|
||||
if ((is_bool($dtd->rules[$key]) || 0 < strlen($dtd->rules[$key])) && !$this->$validateFunction($value, $dtd->rules[$key]))
|
||||
{
|
||||
if (empty($messages[$key]))
|
||||
{
|
||||
if (isset($this->errorMessages[$key]))
|
||||
{
|
||||
$messages[$key] = $this->errorMessages[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
$messages[$key] = "validator.error_messages[$key] empty";
|
||||
}
|
||||
}
|
||||
$errorMessages[$key] = sprintf($messages[$key], $label, $dtd->rules[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $errorMessages;
|
||||
}
|
||||
|
||||
protected function _ban($value, $ruleValue)
|
||||
{
|
||||
return !preg_match($ruleValue, $value);
|
||||
}
|
||||
|
||||
protected function _mask($value, $ruleValue)
|
||||
{
|
||||
return preg_match($ruleValue, $value);
|
||||
}
|
||||
|
||||
protected function _equal_to($value, $ruleValue)
|
||||
{
|
||||
return $value === $ruleValue;
|
||||
}
|
||||
|
||||
protected function _max_length($value, $ruleValue)
|
||||
{
|
||||
return mb_strlen($value) <= $ruleValue;
|
||||
}
|
||||
|
||||
protected function _min_length($value, $ruleValue)
|
||||
{
|
||||
return mb_strlen($value) >= $ruleValue;
|
||||
}
|
||||
|
||||
protected function _max_value($value, $ruleValue)
|
||||
{
|
||||
return $value <= $ruleValue;
|
||||
}
|
||||
|
||||
protected function _min_value($value, $ruleValue)
|
||||
{
|
||||
return $value >= $ruleValue;
|
||||
}
|
||||
|
||||
protected function _min_selected($value, $ruleValue)
|
||||
{
|
||||
return count($value) >= $ruleValue;
|
||||
}
|
||||
|
||||
protected function _max_selected($value, $ruleValue)
|
||||
{
|
||||
return count($value) <= $ruleValue;
|
||||
}
|
||||
|
||||
protected function _required($value, $ruleValue)
|
||||
{
|
||||
if (false == $ruleValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return is_array($value) && count($value) || strlen($value);
|
||||
}
|
||||
}
|
||||
}
|
23
extend/app_alipay/lotusphp_runtime/Validator/ValidatorDtd.php
Executable file
23
extend/app_alipay/lotusphp_runtime/Validator/ValidatorDtd.php
Executable file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
class LtValidatorDtd
|
||||
{
|
||||
public $label;
|
||||
public $rules;
|
||||
public $messages;
|
||||
|
||||
public function __construct($label, $rules, $messages = null)
|
||||
{
|
||||
$this->label = $label;
|
||||
foreach($rules as $key => $rule)
|
||||
{
|
||||
$this->rules[$key] = $rule;
|
||||
}
|
||||
if ($messages)
|
||||
{
|
||||
foreach($messages as $key => $message)
|
||||
{
|
||||
$this->messages[$key] = $message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
304
extend/app_alipay/lotusphp_runtime/XML/Xml.php
Executable file
304
extend/app_alipay/lotusphp_runtime/XML/Xml.php
Executable file
@ -0,0 +1,304 @@
|
||||
<?php
|
||||
/**
|
||||
*返回码定义
|
||||
*/
|
||||
/* 扩展内部错误 */
|
||||
define("INTERNAL_ERR", -1);
|
||||
/* 当前模式下不允许执行该函数 */
|
||||
define("WRONG_MODE", 0);
|
||||
/* 成功 */
|
||||
define("SUCESS", 1);
|
||||
|
||||
/**
|
||||
* 模式定义
|
||||
*/
|
||||
define("READMODE", 0);
|
||||
define("WRITEMODE", 1);
|
||||
|
||||
/**
|
||||
* @desc LtXml用于解析和生成XML文件
|
||||
* 使用前调用 init() 方法对类进行初始化
|
||||
*
|
||||
* LtXml提供两个公共方法 getArray() 和 getString
|
||||
*
|
||||
* getArray() 方法要求传入一个规范的xml字符串,
|
||||
* 返回一个格式化的数组
|
||||
*
|
||||
* getString() 方法要求传入一个格式化的数组,反
|
||||
* 回一个规范的xml字符串
|
||||
* 在使用getString() 方法时,传入的格式化数组可
|
||||
* 通过 createTag() 方法获得。
|
||||
*
|
||||
*/
|
||||
class LtXml {
|
||||
/**
|
||||
* 只支持 ISO-8859-1, UTF-8 和 US-ASCII三种编码
|
||||
*/
|
||||
private $_supportedEncoding = array("ISO-8859-1", "UTF-8", "US-ASCII");
|
||||
|
||||
/**
|
||||
* XMLParser 操作句柄
|
||||
*/
|
||||
private $_handler;
|
||||
|
||||
/**
|
||||
* READMODE 0:读模式,encoding参数不生效,通过输入的string获取version和encoding(getString方法不可用)
|
||||
* WRITEMODE 1:写模式,按照制定的encoding和array生成string(getArray方法不可用)
|
||||
*/
|
||||
public $mode;
|
||||
|
||||
/**
|
||||
* 该 XML 对象的编码,ISO-8859-1, UTF-8(默认) 或 US-ASCII
|
||||
*/
|
||||
public $encoding;
|
||||
|
||||
/**
|
||||
* 该 XML 对象的版本,1.0(默认)
|
||||
*/
|
||||
public $version;
|
||||
|
||||
public function init($mode = 0, $encoding = "UTF-8", $version = "1.0") {
|
||||
$this->mode = $mode;
|
||||
|
||||
$this->encoding = $encoding;
|
||||
$this->version = $version;
|
||||
|
||||
$this->_getParser($encoding);
|
||||
}
|
||||
|
||||
public function getArray($xmlString) {
|
||||
if (READMODE !== $this->mode) {
|
||||
trigger_error("LtXml is on WRITEMODE, and cannot convert XML string to array.");
|
||||
return WRONG_MODE;
|
||||
}
|
||||
|
||||
if (0 === preg_match("/version=[\"|\']([1-9]\d*\.\d*)[\"|\']/", $xmlString, $res)) {
|
||||
trigger_error("Cannot find the version in this XML document.");
|
||||
return INTERNAL_ERR;
|
||||
}
|
||||
else {
|
||||
$this->version = $res[1];
|
||||
}
|
||||
|
||||
if (0 === preg_match("/encoding=[\"|\'](.*?)[\"|\']/", $xmlString, $res)) {
|
||||
$this->encoding = "UTF-8";
|
||||
}
|
||||
else {
|
||||
$this->encoding = strtoupper($res[1]);
|
||||
}
|
||||
|
||||
$_array = $this->_stringToArray($xmlString);
|
||||
if (NULL === $_array) {
|
||||
trigger_error("Fail to get the tag template.");
|
||||
return INTERNAL_ERR;
|
||||
}
|
||||
$currentArray = NULL;
|
||||
$openingTags = array();
|
||||
$array = $this->_getArrayTemplate();
|
||||
|
||||
foreach ($_array as $tag) {
|
||||
$tag["tag"] = strtolower($tag["tag"]);
|
||||
if (isset($tag["type"]) && "close" == $tag["type"]
|
||||
&& isset($tag["tag"]) && ! empty($tag["tag"])) {
|
||||
if ($openingTags[count($openingTags) - 1]["tag"] == $tag["tag"]) {
|
||||
unset($openingTags[count($openingTags) - 1]);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if ((isset($tag["type"]) && "complete" == $tag["type"])
|
||||
|| (isset($tag["type"]) && "open" == $tag["type"])
|
||||
&& isset($tag["tag"]) && ! empty($tag["tag"])){
|
||||
$currentArray = $this->_getArrayTemplate();
|
||||
$currentArray["tag"] = $tag["tag"];
|
||||
$cdata = $tag["value"];
|
||||
$cdata = preg_replace("/^\s*/", "", $cdata);
|
||||
$cdata = preg_replace("/\s*$/", "", $cdata);
|
||||
$currentArray["cdata"] = $cdata;
|
||||
if (isset($tag["attributes"]) && is_array($tag["attributes"])) {
|
||||
foreach($tag["attributes"] as $k => $v) {
|
||||
$currentArray["attributes"][strtolower($k)] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == count($openingTags)) {
|
||||
$openingTags[] = &$array;
|
||||
$openingTags[0] = $currentArray;
|
||||
}
|
||||
else {
|
||||
$subCount = count($openingTags[count($openingTags) - 1]["sub"]);
|
||||
$openingTags[count($openingTags) - 1]["sub"][$subCount] = $currentArray;
|
||||
$openingTags[count($openingTags)] = &$openingTags[count($openingTags) - 1]["sub"][$subCount];
|
||||
}
|
||||
|
||||
if ("complete" == $tag["type"]) {
|
||||
unset($openingTags[count($openingTags) - 1]);
|
||||
}
|
||||
}
|
||||
else if (isset($tag["type"]) && "cdata" == $tag["type"]
|
||||
&& isset($tag["tag"]) && ! empty($tag["tag"])) {
|
||||
if ($tag["tag"] == $openingTags[count($openingTags) - 1]["tag"]) {
|
||||
$cdata = $tag["value"];
|
||||
$cdata = preg_replace("/^\s*/", "", $cdata);
|
||||
$cdata = preg_replace("/\s*$/", "", $cdata);
|
||||
$openingTags[count($openingTags) - 1]["cdata"] .= $cdata;
|
||||
}
|
||||
else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < count($openingTags)) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function getString($xmlArray) {
|
||||
if (WRITEMODE !== $this->mode) {
|
||||
trigger_error("LtXml is on READMODE, and cannot convert array to string.");
|
||||
return WRONG_MODE;
|
||||
}
|
||||
|
||||
$header = "<?xml version=\"{$this->version}\" encoding=\"{$this->encoding}\"". " ?" . ">\n";
|
||||
|
||||
$xmlString = $header;
|
||||
|
||||
$processingTags = array($xmlArray);
|
||||
while (! empty($processingTags)) {
|
||||
if (! isset($processingTags[count($processingTags) -1]["close"])) {
|
||||
$tagArray = $processingTags[count($processingTags) - 1];
|
||||
|
||||
if (0 === $this->_isTag($tagArray)) {
|
||||
trigger_error("The array do not match the format.");
|
||||
return INTERNAL_ERR;
|
||||
}
|
||||
|
||||
$processingTags[count($processingTags) -1]["close"] = "YES";
|
||||
$tagName = $tagArray["tag"];
|
||||
|
||||
$tag = "<{$tagName}";
|
||||
foreach ($tagArray["attributes"] as $key => $value) {
|
||||
$tag .= " {$key}=\"{$value}\"";
|
||||
}
|
||||
if (! empty($tagArray["sub"]) || ! empty($tagArray["cdata"])) {
|
||||
$cdata = $this->_convertEntity($tagArray["cdata"]);
|
||||
$tag .= ">\n{$cdata}\n";
|
||||
for ($i=count($tagArray["sub"]) - 1; $i>=0; $i--) {
|
||||
$subArray = $tagArray["sub"][$i];
|
||||
$processingTags[count($processingTags)] = $subArray;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$processingTags[count($processingTags) - 1]["complete"] = "YES";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$tag = (isset($processingTags[count($processingTags) - 1]["complete"]))
|
||||
? "/>\n"
|
||||
: "</{$processingTags[count($processingTags) - 1]["tag"]}>\n";
|
||||
unset($processingTags[count($processingTags) - 1]);
|
||||
}
|
||||
|
||||
$xmlString .= $tag;
|
||||
}
|
||||
$xmlString = preg_replace("/\n\s*/", "\n", $xmlString);
|
||||
|
||||
return $xmlString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成一个xml节点
|
||||
* @param string tag 标签名
|
||||
* @param string cdata 数据
|
||||
* @param array attr 属性列表
|
||||
* @param array sub 子标签列表
|
||||
*/
|
||||
public function createTag($tag, $cdata = "", $attr = array(), $sub = array()) {
|
||||
$newTag = $this->_getArrayTemplate();
|
||||
if (! is_string($tag)) {
|
||||
trigger_error("Cannot read the tag name.");
|
||||
return INTERNAL_ERR;
|
||||
}
|
||||
|
||||
$newTag["tag"] = $tag;
|
||||
$newTag["cdata"] = $cdata;
|
||||
$newTag["attributes"] = $attr;
|
||||
$newTag["sub"] = $sub;
|
||||
|
||||
return $newTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放xml_parser
|
||||
*/
|
||||
public function free() {
|
||||
xml_parser_free($this->_handler);
|
||||
}
|
||||
|
||||
private function _getParser($encoding) {
|
||||
if (in_array($encoding, $this->_supportedEncoding))
|
||||
$this->_handler = xml_parser_create($encoding);
|
||||
else
|
||||
$this->_handler = NULL;
|
||||
}
|
||||
|
||||
private function _stringToArray($xmlString) {
|
||||
$res = xml_parse_into_struct($this->_handler, $xmlString, $array);
|
||||
if (1 === $res)
|
||||
return $array;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private function _convertEntity($string) {
|
||||
$patterns = array("/</", "/</", "/&/", "/'/", "/\"/");
|
||||
$replacement = array("<", ">", "&", "'", """);
|
||||
|
||||
return preg_replace($patterns, $replacement, $string);
|
||||
}
|
||||
|
||||
private function _rConvertEntity($string) {
|
||||
$patterns = array("/</", "/>/", "/&/", "/'/", "/"/");
|
||||
$replacement = array("<", "<", "&", "'", "\"");
|
||||
|
||||
return preg_replace($patterns, $replacement, $string);
|
||||
}
|
||||
|
||||
private function _getArrayTemplate() {
|
||||
return array("tag" => "", "attributes" => array(), "sub" => array(), "cdata" => "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测传入的参数是否是一个合法的tag数组
|
||||
* @return 0 非法
|
||||
* @return 1 合法
|
||||
*/
|
||||
private function _isTag($tag) {
|
||||
if (! is_array($tag)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! isset($tag["tag"]) || ! is_string($tag["tag"]) || empty($tag["tag"])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! isset($tag["attributes"]) || ! is_array($tag["attributes"])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! isset($tag["sub"]) || ! is_array($tag["sub"])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! isset($tag["cdata"]) || ! is_string($tag["cdata"])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
5
extend/app_alipay/lotusphp_runtime/shortcut.php
Executable file
5
extend/app_alipay/lotusphp_runtime/shortcut.php
Executable file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
function C($className)
|
||||
{
|
||||
return LtObjectUtil::singleton($className);
|
||||
}
|
Reference in New Issue
Block a user