mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-09 03:32:00 +09:00
Added changes from 1.5 branch to the 1.5-DB branch.
git-svn-id: http://xe-core.googlecode.com/svn/branches/1.5.0-DB@8675 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
commit
6831e6e767
587 changed files with 10861 additions and 6716 deletions
|
|
@ -120,7 +120,7 @@ class Context {
|
|||
$this->loadLang(_XE_PATH_.'modules/module/lang');
|
||||
|
||||
// set session handler
|
||||
if($this->db_info->use_db_session != 'N') {
|
||||
if(Context::isInstalled() && $this->db_info->use_db_session != 'N') {
|
||||
$oSessionModel = &getModel('session');
|
||||
$oSessionController = &getController('session');
|
||||
session_set_save_handler(
|
||||
|
|
@ -133,6 +133,7 @@ class Context {
|
|||
);
|
||||
}
|
||||
session_start();
|
||||
if($sess=$_POST[session_name()]) session_id($sess);
|
||||
|
||||
// set authentication information in Context and session
|
||||
if(Context::isInstalled()) {
|
||||
|
|
@ -925,6 +926,8 @@ class Context {
|
|||
**/
|
||||
function get($key) {
|
||||
is_a($this,'Context')?$self=&$this:$self=&Context::getInstance();
|
||||
|
||||
if(!isset($self->context->{$key})) return null;
|
||||
return $self->context->{$key};
|
||||
}
|
||||
|
||||
|
|
@ -1010,7 +1013,7 @@ class Context {
|
|||
$avail_types = array('head', 'body');
|
||||
if(!in_array($type, $avail_types)) $type = $avail_types[0];
|
||||
|
||||
$key = $self->normalizeFilePath($file)."\t".$targetie;
|
||||
$key = Context::getAbsFileUrl($file)."\t".$targetie;
|
||||
$map = &$self->js_files_map;
|
||||
|
||||
// Is this file already registered?
|
||||
|
|
@ -1024,11 +1027,10 @@ class Context {
|
|||
function unloadJsFile($file, $optimized = false, $targetie = '') {
|
||||
is_a($this,'Context')?$self=&$this:$self=&Context::getInstance();
|
||||
|
||||
$realfile = $self->getAbsFileUrl($file);
|
||||
$remove_key = Context::getAbsFileUrl($file)."\t$targetie";
|
||||
|
||||
foreach($self->js_files_map as $key=>$val) {
|
||||
list($_file, $_targetie) = explode("\t", $key);
|
||||
if($self->getAbsFileUrl($_file)==$realfile && $_targetie == $targetie) {
|
||||
if($key === $remove_key) {
|
||||
unset($self->js_files_map[$key]);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1095,7 +1097,9 @@ class Context {
|
|||
function addCSSFile($file, $optimized=false, $media='all', $targetie='',$index=0) {
|
||||
is_a($this,'Context')?$self=&$this:$self=&Context::getInstance();
|
||||
|
||||
$key = $self->normalizeFilePath($file)."\t".$targetie."\t".$media;
|
||||
if(!$media) $media = 'all';
|
||||
|
||||
$key = Context::getAbsFileUrl($file)."\t$targetie\t$media";
|
||||
$map = &$self->css_files_map;
|
||||
|
||||
if (!isset($map[$key]) || (int)$map[$key] > (int)$index) $map[$key] = (int)$index+count($map)/100-1;
|
||||
|
|
@ -1107,11 +1111,10 @@ class Context {
|
|||
function unloadCSSFile($file, $optimized = false, $media = 'all', $targetie = '') {
|
||||
is_a($this,'Context')?$self=&$this:$self=&Context::getInstance();
|
||||
|
||||
$realfile = $self->getAbsFileUrl($file);
|
||||
$remove_key = Context::getAbsFileUrl($file)."\t$targetie\t$media";
|
||||
|
||||
foreach($self->css_files_map as $key => $val) {
|
||||
list($_file, $_targetie, $_media) = explode("\t", $key);
|
||||
if($self->getAbsFileUrl($_file)==$realfile && $_media==$media && $_targetie==$targetie) {
|
||||
if($key === $remove_key) {
|
||||
unset($self->css_files_map[$key]);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,21 @@ class HTMLDisplayHandler {
|
|||
$oTemplate = &TemplateHandler::getInstance();
|
||||
|
||||
// compile module tpl
|
||||
$template_path = $oModule->getTemplatePath();
|
||||
if ($oModule->module_info->module == $oModule->module)
|
||||
$skin = $oModule->origin_module_info->skin;
|
||||
else
|
||||
$skin = $oModule->module_config->skin;
|
||||
|
||||
if ($skin){
|
||||
$theme_skin = explode('.', $skin);
|
||||
if (count($theme_skin) == 2)
|
||||
$template_path = sprintf('./themes/%s/modules/%s/', $theme_skin[0], $theme_skin[1]);
|
||||
else
|
||||
$template_path = $oModule->getTemplatePath();
|
||||
}else
|
||||
$template_path = $oModule->getTemplatePath();
|
||||
$tpl_file = $oModule->getTemplateFile();
|
||||
|
||||
$output = $oTemplate->compile($template_path, $tpl_file);
|
||||
|
||||
// add #xeAdmin div for adminitration pages
|
||||
|
|
@ -92,6 +105,15 @@ class HTMLDisplayHandler {
|
|||
// prevent the 2nd request due to url(none) of the background-image
|
||||
$output = preg_replace('/url\((["\']?)none(["\']?)\)/is', 'none', $output);
|
||||
|
||||
if(is_array(Context::get('INPUT_ERROR')))
|
||||
{
|
||||
$INPUT_ERROR = Context::get('INPUT_ERROR');
|
||||
$keys = array_keys($INPUT_ERROR);
|
||||
$keys = '('.implode('|', $keys).')';
|
||||
|
||||
$output = preg_replace('/(<input[^>]*?)(?:value="[^"]*"([^>]*?name="'.$keys.'"[^>])|(name="'.$keys.'"[^>]*?)(?:value="[^"]*")?)([^>]*?\/?>)/ise', '"\\1\\2\\4 value=\\"".htmlspecialchars($INPUT_ERROR["\\3\\5"])."\\" \\6"', $output);
|
||||
}
|
||||
|
||||
if(__DEBUG__==3) $GLOBALS['__trans_content_elapsed__'] = getMicroTime()-$start;
|
||||
|
||||
// Remove unnecessary information
|
||||
|
|
@ -151,17 +173,16 @@ class HTMLDisplayHandler {
|
|||
$oContext->addJsFile('./common/js/x.min.js', false, '', -100000);
|
||||
$oContext->addJsFile('./common/js/xe.min.js', false, '', -100000);
|
||||
$oContext->addCSSFile('./common/css/xe.min.css', false, 'all', '', -100000);
|
||||
$oContext->addJsFile('./common/js/xml_handler.js', false, '', -100000);
|
||||
}
|
||||
|
||||
// for admin page, add admin css
|
||||
if(Context::get('module')=='admin' || strpos(Context::get('act'),'Admin')>0){
|
||||
if(__DEBUG__) {
|
||||
$oContext->addCSSFile('./modules/admin/tpl/css/font.css', false, 'all', '',10000);
|
||||
$oContext->addCSSFile('./modules/admin/tpl/css/pagination.css', false, 'all', '', 100001);
|
||||
$oContext->addCSSFile('./modules/admin/tpl/css/admin.css', false, 'all', '', 100002);
|
||||
$oContext->addCSSFile('./modules/admin/tpl/css/admin.css', false, 'all', '', 100000);
|
||||
$oContext->addJsFile('./modules/admin/tpl/js/admin.js');
|
||||
} else {
|
||||
$oContext->addCSSFile('./modules/admin/tpl/css/xe_admin.min.css', false, 'all', '',10000);
|
||||
$oContext->addCSSFile('./modules/admin/tpl/css/admin.min.css', false, 'all', '',10000);
|
||||
$oContext->addJsFile('./modules/admin/tpl/js/admin.js');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,12 +101,12 @@ class XEHttpRequest {
|
|||
$request .= $crlf.$post_body;
|
||||
fwrite($sock, $request);
|
||||
|
||||
list($httpver, $code, $status) = split(' +', rtrim(fgets($sock)));
|
||||
list($httpver, $code, $status) = preg_split('/ +/', rtrim(fgets($sock)), 3);
|
||||
|
||||
// read response headers
|
||||
$is_chunked = false;
|
||||
while(strlen(trim($line = fgets($sock)))) {
|
||||
list($equiv, $content) = split(' *: *', rtrim($line));
|
||||
list($equiv, $content) = preg_split('/ *: */', rtrim($line), 1);
|
||||
if(!strcasecmp($equiv, 'Transfer-Encoding') && $content == 'chunked') {
|
||||
$is_chunked = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,44 +16,37 @@ class Mobile {
|
|||
|
||||
function _isFromMobilePhone() {
|
||||
if($this->ismobile !== null) return $this->ismobile;
|
||||
$db_info = Context::getDBInfo();
|
||||
if($db_info->use_mobile_view != "Y" || Context::get('full_browse') || $_COOKIE["FullBrowse"])
|
||||
{
|
||||
$this->ismobile = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$xe_web_path = Context::pathToUrl(_XE_PATH_);
|
||||
|
||||
$m = Context::get('m');
|
||||
if(strlen($m)==1) {
|
||||
if($m == "1") {
|
||||
$_COOKIE["mobile"] = 'true';
|
||||
setcookie("mobile", 'true', 0, $xe_web_path);
|
||||
$this->ismobile = true;
|
||||
}
|
||||
else if($m == "0") {
|
||||
$_COOKIE["mobile"] = 'false';
|
||||
setcookie("mobile", 'false', 0, $xe_web_path);
|
||||
$this->ismobile = false;
|
||||
}
|
||||
$db_info = Context::getDBInfo();
|
||||
if($db_info->use_mobile_view != "Y" || Context::get('full_browse') || $_COOKIE["FullBrowse"]) {
|
||||
return ($this->ismobile = false);
|
||||
}
|
||||
|
||||
$xe_web_path = Context::pathToUrl(_XE_PATH_);
|
||||
|
||||
$m = Context::get('m');
|
||||
if(strlen($m)==1) {
|
||||
if($m == "1") {
|
||||
$_COOKIE['mobile'] = 'true';
|
||||
setcookie('mobile', 'true', 0, $xe_web_path);
|
||||
$this->ismobile = true;
|
||||
} elseif($m == "0") {
|
||||
$_COOKIE['mobile'] = 'false';
|
||||
setcookie('mobile', 'false', 0, $xe_web_path);
|
||||
$this->ismobile = false;
|
||||
}
|
||||
else if(isset($_COOKIE["mobile"])) {
|
||||
if($_COOKIE['mobile'] == 'true') {
|
||||
$this->ismobile = true;
|
||||
}
|
||||
else {
|
||||
$_COOKIE["mobile"] = 'false';
|
||||
setcookie("mobile", 'false', 0, $xe_web_path);
|
||||
$this->ismobile = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(preg_match('/(iPod|iPhone|Android|BlackBerry|SymbianOS|SCH\-M[0-9]+)/',$_SERVER['HTTP_USER_AGENT']))
|
||||
{
|
||||
setcookie("mobile", 'true', 0, $xe_web_path);
|
||||
$this->ismobile = true;
|
||||
}
|
||||
} elseif(isset($_COOKIE['mobile'])) {
|
||||
if($_COOKIE['mobile'] == 'true') {
|
||||
$this->ismobile = true;
|
||||
} else {
|
||||
$_COOKIE['mobile'] = 'false';
|
||||
setcookie('mobile', 'false', 0, $xe_web_path);
|
||||
$this->ismobile = false;
|
||||
}
|
||||
} else {
|
||||
if($this->isMobileCheckByAgent()) {
|
||||
setcookie("mobile", 'true', 0, $xe_web_path);
|
||||
$this->ismobile = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,10 +55,7 @@ class Mobile {
|
|||
|
||||
function isMobileCheckByAgent()
|
||||
{
|
||||
if(preg_match('/(iPod|iPhone|Android|BlackBerry|SymbianOS|SCH\-M[0-9]+)/',$_SERVER['HTTP_USER_AGENT']))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return !!preg_match('/(iPod|iPhone|Android|BlackBerry|SymbianOS|SCH-M\d+|Googlebot-Mobile)/',$_SERVER['HTTP_USER_AGENT']);
|
||||
}
|
||||
|
||||
function setMobile($ismobile)
|
||||
|
|
|
|||
|
|
@ -158,6 +158,8 @@
|
|||
* @return executed module instance
|
||||
**/
|
||||
function procModule() {
|
||||
$oModuleModel = &getModel('module');
|
||||
|
||||
// If error occurred while preparation, return a message instance
|
||||
if($this->error) {
|
||||
$type = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
|
||||
|
|
@ -168,8 +170,6 @@
|
|||
return $oMessageObject;
|
||||
}
|
||||
|
||||
$oModuleModel = &getModel('module');
|
||||
|
||||
// Get action information with conf/action.xml
|
||||
$xml_info = $oModuleModel->getModuleActionXml($this->module);
|
||||
|
||||
|
|
@ -189,6 +189,7 @@
|
|||
|
||||
// get type, kind
|
||||
$type = $xml_info->action->{$this->act}->type;
|
||||
$ruleset = $xml_info->action->{$this->act}->ruleset;
|
||||
$kind = strpos(strtolower($this->act),'admin')!==false?'admin':'';
|
||||
if(!$kind && $this->module == 'admin') $kind = 'admin';
|
||||
if($this->module_info->use_mobile != "Y") Mobile::setMobile(false);
|
||||
|
|
@ -234,6 +235,7 @@
|
|||
if($xml_info->action->{$this->act}) {
|
||||
$forward->module = $module;
|
||||
$forward->type = $xml_info->action->{$this->act}->type;
|
||||
$forward->ruleset = $xml_info->action->{$this->act}->ruleset;
|
||||
$forward->act = $this->act;
|
||||
}
|
||||
}
|
||||
|
|
@ -246,6 +248,7 @@
|
|||
if($forward->module && $forward->type && $forward->act && $forward->act == $this->act) {
|
||||
$kind = strpos(strtolower($forward->act),'admin')!==false?'admin':'';
|
||||
$type = $forward->type;
|
||||
$ruleset = $forward->ruleset;
|
||||
$tpl_path = $oModule->getTemplatePath();
|
||||
$orig_module = $oModule;
|
||||
|
||||
|
|
@ -272,7 +275,7 @@
|
|||
|
||||
$logged_info = $oMemberModel->getLoggedInfo();
|
||||
if($logged_info->is_admin=='Y') {
|
||||
$orig_module->loadSideBar();
|
||||
$orig_module->makeGnbUrl($forward->module);
|
||||
$oModule->setLayoutPath("./modules/admin/tpl");
|
||||
$oModule->setLayoutFile("layout.html");
|
||||
}
|
||||
|
|
@ -289,6 +292,36 @@
|
|||
}
|
||||
}
|
||||
|
||||
// ruleset check...
|
||||
if(!empty($ruleset))
|
||||
{
|
||||
$rulesetModule = $forward->module ? $forward->module : $this->module;
|
||||
$rulesetFile = $oModuleModel->getValidatorFilePath($rulesetModule, $ruleset);
|
||||
if(!empty($rulesetFile))
|
||||
{
|
||||
$Validator = new Validator($rulesetFile);
|
||||
$result = $Validator->validate();
|
||||
if(!$result)
|
||||
{
|
||||
$lastError = $Validator->getLastError();
|
||||
$returnUrl = Context::get('error_return_url');
|
||||
$errorMsg = $lastError['msg'] ? $lastError['msg'] : 'validation error';
|
||||
|
||||
//for xml response
|
||||
$oModule->setError(-1);
|
||||
$oModule->setMessage($errorMsg);
|
||||
//for html redirect
|
||||
$this->error = $errorMsg;
|
||||
$_SESSION['XE_VALIDATOR_ERROR'] = -1;
|
||||
$_SESSION['XE_VALIDATOR_MESSAGE'] = $this->error;
|
||||
$_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = 'error';
|
||||
$_SESSION['XE_VALIDATOR_RETURN_URL'] = $returnUrl;
|
||||
$this->_setInputValueToSession();
|
||||
return $oModule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oModule->setAct($this->act);
|
||||
|
||||
$this->module_info->module_type = $type;
|
||||
|
|
@ -297,16 +330,70 @@
|
|||
if($type == "view" && $this->module_info->use_mobile == "Y" && Mobile::isMobileCheckByAgent())
|
||||
{
|
||||
global $lang;
|
||||
$footer = '<div style="margin:1em 0;padding:.5em;background:#333;border:1px solid #666;border-left:0;border-right:0"><p style="color:#fff;text-align:center;margin:1em 0">'.$lang->msg_pc_to_mobile.' <a href="'.getUrl('m', '1').'" style="color:#FF0; font-weight:bold">'.$lang->cmd_move.'</a></p></div>';
|
||||
$footer = '<div style="margin:1em 0;padding:.5em;background:#333;border:1px solid #666;border-left:0;border-right:0"><p style="text-align:center;margin:1em 0"><a href="'.getUrl('m', '1').'" style="color:#ff0; font-weight:bold">'.$lang->msg_pc_to_mobile.'</a></p></div>';
|
||||
Context::addHtmlFooter($footer);
|
||||
}
|
||||
|
||||
// execute the action, and if failed, set error
|
||||
if(!$oModule->proc()) $this->error = $oModule->getMessage();
|
||||
// if failed message exists in session, set context
|
||||
$this->_setInputErrorToContext();
|
||||
|
||||
$procResult = $oModule->proc();
|
||||
|
||||
if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON')))
|
||||
{
|
||||
$error = $oModule->getError();
|
||||
$message = $oModule->getMessage();
|
||||
$messageType = $oModule->getMessageType();
|
||||
$redirectUrl = $oModule->getRedirectUrl();
|
||||
|
||||
if (!$procResult)
|
||||
{
|
||||
$this->error = $message;
|
||||
if (!$redirectUrl && Context::get('error_return_url')) $redirectUrl = Context::get('error_return_url');
|
||||
$this->_setInputValueToSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(count($_SESSION['INPUT_ERROR']))
|
||||
{
|
||||
Context::set('INPUT_ERROR', $_SESSION['INPUT_ERROR']);
|
||||
$_SESSION['INPUT_ERROR'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION['XE_VALIDATOR_ERROR'] = $error;
|
||||
if ($message != 'success') $_SESSION['XE_VALIDATOR_MESSAGE'] = $message;
|
||||
$_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = $messageType;
|
||||
$_SESSION['XE_VALIDATOR_RETURN_URL'] = $redirectUrl;
|
||||
}
|
||||
|
||||
return $oModule;
|
||||
}
|
||||
|
||||
function _setInputErrorToContext()
|
||||
{
|
||||
if($_SESSION['XE_VALIDATOR_ERROR'] && !Context::get('XE_VALIDATOR_ERROR')) Context::set('XE_VALIDATOR_ERROR', $_SESSION['XE_VALIDATOR_ERROR']);
|
||||
if($_SESSION['XE_VALIDATOR_MESSAGE'] && !Context::get('XE_VALIDATOR_MESSAGE')) Context::set('XE_VALIDATOR_MESSAGE', $_SESSION['XE_VALIDATOR_MESSAGE']);
|
||||
if($_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] && !Context::get('XE_VALIDATOR_MESSAGE_TYPE')) Context::set('XE_VALIDATOR_MESSAGE_TYPE', $_SESSION['XE_VALIDATOR_MESSAGE_TYPE']);
|
||||
if($_SESSION['XE_VALIDATOR_RETURN_URL'] && !Context::get('XE_VALIDATOR_RETURN_URL')) Context::set('XE_VALIDATOR_RETURN_URL', $_SESSION['XE_VALIDATOR_RETURN_URL']);
|
||||
|
||||
$this->_clearErrorSession();
|
||||
}
|
||||
|
||||
function _clearErrorSession()
|
||||
{
|
||||
$_SESSION['XE_VALIDATOR_ERROR'] = '';
|
||||
$_SESSION['XE_VALIDATOR_MESSAGE'] = '';
|
||||
$_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = '';
|
||||
$_SESSION['XE_VALIDATOR_RETURN_URL'] = '';
|
||||
}
|
||||
|
||||
function _setInputValueToSession()
|
||||
{
|
||||
$requestVars = Context::getRequestVars();
|
||||
foreach($requestVars AS $key=>$value) $_SESSION['INPUT_ERROR'][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief display contents from executed module
|
||||
* @param[in] $oModule module instance
|
||||
|
|
@ -329,6 +416,13 @@
|
|||
|
||||
// Use message view object, if HTML call
|
||||
if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) {
|
||||
|
||||
if($_SESSION['XE_VALIDATOR_RETURN_URL'])
|
||||
{
|
||||
header('location:'.$_SESSION['XE_VALIDATOR_RETURN_URL']);
|
||||
return;
|
||||
}
|
||||
|
||||
// If error occurred, handle it
|
||||
if($this->error) {
|
||||
// display content with message module instance
|
||||
|
|
@ -340,13 +434,14 @@
|
|||
|
||||
// If module was called normally, change the templates of the module into ones of the message view module
|
||||
if($oModule) {
|
||||
$oModule->setTemplatePath($oMessageObject->getTemplatePath());
|
||||
$oModule->setTemplateFile($oMessageObject->getTemplateFile());
|
||||
|
||||
$oModule->setTemplatePath($oMessageObject->getTemplatePath());
|
||||
$oModule->setTemplateFile($oMessageObject->getTemplateFile());
|
||||
// Otherwise, set message instance as the target module
|
||||
} else {
|
||||
$oModule = $oMessageObject;
|
||||
}
|
||||
|
||||
$this->_clearErrorSession();
|
||||
}
|
||||
|
||||
// Check if layout_srl exists for the module
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
var $module = NULL; ///< Class name of Xe Module that is identified by mid
|
||||
var $module_srl = NULL; ///< integer value to represent a run-time instance of Module (XE Module)
|
||||
var $module_info = NULL; ///< an object containing the module information
|
||||
var $origin_module_info = NULL;
|
||||
var $xml_info = NULL; ///< an object containing the module description extracted from XML file
|
||||
|
||||
var $module_path = NULL; ///< a path to directory where module source code resides
|
||||
|
|
@ -26,6 +27,8 @@
|
|||
|
||||
var $stop_proc = false; ///< a flag to indicating whether to stop the execution of code.
|
||||
|
||||
var $module_config = NULL;
|
||||
|
||||
/**
|
||||
* @brief setter to set the name of module
|
||||
* @param name of module
|
||||
|
|
@ -51,6 +54,42 @@
|
|||
function setRedirectUrl($url='./') {
|
||||
$this->add('redirect_url', $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get url for redirection
|
||||
**/
|
||||
function getRedirectUrl(){
|
||||
return $this->get('redirect_url');
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set message
|
||||
* @param $message a message string
|
||||
* @param $type type of message (error, info, update)
|
||||
**/
|
||||
function setMessage($message, $type = null){
|
||||
parent::setMessage($message);
|
||||
$this->setMessageType($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set type of message
|
||||
* @param $type type of message (error, info, update)
|
||||
**/
|
||||
function setMessageType($type){
|
||||
$this->add('message_type', $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get type of message
|
||||
**/
|
||||
function getMessageType(){
|
||||
$type = $this->get('message_type');
|
||||
if (!in_array($type, array('error', 'info', 'update'))){
|
||||
$type = $this->getError()?'error':'info';
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sett to set the template path for refresh.html
|
||||
|
|
@ -80,6 +119,7 @@
|
|||
$this->mid = $module_info->mid;
|
||||
$this->module_srl = $module_info->module_srl;
|
||||
$this->module_info = $module_info;
|
||||
$this->origin_module_info = $module_info;
|
||||
$this->xml_info = $xml_info;
|
||||
$this->skin_vars = $module_info->skin_vars;
|
||||
// validate certificate info and permission settings necessary in Web-services
|
||||
|
|
@ -120,8 +160,11 @@
|
|||
}
|
||||
// permission variable settings
|
||||
$this->grant = $grant;
|
||||
|
||||
Context::set('grant', $grant);
|
||||
|
||||
$this->module_config = $oModuleModel->getModuleConfig($this->module, $module_info->site_srl);
|
||||
|
||||
if(method_exists($this, 'init')) $this->init();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,6 +187,9 @@
|
|||
// javascript plugin import
|
||||
$buff = preg_replace_callback('!<\!--%load_js_plugin\(\"([^\"]*?)\"\)-->!is', array($this, '_compileLoadJavascriptPlugin'), $buff);
|
||||
|
||||
// form auto generation
|
||||
$buff = preg_replace_callback('/(<form(?:<\?php.+?\?>|[^<>]+)*?>)(.*?)(<\/form>)/is', array($this, '_compileFormAuthGeneration'), $buff);
|
||||
|
||||
// replace variables
|
||||
$buff = preg_replace_callback('/\{[^@^ ]([^\{\}\n]+)\}/i', array($this, '_compileVarToContext'), $buff);
|
||||
|
||||
|
|
@ -200,6 +203,47 @@
|
|||
$this->buff = '<?php if(!defined("__ZBXE__")) exit();?>'.$buff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 1. remove ruleset from form tag
|
||||
* 2. add hidden tag with ruleset value
|
||||
* 3. if empty default hidden tag, generate hidden tag (ex:mid, vid, act...)
|
||||
* 4. generate return url, return url use in server side validator
|
||||
**/
|
||||
function _compileFormAuthGeneration($matches)
|
||||
{
|
||||
// form ruleset attribute move to hidden tag
|
||||
if($matches[1])
|
||||
{
|
||||
preg_match('/ruleset="([^"]*?)"/is', $matches[1], $m);
|
||||
if($m[0])
|
||||
{
|
||||
$matches[1] = preg_replace('/'.$m[0].'/i', '', $matches[1]);
|
||||
$matches[2] = '<input type="hidden" name="ruleset" value="'.$m[1].'" />'.$matches[2];
|
||||
}
|
||||
}
|
||||
|
||||
// if not exists default hidden tag, generate hidden tag
|
||||
preg_match_all('/<input[^>]* name="(act|mid|vid)"/is', $matches[2], $m2);
|
||||
$checkVar = array('act', 'mid', 'vid');
|
||||
$resultArray = array_diff($checkVar, $m2[1]);
|
||||
if(is_array($resultArray))
|
||||
{
|
||||
$generatedHidden = '';
|
||||
foreach($resultArray AS $key=>$value)
|
||||
{
|
||||
$generatedHidden .= '<input type="hidden" name="'.$value.'" value="{$'.$value.'}">';
|
||||
}
|
||||
$matches[2] = $generatedHidden.$matches[2];
|
||||
}
|
||||
|
||||
// return url generate
|
||||
preg_match('/<input[^>]*name="error_return_url"[^>]*>/is', $matches[2], $m3);
|
||||
if(!$m3[0]) $matches[2] = '<input type="hidden" name="error_return_url" value="{getRequestUriByServerEnviroment()}" />'.$matches[2];
|
||||
|
||||
$matches[0] = '';
|
||||
return implode($matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fetch using ob_* function
|
||||
* @param[in] $compiled_tpl_file path of compiled template file
|
||||
|
|
@ -213,7 +257,7 @@
|
|||
$__Context = &$GLOBALS['__Context__'];
|
||||
$__Context->tpl_path = $this->path;
|
||||
|
||||
if($_SESSION['is_logged']) $__Context->logged_info = $_SESSION['logged_info'];
|
||||
if($_SESSION['is_logged']) $__Context->logged_info = Context::get('logged_info');
|
||||
|
||||
ob_start();
|
||||
$eval_str = "?>".$this->buff;
|
||||
|
|
@ -357,9 +401,16 @@
|
|||
|
||||
$pre_pos = strrpos($pre, '<');
|
||||
|
||||
preg_match('/<(\/|[a-z])/i',$next,$m);
|
||||
$isClosedTagUse = true;
|
||||
preg_match('/<(\/|[!DOCTYPE]|[a-z])/i',$next,$m);
|
||||
// if not use closed tag, find simple closed tag
|
||||
if(!$m[0]) {
|
||||
$isClosedTagUse = false;
|
||||
preg_match('/[^->]\/?>/',$next,$m);
|
||||
}
|
||||
if(!$m[0]) return $buff;
|
||||
$next_pos = strpos($next, $m[0]);
|
||||
if($isClosedTagUse) $next_pos = strpos($next, $m[0]);
|
||||
else $next_pos = strpos($next, $m[0])+2;
|
||||
|
||||
$tag = substr($pre, $pre_pos). substr($next, 0, $next_pos);
|
||||
$pre = substr($pre, 0, $pre_pos);
|
||||
|
|
|
|||
|
|
@ -4,33 +4,220 @@
|
|||
*/
|
||||
class Validator
|
||||
{
|
||||
var $_cache_dir = '';
|
||||
var $_last_error;
|
||||
var $_xml_ruleset = null;
|
||||
var $_rules;
|
||||
var $_filters;
|
||||
var $_has_mb_func;
|
||||
var $_version = '1.0';
|
||||
var $_xml_path = '';
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function Validator($xml_path){
|
||||
function Validator($xml_path=''){
|
||||
$this->_rules = array();
|
||||
$this->_filters = array();
|
||||
$this->_xml_ruleset = null;
|
||||
|
||||
if($xml_path) $this->load($xml_path);
|
||||
|
||||
// predefined rules
|
||||
$this->addRule(array(
|
||||
'email' => '/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/',
|
||||
'userid' => '/^[a-z]+[\w-]*[a-z0-9_]+$/i',
|
||||
'url' => '/^(https?|ftp|mms):\/\/[0-9a-z-]+(\.[_0-9a-z-]+)+(:\d+)?/',
|
||||
'alpha' => '/^[a-z]*$/i',
|
||||
'alpha_number' => '/^[a-z][a-z0-9_]*$/i',
|
||||
'number' => '/^(?:[1-9]\\d*|0)$/'
|
||||
));
|
||||
|
||||
$this->_has_mb_func = is_callable('mb_strlen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a xml file
|
||||
* @param[in] string $xml_path A file name to be loaded
|
||||
*/
|
||||
function load($xml_path) {
|
||||
$this->_xml_ruleset = null;
|
||||
|
||||
$xml_path = realpath($xml_path);
|
||||
if(!is_readable($xml_path)) return false;
|
||||
|
||||
$parser = new XmlParser();
|
||||
$xml = $parser->loadXmlFile($xml_path);
|
||||
if(!isset($xml->ruleset) || !isset($xml->ruleset->fields) || !isset($xml->ruleset->fields->field)) return false;
|
||||
|
||||
// custom rules
|
||||
if(isset($xml->ruleset->customrules) && isset($xml->ruleset->customrules->rule)) {
|
||||
$customrules = $xml->ruleset->customrules->rule;
|
||||
if(!is_array($customrules)) $customrules = array($customrules);
|
||||
|
||||
$rules = array();
|
||||
foreach($customrules as $rule) {
|
||||
if(!isset($rule->attrs) || !isset($rule->attrs->name)) continue;
|
||||
|
||||
$rule = (array)$rule->attrs;
|
||||
$name = $rule['name'];
|
||||
unset($rule['name']);
|
||||
|
||||
$rules[$name] = $rule;
|
||||
}
|
||||
if(count($rules)) $this->addRule($rules);
|
||||
}
|
||||
|
||||
// filters
|
||||
$fields = $xml->ruleset->fields->field;
|
||||
if(!is_array($fields)) $fields = array($fields);
|
||||
|
||||
$filters = array();
|
||||
foreach($fields as $field) {
|
||||
$name = '';
|
||||
$filter = array();
|
||||
|
||||
if(!isset($field->attrs) || !isset($field->attrs->name)) continue;
|
||||
$filter = (array)$field->attrs;
|
||||
|
||||
$name = $filter['name'];
|
||||
unset($filter['name']);
|
||||
|
||||
// conditional statement
|
||||
if(isset($field->if)) {
|
||||
$if = $field->if;
|
||||
if(!is_array($if)) $if = array($if);
|
||||
foreach($if as $idx=>$cond) {
|
||||
$if[$idx] = (array)$cond->attrs;
|
||||
}
|
||||
$filter['if'] = $if;
|
||||
}
|
||||
|
||||
$filters[$name] = $filter;
|
||||
}
|
||||
|
||||
$this->_xml_ruleset = $xml->ruleset;
|
||||
$this->_filters = $filters;
|
||||
$this->_xml_path = $xml_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set root cache directory
|
||||
* @param[in] string $cache_dir Root cache directory
|
||||
*/
|
||||
function setCacheDir($cache_dir){
|
||||
}
|
||||
|
||||
/**
|
||||
* Set target fields to be checked.
|
||||
* The keys of array represents filed's name, its values represents field's vale.
|
||||
* @param[in] array $fields Target fields
|
||||
*/
|
||||
function setFields($fields){
|
||||
function setCacheDir($_cache_dir){
|
||||
if(is_dir($cache_dir)) {
|
||||
$this->$_cache_dir = preg_replace('@/$@', '', $cache_dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the fields. If the fields aren't passed, validation will be execute on the Context variables.
|
||||
* @param[in] (optional) array $fields
|
||||
* @param[in] (optional) array $fields Target fields. The keys of the array represents field's name, its values represents field's value.
|
||||
* @return bool True if it is valid, FALSE otherwise.
|
||||
*/
|
||||
function validate($fields){
|
||||
function validate($fields_=null){
|
||||
if(is_array($fields_)) {
|
||||
$fields = $fields_;
|
||||
} else {
|
||||
$args = array_keys($this->_filters);
|
||||
$fields = (array)Context::getRequestVars();
|
||||
}
|
||||
|
||||
if(!is_array($fields)) return true;
|
||||
|
||||
$filter_default = array(
|
||||
'required' => 'false',
|
||||
'default' => '',
|
||||
'modifiers' => array(),
|
||||
'length' => 0,
|
||||
'equalto' => 0,
|
||||
'rule' => 0,
|
||||
'if' => array()
|
||||
);
|
||||
|
||||
$fields = array_map('trim', $fields);
|
||||
|
||||
foreach($this->_filters as $key=>$filter) {
|
||||
$exists = array_key_exists($key, $fields);
|
||||
$filter = array_merge($filter_default, $filter);
|
||||
$value = $exists ? $fields[$key] : null;
|
||||
|
||||
// conditional statement
|
||||
foreach($filter['if'] as $cond) {
|
||||
if(!isset($cond['test']) || !isset($cond['attr'])) continue;
|
||||
|
||||
$func_body = preg_replace('/\\$(\w+)/', '$c[\'$1\']', $cond['test']);
|
||||
$func = create_function('$c', "return !!({$func_body});");
|
||||
|
||||
if($func($fields)) $filter[$cond['attr']] = $cond['value'];
|
||||
}
|
||||
|
||||
// attr : default
|
||||
if(!$value && strlen($default=trim($filter['default']))) {
|
||||
$value = $default;
|
||||
if(is_null($fields_)) Context::set($key, $value);
|
||||
else $fields_[$key] = $value;
|
||||
}
|
||||
$value_len = strlen($value);
|
||||
|
||||
// attr : modifier
|
||||
if(is_string($modifiers=$filter['modifiers'])) $modifiers = explode(',', trim($modifiers));
|
||||
|
||||
// attr : required
|
||||
if($filter['required'] === 'true' && !$value_len) return $this->error($key, 'isnull');
|
||||
|
||||
// if the field wasn't passed, ignore this value
|
||||
if(!$exists && !$value_len) continue;
|
||||
|
||||
// attr : length
|
||||
if($length=$filter['length']){
|
||||
list($min, $max) = explode(':', trim($length));
|
||||
$is_min_b = (substr($min, -1) === 'b');
|
||||
$is_max_b = (substr($max, -1) === 'b');
|
||||
list($min, $max) = array((int)$min, (int)$max);
|
||||
|
||||
$strbytes = strlen($value);
|
||||
if(!$is_min_b || !$is_max_b){
|
||||
$strlength = $this->_has_mb_func?mb_strlen($value,'utf-8'):$this->mbStrLen($value);
|
||||
}
|
||||
|
||||
if(($min && $min > ($is_min_b?$strbytes:$strlength)) || ($max && $max < ($is_max_b?$strbytes:$strlength))) return $this->error($key, 'outofrange');
|
||||
}
|
||||
|
||||
// equalto
|
||||
if($equalto=$filter['equalto']){
|
||||
if(!array_key_exists($equalto, $fields) || trim($fields[$equalto]) !== $value) return $this->error($key, 'equalto');
|
||||
}
|
||||
|
||||
// rules
|
||||
if($rules=$filter['rule']){
|
||||
$rules = explode(',', $rules);
|
||||
foreach($rules as $rule) {
|
||||
$result = $this->applyRule($rule, $value);
|
||||
// apply the 'not' modifier
|
||||
if(in_array('not', $modifiers)) $result = !$result;
|
||||
if(!$result) return $this->error($key, 'invalid_'.$rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an error
|
||||
* @param[in] $msg error message
|
||||
* @return always false
|
||||
*/
|
||||
function error($field, $msg){
|
||||
$lang_filter = Context::getLang('filter');
|
||||
$msg = isset($lang_filter->{$msg})?$lang_filter->{$msg}:$lang_filter->invalid;
|
||||
$msg = sprintf($msg, Context::getLang($field));
|
||||
|
||||
$this->_last_error = array('field'=>$field, 'msg'=>$msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -38,14 +225,29 @@ class Validator
|
|||
* @return array The last error infomation
|
||||
*/
|
||||
function getLastError(){
|
||||
return $this->_last_error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new rule
|
||||
* @param[in] string $name rule name
|
||||
* @param[in] string $rule
|
||||
* @param[in] mixed $rule
|
||||
*/
|
||||
function addRule($name, $rule){
|
||||
function addRule($name, $rule=''){
|
||||
if(is_array($name)) $args = $name;
|
||||
else $args = array($name=>$rule);
|
||||
|
||||
foreach($args as $name=>$rule){
|
||||
if(!$rule) continue;
|
||||
if(is_string($rule)) $rule = array('type'=>'regex', 'test'=>$rule);
|
||||
|
||||
if($rule['type'] == 'enum') {
|
||||
$delim = isset($rule['delim'])?$rule['delim']:',';
|
||||
$rule['test'] = explode($delim, $rule['test']);
|
||||
}
|
||||
|
||||
$this->_rules[$name] = $rule;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -53,15 +255,66 @@ class Validator
|
|||
* @param[in] string $name rule name
|
||||
*/
|
||||
function removeRule($name){
|
||||
unset($this->_rules[$name]);
|
||||
}
|
||||
|
||||
function addFilter($name, $filter='') {
|
||||
if(is_array($name)) $args = $name;
|
||||
else $args = array($name=>$filter);
|
||||
|
||||
foreach($args as $name=>$filter) {
|
||||
if(!$filter) continue;
|
||||
|
||||
if(isset($filter['if'])) {
|
||||
if(is_array($filter['if']) && count($filter['if'])) {
|
||||
$key = key($filter['if']);
|
||||
if(!is_int($key)) $filter['if'] = array($filter['if']);
|
||||
} else {
|
||||
unset($filter['if']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_filters[$name] = $filter;
|
||||
}
|
||||
}
|
||||
|
||||
function removeFilter($name) {
|
||||
unset($this->_filters[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find whether the field is valid with the rule
|
||||
* @param[in] string $name rule name
|
||||
* @param[in] string $field field name
|
||||
* @param[in] string $value a value to be validated
|
||||
* @return bool TRUE if the field is valid, FALSE otherwise.
|
||||
*/
|
||||
function applyRule($name, $field){
|
||||
function applyRule($name, $value){
|
||||
$rule = $this->_rules[$name];
|
||||
|
||||
switch($rule['type']) {
|
||||
case 'regex':
|
||||
return (preg_match($rule['test'], $value) > 0);
|
||||
case 'enum':
|
||||
return in_array($value, $rule['test']);
|
||||
case 'expr':
|
||||
if(!$rule['func_test']) {
|
||||
$rule['func_test'] = create_function('$a', 'return ('.preg_replace('/\$\$/', '$a', $rule['test']).');');
|
||||
}
|
||||
return $rule['func_test']($value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return
|
||||
*/
|
||||
function mbStrLen($str){
|
||||
$arr = count_chars($str);
|
||||
for($i=0x80; $i < 0xc0; $i++) {
|
||||
unset($arr[$i]);
|
||||
}
|
||||
return array_sum($arr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,6 +322,91 @@ class Validator
|
|||
* @return string Compiled JavaScript file path
|
||||
*/
|
||||
function getJsPath(){
|
||||
if(!$this->_cache_dir) return false;
|
||||
|
||||
$dir = $this->_cache_dir.'/rulesets';
|
||||
if(!is_dir($dir) && !mkdir($dir)) return false;
|
||||
if(!$this->_xml_path) return false;
|
||||
|
||||
$filepath = $dir.'/'.md5($this->_version.' '.$this->_xml_path).'.js';
|
||||
if(is_readable($filepath) && filemtime($filepath) > filemtime($this->_xml_path)) return $filepath;
|
||||
|
||||
$content = $this->_compile2js();
|
||||
if($content === false) return false;
|
||||
|
||||
if(is_callable('file_put_contents')) {
|
||||
@file_put_contents($filepath, $content);
|
||||
} else {
|
||||
$fp = @fopen($filepath, 'w');
|
||||
if(is_resource($fp)) {
|
||||
fwrite($fp, $content);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a ruleset to a javascript file
|
||||
* @private
|
||||
*/
|
||||
function _compile2js() {
|
||||
$content = array();
|
||||
|
||||
// custom rulesets
|
||||
foreach($this->_rules as $name=>$rule) {
|
||||
if(strpos('email,userid,url,alpha,alpha_number,number,', $name.',') !== false) continue;
|
||||
switch($rule['type']) {
|
||||
case 'regex':
|
||||
$content[] = "v.addRule('{$name}', {$rule['test']});";
|
||||
break;
|
||||
case 'enum':
|
||||
$enums = '"'.implode('","', $rule['test']).'"';
|
||||
$content[] = "v.addRule('{$name}', function($$){ return ($.inArray($$,[{$enums}]) > -1); });";
|
||||
break;
|
||||
case 'expr':
|
||||
$content[] = "v.addRule('{$name}', function($$){ return ({$rule['test']}); });";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// filters
|
||||
foreach($this->_filters as $name=>$filter) {
|
||||
$field = array();
|
||||
|
||||
if($filter['required'] == 'true') $field[] = 'required:true';
|
||||
if($filter['rule']) $field[] = "rule:'{$filter['rule']}'";
|
||||
if($filter['default']) $field[] = "default:'{$filter['default']}'";
|
||||
if($filter['modifier']) $field[] = "modifier:'{$filter['modifier']}'";
|
||||
if($filter['length']) {
|
||||
list($min, $max) = explode(':', $filter['length']);
|
||||
if($min) $field[] = "minlength:'{$min}'";
|
||||
if($max) $field[] = "maxlength:'{$max}'";
|
||||
}
|
||||
if($filter['if']) {
|
||||
$ifs = array();
|
||||
foreach($ifs as $if) {
|
||||
$ifs[] = "{test:'{$if['test']}', attr:'{$if['attr']}', value:'{$if['value']}'}";
|
||||
}
|
||||
$field[] = "'if':[".implode(',', $ifs)."]";
|
||||
}
|
||||
if(count($field)) {
|
||||
$field = '{'.implode(',', $field).'}';
|
||||
$content[] = "v.addFilter('{$name}', {$field});";
|
||||
}
|
||||
}
|
||||
|
||||
if(count($content)) {
|
||||
array_unshift($content,
|
||||
'(function($){',
|
||||
'var v = xe.getApp("validator")[0];',
|
||||
'if(!v) return false;'
|
||||
);
|
||||
$content[] = '})(jQuery);'; // array_push
|
||||
|
||||
return implode("\n", $content);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
if(__DEBUG__==3) $start = getMicroTime();
|
||||
|
||||
$this->lang = Context::getLangType();
|
||||
|
||||
$this->input = $input?$input:$GLOBALS['HTTP_RAW_POST_DATA'];
|
||||
$this->input = str_replace(array('',''),array('',''),$this->input);
|
||||
|
||||
|
|
@ -62,7 +63,7 @@
|
|||
}
|
||||
// uncheck the language if no specific language is set.
|
||||
} else {
|
||||
unset($this->lang);
|
||||
$this->lang = '';
|
||||
}
|
||||
|
||||
$this->oParser = xml_parser_create('UTF-8');
|
||||
|
|
@ -119,8 +120,8 @@
|
|||
$node_name = strtolower($node_name);
|
||||
$cur_obj = array_pop($this->output);
|
||||
$parent_obj = &$this->output[count($this->output)-1];
|
||||
if(isset($this->lang)&&$cur_obj->attrs->{'xml:lang'}&&$cur_obj->attrs->{'xml:lang'}!=$this->lang) return;
|
||||
if(isset($this->lang)&&$parent_obj->{$node_name}->attrs->{'xml:lang'}&&$parent_obj->{$node_name}->attrs->{'xml:lang'}!=$this->lang) return;
|
||||
if($this->lang&&$cur_obj->attrs->{'xml:lang'}&&$cur_obj->attrs->{'xml:lang'}!=$this->lang) return;
|
||||
if($this->lang&&$parent_obj->{$node_name}->attrs->{'xml:lang'}&&$parent_obj->{$node_name}->attrs->{'xml:lang'}!=$this->lang) return;
|
||||
|
||||
if(isset($parent_obj->{$node_name})) {
|
||||
$tmp_obj = $parent_obj->{$node_name};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue