mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-07 02:31:40 +09:00
Merge branch 'next' into develop
This commit is contained in:
commit
2b49bd80de
445 changed files with 11109 additions and 25881 deletions
31
.htaccess
31
.htaccess
|
|
@ -13,32 +13,7 @@ RewriteRule ^(.+)/(addons|files|layouts|m\.layouts|modules|widgets|widgetstyles)
|
|||
RewriteCond %{SCRIPT_FILENAME} !-f
|
||||
RewriteRule ^(.+)\.min\.(css|js)$ ./$1.$2 [L]
|
||||
|
||||
# rss, blogAPI
|
||||
RewriteRule ^(rss|atom)$ ./index.php?module=rss&act=$1 [L]
|
||||
RewriteRule ^([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?mid=$1&act=$2 [L]
|
||||
|
||||
# trackback
|
||||
RewriteRule ^([0-9]+)/(.+)/trackback$ ./index.php?document_srl=$1&key=$2&act=trackback [L]
|
||||
RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?mid=$1&document_srl=$2&key=$3&act=trackback [L]
|
||||
|
||||
# document category
|
||||
RewriteRule ^([a-zA-Z0-9_]+)/category/([0-9]+)$ ./index.php?mid=$1&category=$2 [L,QSA]
|
||||
|
||||
# document permanent link
|
||||
RewriteRule ^([0-9]+)$ ./index.php?document_srl=$1 [L,QSA]
|
||||
|
||||
# admin module link
|
||||
RewriteRule ^admin/?$ ./index.php?module=admin [L,QSA]
|
||||
|
||||
# mid link
|
||||
# all other short URLs
|
||||
RewriteCond %{SCRIPT_FILENAME} !-f
|
||||
RewriteCond %{SCRIPT_FILENAME} !-d
|
||||
RewriteRule ^([a-zA-Z0-9_]+)/?$ ./index.php?mid=$1 [L,QSA]
|
||||
|
||||
# mid + document link
|
||||
RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?mid=$1&document_srl=$2 [L,QSA]
|
||||
|
||||
# mid + entry title
|
||||
RewriteRule ^([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?mid=$1&entry=$2 [L,QSA]
|
||||
|
||||
# file download
|
||||
RewriteRule ^files/download/([0-9]+)/([a-zA-Z0-9_-]+)/(.+)$ ./index.php?act=procFileOutput&file_srl=$1&file_key=$2&filename=$3 [L]
|
||||
RewriteRule . index.php [L]
|
||||
|
|
|
|||
|
|
@ -1,131 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<addon version="0.2">
|
||||
<title xml:lang="ko">reCAPTCHA</title>
|
||||
<title xml:lang="en">reCAPTCHA</title>
|
||||
<description xml:lang="ko">구글 reCAPTCHA 서비스를 사용하여 자동 가입 스팸을 방지합니다.</description>
|
||||
<description xml:lang="en">Prevent automated signups and spam with Google's reCAPTCHA service.</description>
|
||||
<version>1.0.0</version>
|
||||
<date>2016-05-27</date>
|
||||
<author email_address="kijin@kijinsung.com" link="https://github.com/kijin">
|
||||
<name xml:lang="ko">Kijin Sung</name>
|
||||
<name xml:lang="en">Kijin Sung</name>
|
||||
</author>
|
||||
<extra_vars>
|
||||
<var name="site_key" type="text">
|
||||
<title xml:lang="ko">Site Key</title>
|
||||
<title xml:lang="en">Site Key</title>
|
||||
</var>
|
||||
<var name="secret_key" type="text">
|
||||
<title xml:lang="ko">Secret Key</title>
|
||||
<title xml:lang="en">Secret Key</title>
|
||||
</var>
|
||||
<var name="use_signup" type="select">
|
||||
<title xml:lang="ko">회원가입에 사용</title>
|
||||
<title xml:lang="en">Use on Signup Form</title>
|
||||
<options value="Y">
|
||||
<title xml:lang="ko">예</title>
|
||||
<title xml:lang="en">Yes</title>
|
||||
</options>
|
||||
<options value="N">
|
||||
<title xml:lang="ko">아니오</title>
|
||||
<title xml:lang="en">No</title>
|
||||
</options>
|
||||
</var>
|
||||
<var name="use_login" type="select">
|
||||
<title xml:lang="ko">로그인에 사용</title>
|
||||
<title xml:lang="en">Use on Login Form</title>
|
||||
<options value="Y">
|
||||
<title xml:lang="ko">예</title>
|
||||
<title xml:lang="en">Yes</title>
|
||||
</options>
|
||||
<options value="N">
|
||||
<title xml:lang="ko">아니오</title>
|
||||
<title xml:lang="en">No</title>
|
||||
</options>
|
||||
</var>
|
||||
<var name="use_recovery" type="select">
|
||||
<title xml:lang="ko">ID/PW찾기에 사용</title>
|
||||
<title xml:lang="en">Use on Account Recovery Form</title>
|
||||
<options value="Y">
|
||||
<title xml:lang="ko">예</title>
|
||||
<title xml:lang="en">Yes</title>
|
||||
</options>
|
||||
<options value="N">
|
||||
<title xml:lang="ko">아니오</title>
|
||||
<title xml:lang="en">No</title>
|
||||
</options>
|
||||
</var>
|
||||
<var name="use_document" type="select">
|
||||
<title xml:lang="ko">글쓰기에 사용</title>
|
||||
<title xml:lang="en">Use on New Document</title>
|
||||
<options value="N">
|
||||
<title xml:lang="ko">아니오</title>
|
||||
<title xml:lang="en">No</title>
|
||||
</options>
|
||||
<options value="Y">
|
||||
<title xml:lang="ko">예</title>
|
||||
<title xml:lang="en">Yes</title>
|
||||
</options>
|
||||
</var>
|
||||
<var name="use_comment" type="select">
|
||||
<title xml:lang="ko">댓글쓰기에 사용</title>
|
||||
<title xml:lang="en">Use on New Comment</title>
|
||||
<options value="N">
|
||||
<title xml:lang="ko">아니오</title>
|
||||
<title xml:lang="en">No</title>
|
||||
</options>
|
||||
<options value="Y">
|
||||
<title xml:lang="ko">예</title>
|
||||
<title xml:lang="en">Yes</title>
|
||||
</options>
|
||||
</var>
|
||||
<var name="target_users" type="select">
|
||||
<title xml:lang="ko">사용 대상</title>
|
||||
<title xml:lang="en">Target Users</title>
|
||||
<options value="non_members">
|
||||
<title xml:lang="ko">비회원만 사용</title>
|
||||
<title xml:lang="en">Non-members Only</title>
|
||||
</options>
|
||||
<options value="everyone">
|
||||
<title xml:lang="ko">모든 방문자에게 사용</title>
|
||||
<title xml:lang="en">Everyone</title>
|
||||
</options>
|
||||
</var>
|
||||
<var name="target_frequency" type="select">
|
||||
<title xml:lang="ko">사용 빈도</title>
|
||||
<title xml:lang="en">Target Frequency</title>
|
||||
<options value="every_time">
|
||||
<title xml:lang="ko">매번 사용</title>
|
||||
<title xml:lang="en">Every Time</title>
|
||||
</options>
|
||||
<options value="first_time_only">
|
||||
<title xml:lang="ko">방문자당 최초 1회만 사용</title>
|
||||
<title xml:lang="en">First Time Only</title>
|
||||
</options>
|
||||
</var>
|
||||
<var name="theme" type="select">
|
||||
<title xml:lang="ko">테마</title>
|
||||
<title xml:lang="en">Theme</title>
|
||||
<options value="light">
|
||||
<title xml:lang="ko">밝은 테마</title>
|
||||
<title xml:lang="en">Light</title>
|
||||
</options>
|
||||
<options value="dark">
|
||||
<title xml:lang="ko">어두운 테마</title>
|
||||
<title xml:lang="en">Dark</title>
|
||||
</options>
|
||||
</var>
|
||||
<var name="size" type="select">
|
||||
<title xml:lang="ko">크기</title>
|
||||
<title xml:lang="en">Size</title>
|
||||
<options value="normal">
|
||||
<title xml:lang="ko">보통</title>
|
||||
<title xml:lang="en">Normal</title>
|
||||
</options>
|
||||
<options value="compact">
|
||||
<title xml:lang="ko">작게</title>
|
||||
<title xml:lang="en">Compact</title>
|
||||
</options>
|
||||
</var>
|
||||
</extra_vars>
|
||||
</addon>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
<?php
|
||||
$lang->msg_recaptcha_connection_error = 'An error occurred while connecting to the reCAPTCHA verification server.';
|
||||
$lang->msg_recaptcha_server_error = 'An error occurred while verifying your reCAPTCHA response.';
|
||||
$lang->msg_recaptcha_invalid_response = 'Please check reCAPTCHA.';
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
<?php
|
||||
$lang->msg_recaptcha_connection_error = 'reCAPTCHA 스팸방지 서버에 접속하는 도중 오류가 발생했습니다.';
|
||||
$lang->msg_recaptcha_server_error = 'reCAPTCHA 스팸방지 서버와 통신하는 도중 오류가 발생했습니다.';
|
||||
$lang->msg_recaptcha_invalid_response = 'reCAPTCHA 스팸방지 기능을 체크해 주십시오.';
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
<?php
|
||||
|
||||
if (!defined('RX_BASEDIR') || !$addon_info->site_key || !$addon_info->secret_key || $called_position !== 'before_module_init')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$current_action = Context::get('act');
|
||||
$current_member = Context::get('logged_info');
|
||||
|
||||
if ($current_member->is_admin === 'Y')
|
||||
{
|
||||
$enable_captcha = false;
|
||||
}
|
||||
elseif ($addon_info->target_users !== 'everyone' && $current_member->member_srl)
|
||||
{
|
||||
$enable_captcha = false;
|
||||
}
|
||||
elseif ($addon_info->target_frequency !== 'every_time' && isset($_SESSION['recaptcha_authenticated']) && $_SESSION['recaptcha_authenticated'])
|
||||
{
|
||||
$enable_captcha = false;
|
||||
}
|
||||
elseif ($addon_info->use_signup === 'Y' && preg_match('/^(?:disp|proc)Member(?:SignUp|Insert)/i', $current_action))
|
||||
{
|
||||
$enable_captcha = true;
|
||||
}
|
||||
elseif ($addon_info->use_login === 'Y' && preg_match('/^(?:disp|proc)MemberLogin(?:Form)?/i', $current_action))
|
||||
{
|
||||
$enable_captcha = true;
|
||||
}
|
||||
elseif ($addon_info->use_recovery === 'Y' && preg_match('/^(?:disp|proc)Member(?:FindAccount|ResendAuthMail)/i', $current_action))
|
||||
{
|
||||
$enable_captcha = true;
|
||||
}
|
||||
elseif ($addon_info->use_document === 'Y' && preg_match('/^(?:disp|proc)Board(Write|InsertDocument)/i', $current_action))
|
||||
{
|
||||
$enable_captcha = true;
|
||||
}
|
||||
elseif ($addon_info->use_comment === 'Y' && (preg_match('/^(?:disp|proc)Board(Content|InsertComment)/i', $current_action) || (!$current_action && Context::get('document_srl'))))
|
||||
{
|
||||
$enable_captcha = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$enable_captcha = false;
|
||||
}
|
||||
|
||||
if ($enable_captcha)
|
||||
{
|
||||
include_once __DIR__ . '/recaptcha.class.php';
|
||||
reCAPTCHA::init($addon_info);
|
||||
|
||||
if (strncasecmp('proc', $current_action, 4) === 0)
|
||||
{
|
||||
getController('module')->addTriggerFunction('moduleObject.proc', 'before', 'reCAPTCHA::check');
|
||||
}
|
||||
else
|
||||
{
|
||||
Context::set('captcha', new reCAPTCHA());
|
||||
}
|
||||
}
|
||||
|
|
@ -8,12 +8,6 @@
|
|||
*/
|
||||
class Context
|
||||
{
|
||||
/**
|
||||
* Allow rewrite
|
||||
* @var bool TRUE: using rewrite mod, FALSE: otherwise
|
||||
*/
|
||||
public $allow_rewrite = FALSE;
|
||||
|
||||
/**
|
||||
* Request method
|
||||
* @var string GET|POST|XMLRPC|JSON
|
||||
|
|
@ -133,23 +127,17 @@ class Context
|
|||
*/
|
||||
private static $_init_called = false;
|
||||
|
||||
/**
|
||||
* Current route information
|
||||
*/
|
||||
private static $_route_info = null;
|
||||
|
||||
/**
|
||||
* object oFrontEndFileHandler()
|
||||
* @var object
|
||||
*/
|
||||
private static $_oFrontEndFileHandler = null;
|
||||
|
||||
/**
|
||||
* SSL action cache file
|
||||
* @var array
|
||||
*/
|
||||
private static $_ssl_actions_cache_file = 'files/cache/common/ssl_actions.php';
|
||||
|
||||
/**
|
||||
* SSL action cache
|
||||
*/
|
||||
private static $_ssl_actions = array();
|
||||
|
||||
/**
|
||||
* Plugin blacklist cache
|
||||
*/
|
||||
|
|
@ -205,13 +193,6 @@ class Context
|
|||
self::$_oFrontEndFileHandler = self::$_instance->oFrontEndFileHandler = new FrontEndFileHandler();
|
||||
self::$_get_vars = self::$_get_vars ?: new stdClass;
|
||||
self::$_tpl_vars = self::$_tpl_vars ?: new stdClass;
|
||||
|
||||
// Include SSL action cache file.
|
||||
self::$_ssl_actions_cache_file = RX_BASEDIR . self::$_ssl_actions_cache_file;
|
||||
if(Rhymix\Framework\Storage::exists(self::$_ssl_actions_cache_file))
|
||||
{
|
||||
self::$_ssl_actions = (include self::$_ssl_actions_cache_file) ?: array();
|
||||
}
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
|
|
@ -246,15 +227,26 @@ class Context
|
|||
self::$_instance = self::getInstance();
|
||||
}
|
||||
|
||||
// Load system configuration.
|
||||
self::loadDBInfo();
|
||||
|
||||
// Set information about the current request.
|
||||
self::_checkGlobalVars();
|
||||
self::setRequestMethod();
|
||||
self::setRequestArguments();
|
||||
if (in_array(self::$_instance->request_method, array('GET', 'POST', 'JSON')))
|
||||
{
|
||||
$method = $_SERVER['REQUEST_METHOD'] ?: 'GET';
|
||||
$url = $_SERVER['REQUEST_URI'];
|
||||
$route_info = Rhymix\Framework\Router::parseURL($method, $url, Rhymix\Framework\Router::getRewriteLevel());
|
||||
self::setRequestArguments($route_info->args);
|
||||
self::$_route_info = $route_info;
|
||||
}
|
||||
else
|
||||
{
|
||||
self::setRequestArguments();
|
||||
}
|
||||
self::setUploadInfo();
|
||||
|
||||
// Load system configuration.
|
||||
self::loadDBInfo();
|
||||
|
||||
// If Rhymix is installed, get virtual site information.
|
||||
if(self::isInstalled())
|
||||
{
|
||||
|
|
@ -266,14 +258,13 @@ class Context
|
|||
define('RX_BASEURL', parse_url($default_url, PHP_URL_PATH));
|
||||
}
|
||||
}
|
||||
$oModuleModel = getModel('module');
|
||||
$site_module_info = $oModuleModel->getDefaultMid() ?: new stdClass;
|
||||
$site_module_info = ModuleModel::getDefaultMid() ?: new stdClass;
|
||||
self::set('site_module_info', $site_module_info);
|
||||
self::set('_default_timezone', ($site_module_info->settings && $site_module_info->settings->timezone) ? $site_module_info->settings->timezone : null);
|
||||
self::set('_default_url', self::$_instance->db_info->default_url = self::getDefaultUrl($site_module_info));
|
||||
self::set('_http_port', self::$_instance->db_info->http_port = $site_module_info->http_port ?: null);
|
||||
self::set('_https_port', self::$_instance->db_info->https_port = $site_module_info->https_port ?: null);
|
||||
self::set('_use_ssl', self::$_instance->db_info->use_ssl = $site_module_info->security ?: 'none');
|
||||
self::set('_use_ssl', self::$_instance->db_info->use_ssl = ($site_module_info->security === 'none' ? 'none' : 'always'));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -285,15 +276,15 @@ class Context
|
|||
self::set('site_module_info', $site_module_info);
|
||||
}
|
||||
|
||||
// Redirect to SSL if the current domain always uses SSL.
|
||||
if ($site_module_info->security === 'always' && !RX_SSL && PHP_SAPI !== 'cli' && !$site_module_info->is_default_replaced)
|
||||
// Redirect to SSL if the current domain requires SSL.
|
||||
if (!RX_SSL && PHP_SAPI !== 'cli' && $site_module_info->security !== 'none' && !$site_module_info->is_default_replaced)
|
||||
{
|
||||
$ssl_url = self::getDefaultUrl($site_module_info) . RX_REQUEST_URL;
|
||||
$ssl_url = self::getDefaultUrl($site_module_info, true) . RX_REQUEST_URL;
|
||||
self::setCacheControl(0);
|
||||
header('Location: ' . $ssl_url, true, 301);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// Load language support.
|
||||
$enabled_langs = self::loadLangSelected();
|
||||
$set_lang_cookie = false;
|
||||
|
|
@ -310,18 +301,17 @@ class Context
|
|||
{
|
||||
$lang_type = $_COOKIE['lang_type'];
|
||||
}
|
||||
elseif(config('locale.auto_select_lang') && count($enabled_langs) > 1)
|
||||
elseif(config('locale.auto_select_lang') && count($enabled_langs) > 1 && isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
|
||||
{
|
||||
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
|
||||
$ua_locale = Rhymix\Framework\UA::getLocale();
|
||||
if (substr($ua_locale, 0, 2) !== 'zh')
|
||||
{
|
||||
foreach($enabled_langs as $lang_code => $lang_name)
|
||||
{
|
||||
if(!strncasecmp($lang_code, $_SERVER['HTTP_ACCEPT_LANGUAGE'], strlen($lang_code)))
|
||||
{
|
||||
$lang_type = $lang_code;
|
||||
$set_lang_cookie = true;
|
||||
}
|
||||
}
|
||||
$ua_locale = substr($ua_locale, 0, 2);
|
||||
}
|
||||
if (isset($enabled_langs[$ua_locale]))
|
||||
{
|
||||
$lang_type = $ua_locale;
|
||||
$set_lang_cookie = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -358,8 +348,8 @@ class Context
|
|||
// set session handler
|
||||
if(self::isInstalled() && config('session.use_db'))
|
||||
{
|
||||
$oSessionModel = getModel('session');
|
||||
$oSessionController = getController('session');
|
||||
$oSessionModel = SessionModel::getInstance();
|
||||
$oSessionController = SessionController::getInstance();
|
||||
ini_set('session.serialize_handler', 'php');
|
||||
session_set_save_handler(
|
||||
array(&$oSessionController, 'open'), array(&$oSessionController, 'close'), array(&$oSessionModel, 'read'), array(&$oSessionController, 'write'), array(&$oSessionController, 'destroy'), array(&$oSessionController, 'gc')
|
||||
|
|
@ -380,12 +370,9 @@ class Context
|
|||
// set authentication information in Context and session
|
||||
if (self::isInstalled())
|
||||
{
|
||||
$oModuleModel = getModel('module');
|
||||
$oModuleModel->loadModuleExtends();
|
||||
|
||||
if (Rhymix\Framework\Session::getMemberSrl())
|
||||
{
|
||||
getController('member')->setSessionInfo();
|
||||
MemberController::getInstance()->setSessionInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -500,90 +487,22 @@ class Context
|
|||
{
|
||||
$config = Rhymix\Framework\Config::getAll();
|
||||
}
|
||||
if (!is_array($config) || !count($config))
|
||||
{
|
||||
self::$_instance->db_info = self::$_instance->db_info ?: new stdClass;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Copy to old format for backward compatibility.
|
||||
self::$_instance->db_info = self::convertDBInfo($config);
|
||||
self::$_instance->allow_rewrite = self::$_instance->db_info->use_rewrite === 'Y';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Rhymix configuration to XE DBInfo format
|
||||
*
|
||||
* @param array $config
|
||||
* @return object
|
||||
*/
|
||||
public static function convertDBInfo($config)
|
||||
{
|
||||
$db_info = new stdClass;
|
||||
$db_info->master_db = array(
|
||||
'db_type' => $config['db']['master']['type'] . ($config['db']['master']['engine'] === 'innodb' ? '_innodb' : ''),
|
||||
'db_hostname' => $config['db']['master']['host'],
|
||||
'db_port' => $config['db']['master']['port'],
|
||||
'db_userid' => $config['db']['master']['user'],
|
||||
'db_password' => $config['db']['master']['pass'],
|
||||
'db_database' => $config['db']['master']['database'],
|
||||
'db_table_prefix' => $config['db']['master']['prefix'],
|
||||
'db_charset' => $config['db']['master']['charset'],
|
||||
);
|
||||
$db_info->slave_db = array();
|
||||
foreach ($config['db'] as $key => $dbconfig)
|
||||
self::$_instance->db_info = new stdClass;
|
||||
if (is_array($config) && count($config))
|
||||
{
|
||||
if ($key !== 'master')
|
||||
{
|
||||
$db_info->slave_db[] = array(
|
||||
'db_type' => $dbconfig['type'] . ($dbconfig['engine'] === 'innodb' ? '_innodb' : ''),
|
||||
'db_hostname' => $dbconfig['host'],
|
||||
'db_port' => $dbconfig['port'],
|
||||
'db_userid' => $dbconfig['user'],
|
||||
'db_password' => $dbconfig['pass'],
|
||||
'db_database' => $dbconfig['database'],
|
||||
'db_table_prefix' => $dbconfig['prefix'],
|
||||
'db_charset' => $dbconfig['charset'],
|
||||
);
|
||||
}
|
||||
self::$_instance->db_info->master_db = array(
|
||||
'db_type' => $config['db']['master']['type'],
|
||||
'db_hostname' => $config['db']['master']['host'],
|
||||
'db_port' => $config['db']['master']['port'],
|
||||
'db_userid' => $config['db']['master']['user'],
|
||||
'db_password' => $config['db']['master']['pass'],
|
||||
'db_database' => $config['db']['master']['database'],
|
||||
'db_table_prefix' => $config['db']['master']['prefix'],
|
||||
'db_charset' => $config['db']['master']['charset'],
|
||||
);
|
||||
}
|
||||
if (!count($db_info->slave_db))
|
||||
{
|
||||
$db_info->slave_db = array($db_info->master_db);
|
||||
}
|
||||
$db_info->use_object_cache = $config['cache']['type'] ?: null;
|
||||
$db_info->ftp_info = new stdClass;
|
||||
$db_info->ftp_info->ftp_host = $config['ftp']['host'];
|
||||
$db_info->ftp_info->ftp_port = $config['ftp']['port'];
|
||||
$db_info->ftp_info->ftp_user = $config['ftp']['user'];
|
||||
$db_info->ftp_info->ftp_pasv = $config['ftp']['pasv'] ? 'Y' : 'N';
|
||||
$db_info->ftp_info->ftp_root_path = $config['ftp']['path'];
|
||||
$db_info->ftp_info->sftp = $config['ftp']['sftp'] ? 'Y' : 'N';
|
||||
$db_info->lang_type = $config['locale']['default_lang'];
|
||||
$db_info->time_zone = $config['locale']['internal_timezone'];
|
||||
$db_info->time_zone = sprintf('%s%02d%02d', $db_info->time_zone >= 0 ? '+' : '-', abs($db_info->time_zone) / 3600, (abs($db_info->time_zone) % 3600 / 60));
|
||||
$db_info->delay_session = $config['session']['delay'] ? 'Y' : 'N';
|
||||
$db_info->use_db_session = $config['session']['use_db'] ? 'Y' : 'N';
|
||||
$db_info->minify_scripts = $config['view']['minify_scripts'] ? 'Y' : 'N';
|
||||
$db_info->admin_ip_list = count($config['admin']['allow']) ? $config['admin']['allow'] : null;
|
||||
$db_info->use_sitelock = $config['lock']['locked'] ? 'Y' : 'N';
|
||||
$db_info->sitelock_title = $config['lock']['title'];
|
||||
$db_info->sitelock_message = $config['lock']['message'];
|
||||
$db_info->sitelock_whitelist = count($config['lock']['allow']) ? $config['lock']['allow'] : array('127.0.0.1');
|
||||
$db_info->embed_white_iframe = $config['mediafilter']['iframe'] ?: $config['embedfilter']['iframe'];
|
||||
$db_info->embed_white_object = $config['mediafilter']['object'] ?: $config['embedfilter']['object'];
|
||||
$db_info->use_mobile_view = (isset($config['mobile']['enabled']) ? $config['mobile']['enabled'] : $config['use_mobile_view']) ? 'Y' : 'N';
|
||||
$db_info->use_prepared_statements = $config['use_prepared_statements'] ? 'Y' : 'N';
|
||||
$db_info->use_rewrite = $config['use_rewrite'] ? 'Y' : 'N';
|
||||
$db_info->use_sso = $config['use_sso'] ? 'Y' : 'N';
|
||||
if (is_array($config['other']))
|
||||
{
|
||||
foreach ($config['other'] as $key => $value)
|
||||
{
|
||||
$db_info->{$key} = $value;
|
||||
}
|
||||
}
|
||||
return $db_info;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -617,12 +536,22 @@ class Context
|
|||
return self::$_instance->db_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current route information
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function getRouteInfo()
|
||||
{
|
||||
return self::$_route_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ssl status
|
||||
*
|
||||
* @return object SSL status (Optional - none|always|optional)
|
||||
* @return object SSL status (none or always)
|
||||
*/
|
||||
public static function getSslStatus()
|
||||
public static function getSSLStatus()
|
||||
{
|
||||
return self::get('_use_ssl');
|
||||
}
|
||||
|
|
@ -631,9 +560,10 @@ class Context
|
|||
* Return default URL
|
||||
*
|
||||
* @param object $site_module_info (optional)
|
||||
* @param bool $use_ssl (optional)
|
||||
* @return string Default URL
|
||||
*/
|
||||
public static function getDefaultUrl($site_module_info = null)
|
||||
public static function getDefaultUrl($site_module_info = null, $use_ssl = null)
|
||||
{
|
||||
if ($site_module_info === null && ($default_url = self::get('_default_url')))
|
||||
{
|
||||
|
|
@ -645,9 +575,9 @@ class Context
|
|||
$site_module_info = self::get('site_module_info');
|
||||
}
|
||||
|
||||
$prefix = $site_module_info->security === 'always' ? 'https://' : 'http://';
|
||||
$prefix = ($site_module_info->security !== 'none' || $use_ssl) ? 'https://' : 'http://';
|
||||
$hostname = $site_module_info->domain;
|
||||
$port = $site_module_info->security === 'always' ? $site_module_info->https_port : $site_module_info->http_port;
|
||||
$port = ($prefix === 'https://') ? $site_module_info->https_port : $site_module_info->http_port;
|
||||
$result = $prefix . $hostname . ($port ? sprintf(':%d', $port) : '') . RX_BASEURL;
|
||||
return $result;
|
||||
}
|
||||
|
|
@ -803,7 +733,7 @@ class Context
|
|||
{
|
||||
return '';
|
||||
}
|
||||
getController('module')->replaceDefinedLangCode(self::$_instance->browser_title);
|
||||
ModuleController::getInstance()->replaceDefinedLangCode(self::$_instance->browser_title);
|
||||
return htmlspecialchars(self::$_instance->browser_title, ENT_QUOTES, 'UTF-8', FALSE);
|
||||
}
|
||||
|
||||
|
|
@ -818,7 +748,7 @@ class Context
|
|||
if ($domain_info && $domain_info->settings && $domain_info->settings->title)
|
||||
{
|
||||
$title = trim($domain_info->settings->title);
|
||||
getController('module')->replaceDefinedLangCode($title);
|
||||
ModuleController::getInstance()->replaceDefinedLangCode($title);
|
||||
return $title;
|
||||
}
|
||||
else
|
||||
|
|
@ -838,7 +768,7 @@ class Context
|
|||
if ($domain_info && $domain_info->settings && $domain_info->settings->subtitle)
|
||||
{
|
||||
$subtitle = trim($domain_info->settings->subtitle);
|
||||
getController('module')->replaceDefinedLangCode($subtitle);
|
||||
ModuleController::getInstance()->replaceDefinedLangCode($subtitle);
|
||||
return $subtitle;
|
||||
}
|
||||
else
|
||||
|
|
@ -1039,11 +969,11 @@ class Context
|
|||
*/
|
||||
public static function convertEncodingStr($str)
|
||||
{
|
||||
if (!$str || utf8_check($str))
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
if (!$str || utf8_check($str))
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
$obj = new stdClass;
|
||||
$obj->str = $str;
|
||||
$obj = self::convertEncoding($obj);
|
||||
|
|
@ -1146,109 +1076,107 @@ class Context
|
|||
self::$_instance->request_method = $_SERVER['REQUEST_METHOD'];
|
||||
}
|
||||
|
||||
// Check POST data
|
||||
if(self::$_instance->request_method === 'POST')
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST')
|
||||
{
|
||||
// Set HTTP_RAW_POST_DATA for compatibility with XE third-party programs.
|
||||
if(!isset($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
// Set variables for XE compatibility.
|
||||
if (isset($_POST['_rx_ajax_compat']) && in_array($_POST['_rx_ajax_compat'], array('JSON', 'XMLRPC')))
|
||||
{
|
||||
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents("php://input");
|
||||
}
|
||||
|
||||
// Pretend that this request is XMLRPC for compatibility with XE third-party.
|
||||
if(isset($_POST['_rx_ajax_compat']) && $_POST['_rx_ajax_compat'] === 'XMLRPC')
|
||||
{
|
||||
self::$_instance->request_method = 'XMLRPC';
|
||||
self::$_instance->request_method = $_POST['_rx_ajax_compat'];
|
||||
return;
|
||||
}
|
||||
|
||||
// Check JSON
|
||||
foreach(array($_SERVER['HTTP_ACCEPT'], $_SERVER['HTTP_CONTENT_TYPE'], $_SERVER['CONTENT_TYPE']) as $header)
|
||||
else
|
||||
{
|
||||
if(strpos($header, 'json') !== false)
|
||||
// Set HTTP_RAW_POST_DATA for third-party apps that look for it.
|
||||
if (!$_POST && !isset($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
self::$_instance->request_method = 'JSON';
|
||||
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents('php://input');
|
||||
}
|
||||
|
||||
// Check the Content-Type header for a hint of JSON.
|
||||
foreach (array('HTTP_ACCEPT', 'HTTP_CONTENT_TYPE', 'CONTENT_TYPE') as $header)
|
||||
{
|
||||
if (isset($_SERVER[$header]) && strpos($_SERVER[$header], 'json') !== false)
|
||||
{
|
||||
self::$_instance->request_method = 'JSON';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Decide whether it's JSON or XMLRPC by looking at the first character of the POST data.
|
||||
if (!$_POST && !empty($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
self::$_instance->request_method = substr($GLOBALS['HTTP_RAW_POST_DATA'], 0, 1) === '<' ? 'XMLRPC' : 'JSON';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check XMLRPC
|
||||
if(!$_POST && !empty($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
self::$_instance->request_method = 'XMLRPC';
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle request arguments for GET/POST
|
||||
*
|
||||
* @param array $router_args
|
||||
* @return void
|
||||
*/
|
||||
public static function setRequestArguments()
|
||||
public static function setRequestArguments(array $router_args = [])
|
||||
{
|
||||
foreach($_REQUEST as $key => $val)
|
||||
// Arguments detected by the router have precedence over GET/POST parameters.
|
||||
$request_args = $_SERVER['REQUEST_METHOD'] === 'GET' ? $_GET : $_POST;
|
||||
if (count($router_args))
|
||||
{
|
||||
if($val === '' || isset(self::$_reserved_keys[$key]) || self::get($key))
|
||||
foreach ($router_args as $key => $val)
|
||||
{
|
||||
continue;
|
||||
$request_args[$key] = $val;
|
||||
}
|
||||
|
||||
$key = escape($key);
|
||||
$val = self::_filterRequestVar($key, $val);
|
||||
$set_to_vars = false;
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET[$key]))
|
||||
{
|
||||
$set_to_vars = true;
|
||||
}
|
||||
elseif($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST[$key]))
|
||||
{
|
||||
$set_to_vars = true;
|
||||
}
|
||||
|
||||
self::set($key, $val, $set_to_vars);
|
||||
}
|
||||
|
||||
// Set deprecated request parameters.
|
||||
if(!$_POST && !empty($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
// Set JSON and XMLRPC arguments.
|
||||
if($_SERVER['REQUEST_METHOD'] === 'POST' && !$_POST && !empty($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
if(self::getRequestMethod() === 'XMLRPC')
|
||||
$params = array();
|
||||
$request_method = self::getRequestMethod();
|
||||
if($request_method === 'XMLRPC')
|
||||
{
|
||||
if(!Rhymix\Framework\Security::checkXXE($GLOBALS['HTTP_RAW_POST_DATA']))
|
||||
{
|
||||
header("HTTP/1.0 400 Bad Request");
|
||||
exit;
|
||||
self::$_instance->security_check = 'DENY ALL';
|
||||
$GLOBALS['HTTP_RAW_POST_DATA'] = '';
|
||||
return;
|
||||
}
|
||||
if(function_exists('libxml_disable_entity_loader'))
|
||||
libxml_disable_entity_loader(true);
|
||||
$params = Rhymix\Framework\Parsers\XMLRPCParser::parse($GLOBALS['HTTP_RAW_POST_DATA']);
|
||||
}
|
||||
elseif($request_method === 'JSON')
|
||||
{
|
||||
if(substr($GLOBALS['HTTP_RAW_POST_DATA'], 0, 1) === '{')
|
||||
{
|
||||
libxml_disable_entity_loader(true);
|
||||
$params = json_decode($GLOBALS['HTTP_RAW_POST_DATA']);
|
||||
}
|
||||
|
||||
$oXml = new XmlParser();
|
||||
$params = $oXml->parse($GLOBALS['HTTP_RAW_POST_DATA'])->methodcall->params;
|
||||
unset($params->node_name, $params->attrs, $params->body);
|
||||
|
||||
foreach((array)$params as $key => $val)
|
||||
else
|
||||
{
|
||||
$key = escape($key);
|
||||
$val = self::_filterXmlVars($key, $val);
|
||||
self::set($key, $val, true);
|
||||
parse_str($GLOBALS['HTTP_RAW_POST_DATA'], $params);
|
||||
}
|
||||
}
|
||||
elseif(self::getRequestMethod() === 'JSON')
|
||||
|
||||
foreach($params as $key => $val)
|
||||
{
|
||||
$params = array();
|
||||
parse_str($GLOBALS['HTTP_RAW_POST_DATA'], $params);
|
||||
foreach($params as $key => $val)
|
||||
if ($val !== '' && !isset($request_args[$key]))
|
||||
{
|
||||
$key = escape($key);
|
||||
$val = self::_filterRequestVar($key, $val);
|
||||
self::set($key, $val, true);
|
||||
$request_args[$key] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter all arguments and set them to Context.
|
||||
foreach($request_args as $key => $val)
|
||||
{
|
||||
if($val !== '' && !isset(self::$_reserved_keys[$key]) && !self::get($key))
|
||||
{
|
||||
$key = escape($key);
|
||||
$val = self::_filterRequestVar($key, $val);
|
||||
self::set($key, $val, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1435,7 +1363,15 @@ class Context
|
|||
{
|
||||
$_val = (int)$_val;
|
||||
}
|
||||
elseif(in_array($key, array('mid', 'vid', 'search_target', 'search_keyword', 'xe_validator_id')) || $_SERVER['REQUEST_METHOD'] === 'GET')
|
||||
elseif(in_array($key, array('mid', 'vid', 'act', 'module')))
|
||||
{
|
||||
$_val = preg_match('/^[a-zA-Z0-9_-]*$/', $_val) ? $_val : null;
|
||||
if($_val === null)
|
||||
{
|
||||
self::$_instance->security_check = 'DENY ALL';
|
||||
}
|
||||
}
|
||||
elseif(in_array($key, array('search_target', 'search_keyword', 'xe_validator_id')) || $_SERVER['REQUEST_METHOD'] === 'GET')
|
||||
{
|
||||
$_val = escape($_val, false);
|
||||
if(ends_with('url', $key, false))
|
||||
|
|
@ -1553,7 +1489,7 @@ class Context
|
|||
}
|
||||
}
|
||||
|
||||
if (in_array(Context::getRequestMethod(), array('XMLRPC', 'JSON', 'JS_CALLBACK')))
|
||||
if (in_array(self::getRequestMethod(), array('XMLRPC', 'JSON', 'JS_CALLBACK')))
|
||||
{
|
||||
$oMessageObject->setMessage(trim($title . "\n\n" . $message));
|
||||
}
|
||||
|
|
@ -1614,6 +1550,12 @@ class Context
|
|||
{
|
||||
static $current_domain = null;
|
||||
static $site_module_info = null;
|
||||
static $rewrite_level = null;
|
||||
if ($rewrite_level === null)
|
||||
{
|
||||
$rewrite_level = Rhymix\Framework\Router::getRewriteLevel();
|
||||
}
|
||||
|
||||
if ($site_module_info === null)
|
||||
{
|
||||
$site_module_info = self::get('site_module_info');
|
||||
|
|
@ -1723,39 +1665,11 @@ class Context
|
|||
$query = '';
|
||||
if(count($get_vars) > 0)
|
||||
{
|
||||
// if using rewrite mod
|
||||
if(self::$_instance->allow_rewrite)
|
||||
{
|
||||
$var_keys = array_keys($get_vars);
|
||||
sort($var_keys);
|
||||
$target = join('.', $var_keys);
|
||||
$act = $get_vars['act'];
|
||||
$mid = $get_vars['mid'];
|
||||
$key = $get_vars['key'];
|
||||
$srl = $get_vars['document_srl'];
|
||||
$tmpArray = array('rss' => 1, 'atom' => 1, 'api' => 1);
|
||||
$is_feed = isset($tmpArray[$act]);
|
||||
$target_map = array(
|
||||
'mid' => $mid,
|
||||
'category.mid' => "$mid/category/" . $get_vars['category'],
|
||||
'entry.mid' => "$mid/entry/" . $get_vars['entry'],
|
||||
'document_srl' => $srl,
|
||||
'document_srl.mid' => "$mid/$srl",
|
||||
'act' => ($is_feed && $act !== 'api') ? $act : '',
|
||||
'act.mid' => $is_feed ? "$mid/$act" : '',
|
||||
'act.document_srl.key' => ($act == 'trackback') ? "$srl/$key/$act" : '',
|
||||
'act.document_srl.key.mid' => ($act == 'trackback') ? "$mid/$srl/$key/$act" : '',
|
||||
);
|
||||
$query = $target_map[$target];
|
||||
}
|
||||
if(!$query && count($get_vars) > 0)
|
||||
{
|
||||
$query = 'index.php?' . http_build_query($get_vars);
|
||||
}
|
||||
$query = Rhymix\Framework\Router::getURL($get_vars, $rewrite_level);
|
||||
}
|
||||
|
||||
// If using SSL always
|
||||
if($site_module_info->security == 'always')
|
||||
if($site_module_info->security !== 'none')
|
||||
{
|
||||
if(!$domain && RX_SSL)
|
||||
{
|
||||
|
|
@ -1766,20 +1680,6 @@ class Context
|
|||
$query = self::getRequestUri(ENFORCE_SSL, $domain) . $query;
|
||||
}
|
||||
}
|
||||
// optional SSL use
|
||||
elseif($site_module_info->security == 'optional')
|
||||
{
|
||||
$ssl_mode = ((self::get('module') === 'admin') || ($get_vars['module'] === 'admin') || (isset($get_vars['act']) && self::isExistsSSLAction($get_vars['act']))) ? ENFORCE_SSL : RELEASE_SSL;
|
||||
if(!$domain && (RX_SSL && ENFORCE_SSL) || (!RX_SSL && RELEASE_SSL))
|
||||
{
|
||||
$query = RX_BASEURL . $query;
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = self::getRequestUri($ssl_mode, $domain) . $query;
|
||||
}
|
||||
}
|
||||
// no SSL
|
||||
else
|
||||
{
|
||||
// currently on SSL but target is not based on SSL
|
||||
|
|
@ -1845,7 +1745,7 @@ class Context
|
|||
}
|
||||
|
||||
$site_module_info = self::get('site_module_info');
|
||||
if ($site_module_info->security === 'always')
|
||||
if ($site_module_info->security !== 'none')
|
||||
{
|
||||
$ssl_mode = ENFORCE_SSL;
|
||||
}
|
||||
|
|
@ -1864,7 +1764,7 @@ class Context
|
|||
{
|
||||
if (!isset($domain_infos[$domain]))
|
||||
{
|
||||
$domain_infos[$domain] = getModel('module')->getSiteInfoByDomain($domain);
|
||||
$domain_infos[$domain] = ModuleModel::getInstance()->getSiteInfoByDomain($domain);
|
||||
}
|
||||
$site_module_info = $domain_infos[$domain] ?: $site_module_info;
|
||||
}
|
||||
|
|
@ -2005,91 +1905,60 @@ class Context
|
|||
/**
|
||||
* Register if an action is to be encrypted by SSL. Those actions are sent to https in common/js/xml_handler.js
|
||||
*
|
||||
* @deprecated
|
||||
* @param string $action act name
|
||||
* @return void
|
||||
*/
|
||||
public static function addSSLAction($action)
|
||||
{
|
||||
if(isset(self::$_ssl_actions[$action]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self::$_ssl_actions[$action] = 1;
|
||||
$buff = '<?php return ' . var_export(self::$_ssl_actions, true) . ';';
|
||||
Rhymix\Framework\Storage::write(self::$_ssl_actions_cache_file, $buff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register if actions are to be encrypted by SSL. Those actions are sent to https in common/js/xml_handler.js
|
||||
*
|
||||
* @param string $action act name
|
||||
* @deprecated
|
||||
* @param array $action_array
|
||||
* @return void
|
||||
*/
|
||||
public static function addSSLActions($action_array)
|
||||
{
|
||||
$changed = false;
|
||||
foreach($action_array as $action)
|
||||
{
|
||||
if(!isset(self::$_ssl_actions[$action]))
|
||||
{
|
||||
self::$_ssl_actions[$action] = 1;
|
||||
$changed = true;
|
||||
}
|
||||
}
|
||||
if(!$changed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$buff = '<?php return ' . var_export(self::$_ssl_actions, true) . ';';
|
||||
Rhymix\Framework\Storage::write(self::$_ssl_actions_cache_file, $buff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete if action is registerd to be encrypted by SSL.
|
||||
*
|
||||
* @deprecated
|
||||
* @param string $action act name
|
||||
* @return void
|
||||
*/
|
||||
public static function subtractSSLAction($action)
|
||||
{
|
||||
if(!isset(self::$_ssl_actions[$action]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unset(self::$_ssl_actions[$action]);
|
||||
$buff = '<?php return ' . var_export(self::$_ssl_actions, true) . ';';
|
||||
Rhymix\Framework\Storage::write(self::$_ssl_actions_cache_file, $buff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SSL Action
|
||||
*
|
||||
* @deprecated
|
||||
* @return string acts in array
|
||||
*/
|
||||
public static function getSSLActions()
|
||||
{
|
||||
if(self::getSslStatus() == 'optional')
|
||||
{
|
||||
return self::$_ssl_actions;
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check SSL action are existed
|
||||
*
|
||||
* @deprecated
|
||||
* @param string $action act name
|
||||
* @return bool If SSL exists, return TRUE.
|
||||
* @return bool
|
||||
*/
|
||||
public static function isExistsSSLAction($action)
|
||||
{
|
||||
return isset(self::$_ssl_actions[$action]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2609,11 +2478,11 @@ class Context
|
|||
/**
|
||||
* Check whether it is allowed to use rewrite mod
|
||||
*
|
||||
* @return bool True if it is allowed to use rewrite mod, otherwise FALSE
|
||||
* @return int The currently configured rewrite level
|
||||
*/
|
||||
public static function isAllowRewrite()
|
||||
{
|
||||
return self::$_instance->allow_rewrite;
|
||||
return Rhymix\Framework\Router::getRewriteLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2745,7 +2614,7 @@ class Context
|
|||
*/
|
||||
public static function addMetaTag($name, $content, $is_http_equiv = false)
|
||||
{
|
||||
getController('module')->replaceDefinedLangCode($content);
|
||||
ModuleController::getInstance()->replaceDefinedLangCode($content);
|
||||
self::$_instance->meta_tags[$name] = array('is_http_equiv' => (bool)$is_http_equiv, 'content' => $content);
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,749 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts
|
||||
* @version 0.1
|
||||
*/
|
||||
class Query extends BaseObject
|
||||
{
|
||||
|
||||
/**
|
||||
* Query id, defined in query xml file
|
||||
* @var string
|
||||
*/
|
||||
var $queryID;
|
||||
|
||||
/**
|
||||
* DML type, ex) INSERT, DELETE, UPDATE, SELECT
|
||||
* @var string
|
||||
*/
|
||||
var $action;
|
||||
|
||||
/**
|
||||
* priority level ex)LOW_PRIORITY, HIGHT_PRIORITY
|
||||
* @var string
|
||||
*/
|
||||
var $priority;
|
||||
|
||||
/**
|
||||
* column list
|
||||
* @var string|array
|
||||
*/
|
||||
var $columns;
|
||||
|
||||
/**
|
||||
* table list
|
||||
* @var string|array
|
||||
*/
|
||||
var $tables;
|
||||
|
||||
/**
|
||||
* condition list
|
||||
* @var string|array
|
||||
*/
|
||||
var $conditions;
|
||||
|
||||
/**
|
||||
* group list
|
||||
* @var string|array
|
||||
*/
|
||||
var $groups;
|
||||
|
||||
/**
|
||||
* having list
|
||||
* @var string|array
|
||||
*/
|
||||
var $having;
|
||||
|
||||
/**
|
||||
* order list
|
||||
* @var array
|
||||
*/
|
||||
var $orderby;
|
||||
|
||||
/**
|
||||
* limit count
|
||||
* @var int
|
||||
*/
|
||||
var $limit;
|
||||
|
||||
/**
|
||||
* argument list
|
||||
* @var array
|
||||
*/
|
||||
var $arguments = NULL;
|
||||
|
||||
/**
|
||||
* column list
|
||||
* @var array
|
||||
*/
|
||||
var $columnList = NULL;
|
||||
|
||||
/**
|
||||
* order by text
|
||||
* @var string
|
||||
*/
|
||||
var $_orderByString;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $queryID
|
||||
* @param string $action
|
||||
* @param string|array $columns
|
||||
* @param string|array $tables
|
||||
* @param string|array $conditions
|
||||
* @param string|array $groups
|
||||
* @param string|array $orderby
|
||||
* @param int $limit
|
||||
* @param string $priority
|
||||
* @return void
|
||||
*/
|
||||
function __construct($queryID = NULL
|
||||
, $action = NULL
|
||||
, $columns = NULL
|
||||
, $tables = NULL
|
||||
, $conditions = NULL
|
||||
, $groups = NULL
|
||||
, $orderby = NULL
|
||||
, $limit = NULL
|
||||
, $priority = NULL)
|
||||
{
|
||||
$this->queryID = $queryID;
|
||||
$this->action = $action;
|
||||
$this->priority = $priority;
|
||||
|
||||
if(!isset($tables))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->columns = $this->setColumns($columns);
|
||||
$this->tables = $this->setTables($tables);
|
||||
$this->conditions = $this->setConditions($conditions);
|
||||
$this->groups = $this->setGroups($groups);
|
||||
$this->orderby = $this->setOrder($orderby);
|
||||
$this->limit = $this->setLimit($limit);
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function setQueryId($queryID)
|
||||
{
|
||||
$this->queryID = $queryID;
|
||||
}
|
||||
|
||||
function setAction($action)
|
||||
{
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
function setPriority($priority)
|
||||
{
|
||||
$this->priority = $priority;
|
||||
}
|
||||
|
||||
function setColumnList($columnList)
|
||||
{
|
||||
if (!is_array($columnList) || count($columnList) === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$selectColumns = array();
|
||||
$dbParser = DB::getParser();
|
||||
|
||||
foreach($columnList as $columnName)
|
||||
{
|
||||
$columnName = $dbParser->escapeColumnExpression($columnName);
|
||||
$selectColumns[] = new SelectExpression($columnName);
|
||||
}
|
||||
|
||||
$this->columns = $selectColumns;
|
||||
$this->columnList = $columnList;
|
||||
}
|
||||
|
||||
function setColumns($columns)
|
||||
{
|
||||
if(!isset($columns) || count($columns) === 0)
|
||||
{
|
||||
$this->columns = array(new StarExpression());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is_array($columns))
|
||||
{
|
||||
$columns = array($columns);
|
||||
}
|
||||
|
||||
$this->columns = $columns;
|
||||
}
|
||||
|
||||
function setTables($tables)
|
||||
{
|
||||
if(!isset($tables) || count($tables) === 0)
|
||||
{
|
||||
$this->setError(TRUE);
|
||||
$this->setMessage("You must provide at least one table for the query.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is_array($tables))
|
||||
{
|
||||
$tables = array($tables);
|
||||
}
|
||||
|
||||
$this->tables = $tables;
|
||||
}
|
||||
|
||||
function setSubquery($subquery)
|
||||
{
|
||||
$this->subquery = $subquery;
|
||||
}
|
||||
|
||||
function setConditions($conditions)
|
||||
{
|
||||
$this->conditions = array();
|
||||
if(!isset($conditions) || count($conditions) === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!is_array($conditions))
|
||||
{
|
||||
$conditions = array($conditions);
|
||||
}
|
||||
|
||||
foreach($conditions as $conditionGroup)
|
||||
{
|
||||
if($conditionGroup->show())
|
||||
{
|
||||
$this->conditions[] = $conditionGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setGroups($groups)
|
||||
{
|
||||
if(!isset($groups) || count($groups) === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!is_array($groups))
|
||||
{
|
||||
$groups = array($groups);
|
||||
}
|
||||
|
||||
$this->groups = $groups;
|
||||
}
|
||||
|
||||
function setHaving($conditions)
|
||||
{
|
||||
$this->having = array();
|
||||
if(!isset($conditions) || count($conditions) === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!is_array($conditions))
|
||||
{
|
||||
$conditions = array($conditions);
|
||||
}
|
||||
|
||||
foreach($conditions as $conditionGroup)
|
||||
{
|
||||
if($conditionGroup->show())
|
||||
{
|
||||
$this->having[] = $conditionGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setOrder($order)
|
||||
{
|
||||
if(!isset($order) || count($order) === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!is_array($order))
|
||||
{
|
||||
$order = array($order);
|
||||
}
|
||||
|
||||
$this->orderby = $order;
|
||||
}
|
||||
|
||||
function getOrder()
|
||||
{
|
||||
return $this->orderby;
|
||||
}
|
||||
|
||||
function setLimit($limit = NULL)
|
||||
{
|
||||
if(!isset($limit))
|
||||
{
|
||||
return;
|
||||
}
|
||||
$this->limit = $limit;
|
||||
}
|
||||
|
||||
// START Fluent interface
|
||||
/**
|
||||
* seleect set
|
||||
* @param string|array $columns
|
||||
* @return Query return Query instance
|
||||
*/
|
||||
function select($columns = NULL)
|
||||
{
|
||||
$this->action = 'select';
|
||||
$this->setColumns($columns);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* from set
|
||||
* @param string|array $tables
|
||||
* @return Query return Query instance
|
||||
*/
|
||||
function from($tables)
|
||||
{
|
||||
$this->setTables($tables);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* where set
|
||||
* @param string|array $conditions
|
||||
* @return Query return Query instance
|
||||
*/
|
||||
function where($conditions)
|
||||
{
|
||||
$this->setConditions($conditions);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* groupBy set
|
||||
* @param string|array $groups
|
||||
* @return Query return Query instance
|
||||
*/
|
||||
function groupBy($groups)
|
||||
{
|
||||
$this->setGroups($groups);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* orderBy set
|
||||
* @param string|array $order
|
||||
* @return Query return Query instance
|
||||
*/
|
||||
function orderBy($order)
|
||||
{
|
||||
$this->setOrder($order);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* limit set
|
||||
* @param int $limit
|
||||
* @return Query return Query instance
|
||||
*/
|
||||
function limit($limit)
|
||||
{
|
||||
$this->setLimit($limit);
|
||||
return $this;
|
||||
}
|
||||
|
||||
// END Fluent interface
|
||||
|
||||
function getAction()
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
function getPriority()
|
||||
{
|
||||
return $this->priority ? 'LOW_PRIORITY' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current query uses the click count attribute
|
||||
* For CUBRID, this statement uses the click count feature.
|
||||
* For the other databases, using this attribute causes a query
|
||||
* to produce both a select and an update
|
||||
*/
|
||||
function usesClickCount()
|
||||
{
|
||||
return count($this->getClickCountColumns()) > 0;
|
||||
}
|
||||
|
||||
function getClickCountColumns()
|
||||
{
|
||||
$click_count_columns = array();
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
if($column->show() && is_a($column, 'ClickCountExpression'))
|
||||
{
|
||||
$click_count_columns[] = $column;
|
||||
}
|
||||
}
|
||||
return $click_count_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return select sql
|
||||
* @param boolean $with_values
|
||||
* @return string
|
||||
*/
|
||||
function getSelectString($with_values = TRUE)
|
||||
{
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
if($column->show())
|
||||
{
|
||||
if($column->isSubquery())
|
||||
{
|
||||
$select[] = $column->toString($with_values) . ' as ' . $column->getAlias();
|
||||
}
|
||||
else
|
||||
{
|
||||
$select[] = $column->getExpression($with_values);
|
||||
}
|
||||
}
|
||||
}
|
||||
return trim(implode($select, ', '));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return update sql
|
||||
* @param boolean $with_values
|
||||
* @return string
|
||||
*/
|
||||
function getUpdateString($with_values = TRUE)
|
||||
{
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
if($column->show())
|
||||
{
|
||||
$update[] = $column->getExpression($with_values);
|
||||
}
|
||||
}
|
||||
|
||||
if(!$update) return;
|
||||
return trim(implode($update, ', '));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return insert sql
|
||||
* @param boolean $with_values
|
||||
* @return string
|
||||
*/
|
||||
function getInsertString($with_values = TRUE)
|
||||
{
|
||||
$columnsList = '';
|
||||
// means we have insert-select
|
||||
if($this->subquery)
|
||||
{
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
$columnsList .= $column->getColumnName() . ', ';
|
||||
}
|
||||
$columnsList = substr($columnsList, 0, -2);
|
||||
$selectStatement = $this->subquery->toString($with_values);
|
||||
$selectStatement = substr($selectStatement, 1, -1);
|
||||
return "($columnsList) \n $selectStatement";
|
||||
}
|
||||
|
||||
$valuesList = '';
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
if($column->show())
|
||||
{
|
||||
$columnsList .= $column->getColumnName() . ', ';
|
||||
$valuesList .= $column->getValue($with_values) . ', ';
|
||||
}
|
||||
}
|
||||
$columnsList = substr($columnsList, 0, -2);
|
||||
$valuesList = substr($valuesList, 0, -2);
|
||||
|
||||
return "($columnsList) \n VALUES ($valuesList)";
|
||||
}
|
||||
|
||||
function getTables()
|
||||
{
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* from table_a
|
||||
* from table_a inner join table_b on x=y
|
||||
* from (select * from table a) as x
|
||||
* from (select * from table t) as x inner join table y on y.x
|
||||
* @param boolean $with_values
|
||||
* @return string
|
||||
*/
|
||||
function getFromString($with_values = TRUE)
|
||||
{
|
||||
$from = '';
|
||||
$simple_table_count = 0;
|
||||
foreach($this->tables as $table)
|
||||
{
|
||||
if($table->isJoinTable() || !$simple_table_count)
|
||||
{
|
||||
$from .= $table->toString($with_values) . ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$from .= ', ' . $table->toString($with_values) . ' ';
|
||||
}
|
||||
|
||||
if(is_a($table, 'Subquery'))
|
||||
{
|
||||
$from .= $table->getAlias() ? ' as ' . $table->getAlias() . ' ' : ' ';
|
||||
}
|
||||
|
||||
$simple_table_count++;
|
||||
}
|
||||
if(trim($from) == '')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return where sql
|
||||
* @param boolean $with_values
|
||||
* @param boolean $with_optimization
|
||||
* @return string
|
||||
*/
|
||||
function getWhereString($with_values = TRUE, $with_optimization = TRUE)
|
||||
{
|
||||
$where = '';
|
||||
$condition_count = 0;
|
||||
|
||||
foreach($this->conditions as $conditionGroup)
|
||||
{
|
||||
if($condition_count === 0)
|
||||
{
|
||||
$conditionGroup->setPipe("");
|
||||
}
|
||||
$condition_string = $conditionGroup->toString($with_values);
|
||||
$where .= $condition_string;
|
||||
$condition_count++;
|
||||
}
|
||||
|
||||
if($with_optimization &&
|
||||
(strstr($this->getOrderByString(), 'list_order') || strstr($this->getOrderByString(), 'update_order')))
|
||||
{
|
||||
|
||||
if($condition_count !== 0)
|
||||
{
|
||||
$where = '(' . $where . ') ';
|
||||
}
|
||||
|
||||
foreach($this->orderby as $order)
|
||||
{
|
||||
$colName = $order->getColumnName();
|
||||
if(strstr($colName, 'list_order') || strstr($colName, 'update_order'))
|
||||
{
|
||||
$opt_condition = new ConditionWithoutArgument($colName, 2100000000, 'less', 'and');
|
||||
if($condition_count === 0)
|
||||
{
|
||||
$opt_condition->setPipe("");
|
||||
}
|
||||
$where .= $opt_condition->toString($with_values) . ' ';
|
||||
$condition_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return trim($where);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return groupby sql
|
||||
* @return string
|
||||
*/
|
||||
function getGroupByString()
|
||||
{
|
||||
$groupBy = '';
|
||||
if($this->groups)
|
||||
{
|
||||
if($this->groups[0] !== "")
|
||||
{
|
||||
$groupBy = implode(', ', $this->groups);
|
||||
}
|
||||
}
|
||||
return $groupBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return having sql
|
||||
* @param boolean $with_values
|
||||
* @return string
|
||||
*/
|
||||
function getHavingString($with_values = TRUE)
|
||||
{
|
||||
if(!is_array($this->having))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$having = '';
|
||||
$condition_count = 0;
|
||||
|
||||
foreach($this->having as $conditionGroup)
|
||||
{
|
||||
if($condition_count === 0)
|
||||
{
|
||||
$conditionGroup->setPipe("");
|
||||
}
|
||||
$condition_string = $conditionGroup->toString($with_values);
|
||||
$having .= $condition_string;
|
||||
$condition_count++;
|
||||
}
|
||||
|
||||
return trim($having);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return orderby sql
|
||||
* @return string
|
||||
*/
|
||||
function getOrderByString()
|
||||
{
|
||||
if(!$this->_orderByString)
|
||||
{
|
||||
if(countobj($this->orderby) === 0)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
$orderBy = '';
|
||||
foreach($this->orderby as $order)
|
||||
{
|
||||
$orderBy .= $order->toString() . ', ';
|
||||
}
|
||||
$orderBy = substr($orderBy, 0, -2);
|
||||
$this->_orderByString = $orderBy;
|
||||
}
|
||||
return $this->_orderByString;
|
||||
}
|
||||
|
||||
function getLimit()
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return limit sql
|
||||
* @return string
|
||||
*/
|
||||
function getLimitString()
|
||||
{
|
||||
$limit = '';
|
||||
if(countobj($this->limit) > 0)
|
||||
{
|
||||
$limit = '';
|
||||
$limit .= $this->limit->toString();
|
||||
}
|
||||
return $limit;
|
||||
}
|
||||
|
||||
function getFirstTableName()
|
||||
{
|
||||
return $this->tables[0]->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return argument list
|
||||
* @return array
|
||||
*/
|
||||
function getArguments()
|
||||
{
|
||||
if(!isset($this->arguments))
|
||||
{
|
||||
$this->arguments = array();
|
||||
|
||||
// Join table arguments
|
||||
if(countobj($this->tables) > 0)
|
||||
{
|
||||
foreach($this->tables as $table)
|
||||
{
|
||||
if($table->isJoinTable() || is_a($table, 'Subquery'))
|
||||
{
|
||||
$args = $table->getArguments();
|
||||
if($args)
|
||||
{
|
||||
$this->arguments = array_merge($this->arguments, $args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Column arguments
|
||||
// The if is for delete statements, all others must have columns
|
||||
if(countobj($this->columns) > 0)
|
||||
{
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
if($column->show())
|
||||
{
|
||||
$args = $column->getArguments();
|
||||
if($args)
|
||||
{
|
||||
$this->arguments = array_merge($this->arguments, $args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Condition arguments
|
||||
if(countobj($this->conditions) > 0)
|
||||
{
|
||||
foreach($this->conditions as $conditionGroup)
|
||||
{
|
||||
$args = $conditionGroup->getArguments();
|
||||
if(countobj($args) > 0)
|
||||
{
|
||||
$this->arguments = array_merge($this->arguments, $args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Having arguments
|
||||
if(countobj($this->having) > 0)
|
||||
{
|
||||
foreach($this->having as $conditionGroup)
|
||||
{
|
||||
$args = $conditionGroup->getArguments();
|
||||
if(countobj($args) > 0)
|
||||
{
|
||||
$this->arguments = array_merge($this->arguments, $args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation arguments
|
||||
if(countobj($this->orderby) > 0)
|
||||
{
|
||||
foreach($this->orderby as $order)
|
||||
{
|
||||
$args = $order->getArguments();
|
||||
if(countobj($args) > 0)
|
||||
{
|
||||
$this->arguments = array_merge($this->arguments, $args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file Query.class.php */
|
||||
/* Location: ./classes/db/queryparts/Query.class.php */
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts
|
||||
* @version 0.1
|
||||
*/
|
||||
class Subquery extends Query
|
||||
{
|
||||
|
||||
/**
|
||||
* table alias
|
||||
* @var string
|
||||
*/
|
||||
var $alias;
|
||||
|
||||
/**
|
||||
* join type
|
||||
* @var string
|
||||
*/
|
||||
var $join_type;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $alias
|
||||
* @param string|array $columns
|
||||
* @param string|array $tables
|
||||
* @param string|array $conditions
|
||||
* @param string|array $groups
|
||||
* @param string|array $orderby
|
||||
* @param int $limit
|
||||
* @param string $join_type
|
||||
* @return void
|
||||
*/
|
||||
function __construct($alias, $columns, $tables, $conditions, $groups, $orderby, $limit, $join_type = null)
|
||||
{
|
||||
$this->alias = $alias;
|
||||
|
||||
$this->queryID = null;
|
||||
$this->action = "select";
|
||||
|
||||
$this->columns = $columns;
|
||||
$this->tables = $tables;
|
||||
$this->conditions = $conditions;
|
||||
$this->groups = $groups;
|
||||
$this->orderby = $orderby;
|
||||
$this->limit = $limit;
|
||||
$this->join_type = $join_type;
|
||||
}
|
||||
|
||||
function getAlias()
|
||||
{
|
||||
return $this->alias;
|
||||
}
|
||||
|
||||
function isJoinTable()
|
||||
{
|
||||
if($this->join_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function toString($with_values = true)
|
||||
{
|
||||
$oDB = &DB::getInstance();
|
||||
|
||||
return '(' . $oDB->getSelectSql($this, $with_values) . ')';
|
||||
}
|
||||
|
||||
function isSubquery()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file Subquery.class.php */
|
||||
/* Location: ./classes/db/queryparts/Subquery.class.php */
|
||||
|
|
@ -1,277 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/condition
|
||||
* @version 0.1
|
||||
*/
|
||||
class Condition
|
||||
{
|
||||
|
||||
/**
|
||||
* column name
|
||||
* @var string
|
||||
*/
|
||||
var $column_name;
|
||||
var $argument;
|
||||
|
||||
/**
|
||||
* operation can use 'equal', 'more', 'excess', 'less', 'below', 'like_tail', 'like_prefix', 'like', 'notlike_tail',
|
||||
* 'notlike_prefix', 'notlike', 'in', 'notin', 'not_in', 'and', 'or', 'xor', 'not', 'notequal', 'between'
|
||||
* 'null', 'notnull'
|
||||
* @var string
|
||||
*/
|
||||
var $operation;
|
||||
|
||||
/**
|
||||
* pipe can use 'and', 'or'...
|
||||
* @var string
|
||||
*/
|
||||
var $pipe;
|
||||
var $_value;
|
||||
var $_show;
|
||||
var $_value_to_string;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param mixed $argument
|
||||
* @param string $operation
|
||||
* @param string $pipe
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $argument, $operation, $pipe = 'and')
|
||||
{
|
||||
$this->column_name = $column_name;
|
||||
$this->argument = $argument;
|
||||
$this->operation = $operation;
|
||||
$this->pipe = $pipe;
|
||||
}
|
||||
|
||||
function getArgument()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* value to string
|
||||
* @param boolean $withValue
|
||||
* @return string
|
||||
*/
|
||||
function toString($withValue = true)
|
||||
{
|
||||
if(!isset($this->_value_to_string))
|
||||
{
|
||||
if(!$this->show())
|
||||
{
|
||||
$this->_value_to_string = '';
|
||||
}
|
||||
else if($withValue)
|
||||
{
|
||||
$this->_value_to_string = $this->toStringWithValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_value_to_string = $this->toStringWithoutValue();
|
||||
}
|
||||
}
|
||||
return $this->_value_to_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* change string without value
|
||||
* @return string
|
||||
*/
|
||||
function toStringWithoutValue()
|
||||
{
|
||||
return strtoupper($this->pipe) . ' ' . $this->getConditionPart($this->_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* change string with value
|
||||
* @return string
|
||||
*/
|
||||
function toStringWithValue()
|
||||
{
|
||||
return strtoupper($this->pipe) . ' ' . $this->getConditionPart($this->_value);
|
||||
}
|
||||
|
||||
function setPipe($pipe)
|
||||
{
|
||||
$this->pipe = $pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
function show()
|
||||
{
|
||||
if(!isset($this->_show))
|
||||
{
|
||||
if(is_array($this->_value) && count($this->_value) === 1 && $this->_value[0] === '')
|
||||
{
|
||||
$this->_show = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_show = true;
|
||||
switch($this->operation)
|
||||
{
|
||||
case 'equal' :
|
||||
case 'more' :
|
||||
case 'excess' :
|
||||
case 'less' :
|
||||
case 'below' :
|
||||
case 'gte' :
|
||||
case 'gt' :
|
||||
case 'lte' :
|
||||
case 'lt' :
|
||||
case 'like_tail' :
|
||||
case 'like_prefix' :
|
||||
case 'like' :
|
||||
case 'notlike_tail' :
|
||||
case 'notlike_prefix' :
|
||||
case 'notlike' :
|
||||
case 'not_like' :
|
||||
case 'regexp' :
|
||||
case 'notregexp' :
|
||||
case 'not_regexp' :
|
||||
case 'in' :
|
||||
case 'notin' :
|
||||
case 'not_in' :
|
||||
case 'and':
|
||||
case 'or':
|
||||
case 'xor':
|
||||
case 'not':
|
||||
case 'notequal' :
|
||||
case 'not_equal' :
|
||||
// if variable is not set or is not string or number, return
|
||||
if(!isset($this->_value))
|
||||
{
|
||||
$this->_show = false;
|
||||
break;
|
||||
}
|
||||
if($this->_value === '')
|
||||
{
|
||||
$this->_show = false;
|
||||
break;
|
||||
}
|
||||
$tmpArray = array('string' => 1, 'integer' => 1);
|
||||
if(!isset($tmpArray[gettype($this->_value)]))
|
||||
{
|
||||
$this->_show = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'between' :
|
||||
if(!is_array($this->_value))
|
||||
{
|
||||
$this->_show = false;
|
||||
break;
|
||||
}
|
||||
if(count($this->_value) != 2)
|
||||
{
|
||||
$this->_show = false;
|
||||
break;
|
||||
}
|
||||
case 'null':
|
||||
case 'notnull':
|
||||
case 'not_null':
|
||||
break;
|
||||
default:
|
||||
// If operation is not one of the above, means the condition is invalid
|
||||
$this->_show = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->_show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return condition string
|
||||
* @param int|string|array $value
|
||||
* @return string
|
||||
*/
|
||||
function getConditionPart($value)
|
||||
{
|
||||
$name = $this->column_name;
|
||||
$operation = $this->operation;
|
||||
|
||||
switch($operation)
|
||||
{
|
||||
case 'equal' :
|
||||
return $name . ' = ' . $value;
|
||||
break;
|
||||
case 'more' :
|
||||
case 'gte' :
|
||||
return $name . ' >= ' . $value;
|
||||
break;
|
||||
case 'excess' :
|
||||
case 'gt' :
|
||||
return $name . ' > ' . $value;
|
||||
break;
|
||||
case 'less' :
|
||||
case 'lte' :
|
||||
return $name . ' <= ' . $value;
|
||||
break;
|
||||
case 'below' :
|
||||
case 'lt' :
|
||||
return $name . ' < ' . $value;
|
||||
break;
|
||||
case 'like_tail' :
|
||||
case 'like_prefix' :
|
||||
case 'like' :
|
||||
return $name . ' LIKE ' . $value;
|
||||
case 'notlike_tail' :
|
||||
case 'notlike_prefix' :
|
||||
case 'notlike' :
|
||||
case 'not_like' :
|
||||
return $name . ' NOT LIKE ' . $value;
|
||||
break;
|
||||
case 'regexp' :
|
||||
return $name . ' REGEXP ' . $value;
|
||||
break;
|
||||
case 'notregexp' :
|
||||
case 'not_regexp' :
|
||||
return $name . ' NOT REGEXP ' . $value;
|
||||
break;
|
||||
case 'in' :
|
||||
return $name . ' IN ' . $value;
|
||||
break;
|
||||
case 'notin' :
|
||||
case 'not_in' :
|
||||
return $name . ' NOT IN ' . $value;
|
||||
break;
|
||||
case 'notequal' :
|
||||
case 'not_equal' :
|
||||
return $name . ' <> ' . $value;
|
||||
break;
|
||||
case 'notnull' :
|
||||
case 'not_null' :
|
||||
return $name . ' IS NOT NULL ';
|
||||
break;
|
||||
case 'null' :
|
||||
return $name . ' IS NULL ';
|
||||
break;
|
||||
case 'and' :
|
||||
return $name . ' & ' . $value;
|
||||
break;
|
||||
case 'or' :
|
||||
return $name . ' | ' . $value;
|
||||
break;
|
||||
case 'xor' :
|
||||
return $name . ' ^ ' . $value;
|
||||
break;
|
||||
case 'not' :
|
||||
return $name . ' ~ ' . $value;
|
||||
break;
|
||||
case 'between' :
|
||||
return $name . ' BETWEEN ' . $value[0] . ' AND ' . $value[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file Condition.class.php */
|
||||
/* Location: ./classes/db/queryparts/condition/Condition.class.php */
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/condition
|
||||
* @version 0.1
|
||||
*/
|
||||
class ConditionGroup
|
||||
{
|
||||
|
||||
/**
|
||||
* condition list
|
||||
* @var array
|
||||
*/
|
||||
var $conditions;
|
||||
|
||||
/**
|
||||
* pipe can use 'and', 'or'...
|
||||
* @var string
|
||||
*/
|
||||
var $pipe;
|
||||
var $_group;
|
||||
var $_show;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param array $conditions
|
||||
* @param string $pipe
|
||||
* @return void
|
||||
*/
|
||||
function __construct($conditions, $pipe = 'and')
|
||||
{
|
||||
$this->conditions = array();
|
||||
foreach($conditions as $condition)
|
||||
{
|
||||
if($condition->show())
|
||||
{
|
||||
$this->conditions[] = $condition;
|
||||
}
|
||||
}
|
||||
if(count($this->conditions) === 0)
|
||||
{
|
||||
$this->_show = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_show = true;
|
||||
}
|
||||
|
||||
$this->pipe = $pipe;
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
return $this->_show;
|
||||
}
|
||||
|
||||
function setPipe($pipe)
|
||||
{
|
||||
if($this->pipe !== $pipe)
|
||||
{
|
||||
$this->_group = null;
|
||||
}
|
||||
$this->pipe = $pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* value to string
|
||||
* @param boolean $with_value
|
||||
* @return string
|
||||
*/
|
||||
function toString($with_value = true)
|
||||
{
|
||||
if(!isset($this->_group))
|
||||
{
|
||||
$cond_indx = 0;
|
||||
$group = '';
|
||||
|
||||
foreach($this->conditions as $condition)
|
||||
{
|
||||
if($cond_indx === 0)
|
||||
{
|
||||
$condition->setPipe("");
|
||||
}
|
||||
$group .= $condition->toString($with_value) . ' ';
|
||||
$cond_indx++;
|
||||
}
|
||||
|
||||
if($this->pipe !== "" && trim($group) !== '')
|
||||
{
|
||||
$group = strtoupper($this->pipe) . ' (' . $group . ')';
|
||||
}
|
||||
|
||||
$this->_group = $group;
|
||||
}
|
||||
return $this->_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* return argument list
|
||||
* @return array
|
||||
*/
|
||||
function getArguments()
|
||||
{
|
||||
$args = array();
|
||||
foreach($this->conditions as $condition)
|
||||
{
|
||||
if($condition instanceof ConditionGroup)
|
||||
{
|
||||
foreach($condition->getArguments() as $arg)
|
||||
{
|
||||
if($arg)
|
||||
{
|
||||
$args[] = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$arg = $condition->getArgument();
|
||||
if($arg)
|
||||
{
|
||||
$args[] = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ConditionGroup.class.php */
|
||||
/* Location: ./classes/db/queryparts/condition/ConditionGroup.class.php */
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/condition
|
||||
* @version 0.1
|
||||
*/
|
||||
class ConditionSubquery extends Condition
|
||||
{
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param mixed $argument
|
||||
* @param string $operation
|
||||
* @param string $pipe
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $argument, $operation, $pipe = "")
|
||||
{
|
||||
parent::__construct($column_name, $argument, $operation, $pipe);
|
||||
$this->_value = $this->argument->toString();
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ConditionSubquery.class.php */
|
||||
/* Location: ./classes/db/queryparts/condition/ConditionSubquery.class.php */
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/condition
|
||||
* @version 0.1
|
||||
*/
|
||||
class ConditionWithArgument extends Condition
|
||||
{
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param mixed $argument
|
||||
* @param string $operation
|
||||
* @param string $pipe
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $argument, $operation, $pipe = "")
|
||||
{
|
||||
if($argument === null)
|
||||
{
|
||||
$this->_show = false;
|
||||
return;
|
||||
}
|
||||
parent::__construct($column_name, $argument, $operation, $pipe);
|
||||
$this->_value = $argument->getValue();
|
||||
}
|
||||
|
||||
function getArgument()
|
||||
{
|
||||
if(!$this->show())
|
||||
return;
|
||||
return $this->argument;
|
||||
}
|
||||
|
||||
/**
|
||||
* change string without value
|
||||
* @return string
|
||||
*/
|
||||
function toStringWithoutValue()
|
||||
{
|
||||
$value = $this->argument->getUnescapedValue();
|
||||
|
||||
if(is_array($value))
|
||||
{
|
||||
$q = '';
|
||||
foreach($value as $v)
|
||||
{
|
||||
$q .= '?,';
|
||||
}
|
||||
if($q !== '')
|
||||
{
|
||||
$q = substr($q, 0, -1);
|
||||
}
|
||||
$q = '(' . $q . ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prepared statements: column names should not be sent as query arguments, but instead concatenated to query string
|
||||
if($this->argument->isColumnName())
|
||||
{
|
||||
$q = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$q = '?';
|
||||
}
|
||||
}
|
||||
return strtoupper($this->pipe) . ' ' . $this->getConditionPart($q);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
function show()
|
||||
{
|
||||
if(!isset($this->_show))
|
||||
{
|
||||
if(!$this->argument->isValid())
|
||||
{
|
||||
$this->_show = false;
|
||||
}
|
||||
if($this->_value === '\'\'')
|
||||
{
|
||||
$this->_show = false;
|
||||
}
|
||||
if(!isset($this->_show))
|
||||
{
|
||||
return parent::show();
|
||||
}
|
||||
}
|
||||
return $this->_show;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ConditionWithArgument.class.php */
|
||||
/* Location: ./classes/db/queryparts/condition/ConditionWithArgument.class.php */
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/condition
|
||||
* @version 0.1
|
||||
*/
|
||||
class ConditionWithoutArgument extends Condition
|
||||
{
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param mixed $argument
|
||||
* @param string $operation
|
||||
* @param string $pipe
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $argument, $operation, $pipe = "")
|
||||
{
|
||||
parent::__construct($column_name, $argument, $operation, $pipe);
|
||||
$tmpArray = array('in' => 1, 'notin' => 1, 'not_in' => 1);
|
||||
if(isset($tmpArray[$operation]))
|
||||
{
|
||||
if(is_array($argument))
|
||||
{
|
||||
$argument = implode($argument, ',');
|
||||
}
|
||||
$this->_value = '(' . $argument . ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_value = $argument;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ConditionWithoutArgument.class.php */
|
||||
/* Location: ./classes/db/queryparts/condition/ConditionWithoutArgument.class.php */
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* ClickCountExpression
|
||||
* @author Arnia Software
|
||||
* @package /classes/db/queryparts/expression
|
||||
* @version 0.1
|
||||
*/
|
||||
class ClickCountExpression extends SelectExpression
|
||||
{
|
||||
|
||||
/**
|
||||
* click count
|
||||
* @var bool
|
||||
*/
|
||||
var $click_count;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param string $alias
|
||||
* @param bool $click_count
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $alias = NULL, $click_count = false)
|
||||
{
|
||||
parent::__construct($column_name, $alias);
|
||||
|
||||
if(!is_bool($click_count))
|
||||
{
|
||||
// error_log("Click_count value for $column_name was not boolean", 0);
|
||||
$this->click_count = false;
|
||||
}
|
||||
$this->click_count = $click_count;
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
return $this->click_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return column expression, ex) column = column + 1
|
||||
* @return string
|
||||
*/
|
||||
function getExpression()
|
||||
{
|
||||
$db_type = Context::getDBType();
|
||||
if($db_type == 'cubrid')
|
||||
{
|
||||
return "INCR($this->column_name)";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "$this->column_name";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ClickCountExpression.class.php */
|
||||
/* Location: ./classes/db/queryparts/expression/ClickCountExpression.class.php */
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* DeleteExpression
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/db/queryparts/expression
|
||||
* @version 0.1
|
||||
* @todo Fix this class
|
||||
*/
|
||||
class DeleteExpression extends Expression
|
||||
{
|
||||
|
||||
/**
|
||||
* column value
|
||||
* @var mixed
|
||||
*/
|
||||
var $value;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $value)
|
||||
{
|
||||
parent::__construct($column_name);
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return column expression, ex) column = value
|
||||
* @return string
|
||||
*/
|
||||
function getExpression()
|
||||
{
|
||||
return "$this->column_name = $this->value";
|
||||
}
|
||||
|
||||
function getValue()
|
||||
{
|
||||
// TODO Escape value according to column type instead of variable type
|
||||
if(!is_numeric($this->value))
|
||||
{
|
||||
return "'" . $this->value . "'";
|
||||
}
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
if(!$this->value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file DeleteExpression.class.php */
|
||||
/* Location: ./classes/db/queryparts/expression/DeleteExpression.class.php */
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Expression
|
||||
* Represents an expression used in select/update/insert/delete statements
|
||||
*
|
||||
* Examples (expressions are inside double square brackets):
|
||||
* select [[columnA]], [[columnB as aliasB]] from tableA
|
||||
* update tableA set [[columnA = valueA]] where columnB = something
|
||||
*
|
||||
* @author Corina
|
||||
* @package /classes/db/queryparts/expression
|
||||
* @version 0.1
|
||||
*/
|
||||
class Expression
|
||||
{
|
||||
|
||||
/**
|
||||
* column name
|
||||
* @var string
|
||||
*/
|
||||
var $column_name;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name)
|
||||
{
|
||||
$this->column_name = $column_name;
|
||||
}
|
||||
|
||||
function getColumnName()
|
||||
{
|
||||
return $this->column_name;
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return column expression, ex) column as alias
|
||||
* @return string
|
||||
*/
|
||||
function getExpression()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file Expression.class.php */
|
||||
/* Location: ./classes/db/queryparts/expression/Expression.class.php */
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* InsertExpression
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/db/queryparts/expression
|
||||
* @version 0.1
|
||||
*/
|
||||
class InsertExpression extends Expression
|
||||
{
|
||||
|
||||
/**
|
||||
* argument
|
||||
* @var object
|
||||
*/
|
||||
var $argument;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param object $argument
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $argument)
|
||||
{
|
||||
parent::__construct($column_name);
|
||||
$this->argument = $argument;
|
||||
}
|
||||
|
||||
function getValue($with_values = true)
|
||||
{
|
||||
if($with_values)
|
||||
{
|
||||
return $this->argument->getValue();
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
if(!$this->argument)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$value = $this->argument->getValue();
|
||||
if(!isset($value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getArgument()
|
||||
{
|
||||
return $this->argument;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
if($this->argument)
|
||||
{
|
||||
return array($this->argument);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file InsertExpression.class.php */
|
||||
/* Location: ./classes/db/queryparts/expression/InsertExpression.class.php */
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* SelectExpression
|
||||
* Represents an expresion that appears in the select clause
|
||||
*
|
||||
* $column_name can be:
|
||||
* - a table column name
|
||||
* - an sql function - like count(*)
|
||||
* - an sql expression - substr(column_name, 1, 8) or score1 + score2
|
||||
* $column_name is already escaped
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/db/queryparts/expression
|
||||
* @version 0.1
|
||||
*/
|
||||
class SelectExpression extends Expression
|
||||
{
|
||||
|
||||
/**
|
||||
* column alias name
|
||||
* @var string
|
||||
*/
|
||||
var $column_alias;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param string $alias
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $alias = NULL)
|
||||
{
|
||||
parent::__construct($column_name);
|
||||
$this->column_alias = $alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return column expression, ex) column as alias
|
||||
* @return string
|
||||
*/
|
||||
function getExpression()
|
||||
{
|
||||
return sprintf("%s%s", $this->column_name, $this->column_alias ? (' AS ' . $this->column_alias) : "");
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function getArgument()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
function isSubquery()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file SelectExpression.class.php */
|
||||
/* Location: ./classes/db/queryparts/expression/SelectExpression.class.php */
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* StarExpression
|
||||
* Represents the * in 'select * from ...' statements
|
||||
*
|
||||
* @author Corina
|
||||
* @package /classes/db/queryparts/expression
|
||||
* @version 0.1
|
||||
*/
|
||||
class StarExpression extends SelectExpression
|
||||
{
|
||||
|
||||
/**
|
||||
* constructor, set the column to asterisk
|
||||
* @return void
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct("*");
|
||||
}
|
||||
|
||||
function getArgument()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
// StarExpression has no arguments
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file StarExpression.class.php */
|
||||
/* Location: ./classes/db/queryparts/expression/StarExpression.class.php */
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* UpdateExpression
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/db/queryparts/expression
|
||||
* @version 0.1
|
||||
*/
|
||||
class UpdateExpression extends Expression
|
||||
{
|
||||
|
||||
/**
|
||||
* argument
|
||||
* @var object
|
||||
*/
|
||||
var $argument;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param object $argument
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $argument)
|
||||
{
|
||||
parent::__construct($column_name);
|
||||
$this->argument = $argument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return column expression, ex) column = value
|
||||
* @return string
|
||||
*/
|
||||
function getExpression($with_value = true)
|
||||
{
|
||||
if($with_value)
|
||||
{
|
||||
return $this->getExpressionWithValue();
|
||||
}
|
||||
return $this->getExpressionWithoutValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return column expression, ex) column = value
|
||||
* @return string
|
||||
*/
|
||||
function getExpressionWithValue()
|
||||
{
|
||||
$value = $this->argument->getValue();
|
||||
$operation = $this->argument->getColumnOperation();
|
||||
if(isset($operation))
|
||||
{
|
||||
return "$this->column_name = $this->column_name $operation $value";
|
||||
}
|
||||
return "$this->column_name = $value";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return column expression, ex) column = ?
|
||||
* Can use prepare statement
|
||||
* @return string
|
||||
*/
|
||||
function getExpressionWithoutValue()
|
||||
{
|
||||
$operation = $this->argument->getColumnOperation();
|
||||
if(isset($operation))
|
||||
{
|
||||
return "$this->column_name = $this->column_name $operation ?";
|
||||
}
|
||||
return "$this->column_name = ?";
|
||||
}
|
||||
|
||||
function getValue()
|
||||
{
|
||||
// TODO Escape value according to column type instead of variable type
|
||||
$value = $this->argument->getValue();
|
||||
if(!is_numeric($value))
|
||||
{
|
||||
return "'" . $value . "'";
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
if(!$this->argument)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$value = $this->argument->getValue();
|
||||
if(!isset($value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getArgument()
|
||||
{
|
||||
return $this->argument;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
if($this->argument)
|
||||
{
|
||||
return array($this->argument);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file UpdateExpression.class.php */
|
||||
/* Location: ./classes/db/queryparts/expression/UpdateExpression.class.php */
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* UpdateExpression
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/db/queryparts/expression
|
||||
* @version 0.1
|
||||
*/
|
||||
class UpdateExpressionWithoutArgument extends UpdateExpression
|
||||
{
|
||||
|
||||
/**
|
||||
* argument
|
||||
* @var object
|
||||
*/
|
||||
var $argument;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param object $argument
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $argument)
|
||||
{
|
||||
parent::__construct($column_name, $argument);
|
||||
$this->argument = $argument;
|
||||
}
|
||||
|
||||
function getExpression($with_value = true)
|
||||
{
|
||||
return "$this->column_name = $this->argument";
|
||||
}
|
||||
|
||||
function getValue()
|
||||
{
|
||||
// TODO Escape value according to column type instead of variable type
|
||||
$value = $this->argument;
|
||||
if(!is_numeric($value))
|
||||
{
|
||||
return "'" . $value . "'";
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
if(!$this->argument)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$value = $this->argument;
|
||||
if(!isset($value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getArgument()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file UpdateExpressionWithoutArgument.class.php */
|
||||
/* Location: ./classes/db/queryparts/expression/UpdateExpressionWithoutArgument.class.php */
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/limit
|
||||
* @version 0.1
|
||||
*/
|
||||
class Limit
|
||||
{
|
||||
|
||||
/**
|
||||
* start number
|
||||
* @var int
|
||||
*/
|
||||
var $start;
|
||||
|
||||
/**
|
||||
* list count
|
||||
* @var int
|
||||
*/
|
||||
var $list_count;
|
||||
|
||||
/**
|
||||
* page count
|
||||
* @var int
|
||||
*/
|
||||
var $page_count;
|
||||
|
||||
/**
|
||||
* current page
|
||||
* @var int
|
||||
*/
|
||||
var $page;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param int $list_count
|
||||
* @param int $page
|
||||
* @param int $page_count
|
||||
* @param int $offset
|
||||
* @return void
|
||||
*/
|
||||
function __construct($list_count, $page = NULL, $page_count = NULL, $offset = NULL)
|
||||
{
|
||||
$this->list_count = $list_count;
|
||||
if($list_count->getValue())
|
||||
{
|
||||
if($page && $page->getValue())
|
||||
{
|
||||
$this->start = ($page->getValue() - 1) * $list_count->getValue();
|
||||
$this->page_count = $page_count;
|
||||
$this->page = $page;
|
||||
}
|
||||
elseif($offset)
|
||||
{
|
||||
$this->start = $offset->getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In case you choose to use query limit in other cases than page select
|
||||
* @return boolean
|
||||
*/
|
||||
function isPageHandler()
|
||||
{
|
||||
if($this->page)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getOffset()
|
||||
{
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
function getLimit()
|
||||
{
|
||||
return $this->list_count->getValue();
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
if($this->start)
|
||||
{
|
||||
return $this->start . ' , ' . $this->list_count->getValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->list_count->getValue() ?: '';
|
||||
}
|
||||
}
|
||||
}
|
||||
/* End of file Limit.class.php */
|
||||
/* Location: ./classes/db/limit/Limit.class.php */
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/order
|
||||
* @version 0.1
|
||||
*/
|
||||
class OrderByColumn
|
||||
{
|
||||
|
||||
/**
|
||||
* column name
|
||||
* @var string
|
||||
*/
|
||||
var $column_name;
|
||||
|
||||
/**
|
||||
* sort order
|
||||
* @var string
|
||||
*/
|
||||
var $sort_order;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name
|
||||
* @param string $sort_order
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $sort_order)
|
||||
{
|
||||
$this->column_name = $column_name;
|
||||
$this->sort_order = $sort_order;
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
$result = $this->getColumnName();
|
||||
$result .= ' ';
|
||||
$result .= is_a($this->sort_order, 'Argument') ? $this->sort_order->getValue() : strtoupper($this->sort_order);
|
||||
return $result;
|
||||
}
|
||||
|
||||
function getColumnName()
|
||||
{
|
||||
return is_a($this->column_name, 'Argument') ? $this->column_name->getValue() : $this->column_name;
|
||||
}
|
||||
|
||||
function getPureColumnName()
|
||||
{
|
||||
return is_a($this->column_name, 'Argument') ? $this->column_name->getPureValue() : $this->column_name;
|
||||
}
|
||||
|
||||
function getPureSortOrder()
|
||||
{
|
||||
return is_a($this->sort_order, 'Argument') ? $this->sort_order->getPureValue() : $this->sort_order;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
$args = array();
|
||||
if(is_a($this->column_name, 'Argument'))
|
||||
{
|
||||
$args[] = $this->column_name;
|
||||
}
|
||||
if(is_a($this->sort_order, 'Argument'))
|
||||
{
|
||||
$args[] = $this->sort_order;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file OrderByColumn.class.php */
|
||||
/* Location: ./classes/db/order/OrderByColumn.class.php */
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/table
|
||||
* @version 0.1
|
||||
*/
|
||||
class IndexHint
|
||||
{
|
||||
|
||||
/**
|
||||
* index name
|
||||
* @var string
|
||||
*/
|
||||
var $index_name;
|
||||
|
||||
/**
|
||||
* index hint type, ex) IGNORE, FORCE, USE...
|
||||
* @var string
|
||||
*/
|
||||
var $index_hint_type;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $index_name
|
||||
* @param string $index_hint_type
|
||||
* @return void
|
||||
*/
|
||||
function __construct($index_name, $index_hint_type)
|
||||
{
|
||||
$this->index_name = $index_name;
|
||||
$this->index_hint_type = $index_hint_type;
|
||||
}
|
||||
|
||||
function getIndexName()
|
||||
{
|
||||
return $this->index_name;
|
||||
}
|
||||
|
||||
function getIndexHintType()
|
||||
{
|
||||
return $this->index_hint_type;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file IndexHint.class.php */
|
||||
/* Location: ./classes/db/queryparts/table/IndexHint.class.php */
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* class JoinTable
|
||||
* $conditions in an array of Condition objects
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/db/queryparts/table
|
||||
* @version 0.1
|
||||
*/
|
||||
class JoinTable extends Table
|
||||
{
|
||||
|
||||
/**
|
||||
* join type
|
||||
* @var string
|
||||
*/
|
||||
var $join_type;
|
||||
|
||||
/**
|
||||
* condition list
|
||||
* @var array
|
||||
*/
|
||||
var $conditions;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $name
|
||||
* @param string $alias
|
||||
* @param string $join_type
|
||||
* @param array $conditions
|
||||
* @return void
|
||||
*/
|
||||
function __construct($name, $alias, $join_type, $conditions)
|
||||
{
|
||||
parent::__construct($name, $alias);
|
||||
$this->join_type = $join_type;
|
||||
$this->conditions = $conditions;
|
||||
}
|
||||
|
||||
function toString($with_value = true)
|
||||
{
|
||||
$part = strtoupper($this->join_type) . ' ' . $this->name;
|
||||
$part .= $this->alias ? (' AS ' . $this->alias) : '';
|
||||
$part .= ' ON ';
|
||||
|
||||
$condition_count = 0;
|
||||
foreach($this->conditions as $conditionGroup)
|
||||
{
|
||||
if($condition_count === 0)
|
||||
{
|
||||
$conditionGroup->setPipe("");
|
||||
}
|
||||
$part .= $conditionGroup->toString($with_value);
|
||||
$condition_count++;
|
||||
}
|
||||
return $part;
|
||||
}
|
||||
|
||||
function isJoinTable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
$args = array();
|
||||
foreach($this->conditions as $conditionGroup)
|
||||
{
|
||||
$args = array_merge($args, $conditionGroup->getArguments());
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file JoinTable.class.php */
|
||||
/* Location: ./classes/db/queryparts/table/JoinTable.class.php */
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/table
|
||||
* @version 0.1
|
||||
*/
|
||||
class MysqlTableWithHint extends Table
|
||||
{
|
||||
|
||||
/**
|
||||
* table name
|
||||
* @var string
|
||||
*/
|
||||
var $name;
|
||||
|
||||
/**
|
||||
* table alias
|
||||
* @var string
|
||||
*/
|
||||
var $alias;
|
||||
|
||||
/**
|
||||
* index hint type, ex) IGNORE, FORCE, USE...
|
||||
* @var array
|
||||
*/
|
||||
var $index_hints_list;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $name
|
||||
* @param string $alias
|
||||
* @param string $index_hints_list
|
||||
* @return void
|
||||
*/
|
||||
function __construct($name, $alias = NULL, $index_hints_list)
|
||||
{
|
||||
parent::__construct($name, $alias);
|
||||
$this->index_hints_list = $index_hints_list;
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
$result = parent::toString();
|
||||
|
||||
$use_index_hint = '';
|
||||
$force_index_hint = '';
|
||||
$ignore_index_hint = '';
|
||||
foreach($this->index_hints_list as $index_hint)
|
||||
{
|
||||
$index_hint_type = $index_hint->getIndexHintType();
|
||||
if($index_hint_type == 'USE')
|
||||
{
|
||||
$use_index_hint .= $index_hint->getIndexName() . ', ';
|
||||
}
|
||||
else if($index_hint_type == 'FORCE')
|
||||
{
|
||||
$force_index_hint .= $index_hint->getIndexName() . ', ';
|
||||
}
|
||||
else if($index_hint_type == 'IGNORE')
|
||||
{
|
||||
$ignore_index_hint .= $index_hint->getIndexName() . ', ';
|
||||
}
|
||||
}
|
||||
if($use_index_hint != '')
|
||||
{
|
||||
$result .= ' USE INDEX (' . substr($use_index_hint, 0, -2) . ') ';
|
||||
}
|
||||
if($force_index_hint != '')
|
||||
{
|
||||
$result .= ' FORCE INDEX (' . substr($force_index_hint, 0, -2) . ') ';
|
||||
}
|
||||
if($ignore_index_hint != '')
|
||||
{
|
||||
$result .= ' IGNORE INDEX (' . substr($ignore_index_hint, 0, -2) . ') ';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file MysqlTableWithHint.class.php */
|
||||
/* Location: ./classes/db/queryparts/table/MysqlTableWithHint.class.php */
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/db/queryparts/table
|
||||
* @version 0.1
|
||||
*/
|
||||
class Table
|
||||
{
|
||||
|
||||
/**
|
||||
* table name
|
||||
* @var string
|
||||
*/
|
||||
var $name;
|
||||
|
||||
/**
|
||||
* table alias
|
||||
* @var string
|
||||
*/
|
||||
var $alias;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $name
|
||||
* @param string $alias
|
||||
* @return void
|
||||
*/
|
||||
function __construct($name, $alias = NULL)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->alias = $alias;
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
//return $this->name;
|
||||
return sprintf("%s%s", $this->name, $this->alias ? (' AS ' . $this->alias) : '');
|
||||
}
|
||||
|
||||
function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
function getAlias()
|
||||
{
|
||||
return $this->alias;
|
||||
}
|
||||
|
||||
function isJoinTable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file Table.class.php */
|
||||
/* Location: ./classes/db/queryparts/table/Table.class.php */
|
||||
|
|
@ -36,15 +36,15 @@ class DisplayHandler extends Handler
|
|||
{
|
||||
$handler = new VirtualXMLDisplayHandler();
|
||||
}
|
||||
elseif(Context::getRequestMethod() == 'JSON' || isset($_POST['_rx_ajax_compat']))
|
||||
elseif(Context::getResponseMethod() == 'JSON' || isset($_POST['_rx_ajax_compat']))
|
||||
{
|
||||
$handler = new JSONDisplayHandler();
|
||||
}
|
||||
elseif(Context::getRequestMethod() == 'JS_CALLBACK')
|
||||
elseif(Context::getResponseMethod() == 'JS_CALLBACK')
|
||||
{
|
||||
$handler = new JSCallbackDisplayHandler();
|
||||
}
|
||||
elseif(Context::getRequestMethod() == 'XMLRPC')
|
||||
elseif(Context::getResponseMethod() == 'XMLRPC')
|
||||
{
|
||||
$handler = new XMLDisplayHandler();
|
||||
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE)
|
||||
|
|
@ -82,7 +82,7 @@ class DisplayHandler extends Handler
|
|||
|
||||
// execute add-on
|
||||
$called_position = 'before_display_content';
|
||||
$oAddonController = getController('addon');
|
||||
$oAddonController = AddonController::getInstance();
|
||||
$addon_file = $oAddonController->getCacheFilePath(Mobile::isFromMobilePhone() ? "mobile" : "pc");
|
||||
if(file_exists($addon_file)) include($addon_file);
|
||||
if($output === false || $output === null || $output instanceof BaseObject)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ class HTMLDisplayHandler
|
|||
'@\beditor/skins/xpresseditor/js/xe_textarea\.(?:min\.)?js@' => 'editor/skins/ckeditor/js/xe_textarea.js',
|
||||
);
|
||||
|
||||
/**
|
||||
* Image type information for SEO
|
||||
*/
|
||||
protected $_image_type = 'none';
|
||||
|
||||
/**
|
||||
* Produce HTML compliant content given a module object.\n
|
||||
* @param ModuleObject $oModule the module object
|
||||
|
|
@ -163,10 +168,14 @@ class HTMLDisplayHandler
|
|||
}
|
||||
}
|
||||
|
||||
// Add OpenGraph metadata
|
||||
// Add OpenGraph and Twitter metadata
|
||||
if (config('seo.og_enabled') && Context::get('module') !== 'admin')
|
||||
{
|
||||
$this->_addOpenGraphMetadata();
|
||||
if (config('seo.twitter_enabled'))
|
||||
{
|
||||
$this->_addTwitterMetadata();
|
||||
}
|
||||
}
|
||||
|
||||
// set icon
|
||||
|
|
@ -209,17 +218,14 @@ class HTMLDisplayHandler
|
|||
// handles a relative path generated by using the rewrite module
|
||||
if(Context::isAllowRewrite())
|
||||
{
|
||||
$pattern = '/src=("|\'){1}(?:\.\/)?((?:files\/(?:attach|cache|faceOff|member_extra_info|thumbnails)|addons|common|(?:m\.)?layouts|modules|widgets|widgetstyle)\/[^"\']+)("|\'){1}/s';
|
||||
$pattern = '/(action|src|href)=(["\'])(?:\.\/([^"\']*))?(["\'])/s';
|
||||
$output = preg_replace($pattern, '$1=$2' . \RX_BASEURL . '$3$4', $output);
|
||||
|
||||
$pattern = '/src=(["\'])((?:files\/(?:attach|cache|faceOff|member_extra_info|thumbnails)|addons|common|(?:m\.)?layouts|modules|widgets|widgetstyle)\/[^"\']+)(["\'])/s';
|
||||
$output = preg_replace($pattern, 'src=$1' . \RX_BASEURL . '$2$3', $output);
|
||||
|
||||
$pattern = '/href=("|\'){1}(\?[^"\']+)/s';
|
||||
$pattern = '/href=(["\'])(\?[^"\']+)/s';
|
||||
$output = preg_replace($pattern, 'href=$1' . \RX_BASEURL . '$2', $output);
|
||||
|
||||
if(Context::get('vid'))
|
||||
{
|
||||
$pattern = '/\/' . Context::get('vid') . '\?([^=]+)=/is';
|
||||
$output = preg_replace($pattern, '/?$1=', $output);
|
||||
}
|
||||
}
|
||||
|
||||
// prevent the 2nd request due to url(none) of the background-image
|
||||
|
|
@ -403,7 +409,6 @@ class HTMLDisplayHandler
|
|||
/**
|
||||
* Add OpenGraph metadata tags.
|
||||
*
|
||||
* @param string $output
|
||||
* @return void
|
||||
*/
|
||||
function _addOpenGraphMetadata()
|
||||
|
|
@ -531,6 +536,7 @@ class HTMLDisplayHandler
|
|||
Context::addOpenGraphData('og:image', Rhymix\Framework\URL::getCurrentDomainURL($first_image['filepath']));
|
||||
Context::addOpenGraphData('og:image:width', $first_image['width']);
|
||||
Context::addOpenGraphData('og:image:height', $first_image['height']);
|
||||
$this->_image_type = 'document';
|
||||
}
|
||||
elseif ($default_image = getAdminModel('admin')->getSiteDefaultImageUrl($site_module_info->domain_srl, $width, $height))
|
||||
{
|
||||
|
|
@ -540,6 +546,11 @@ class HTMLDisplayHandler
|
|||
Context::addOpenGraphData('og:image:width', $width);
|
||||
Context::addOpenGraphData('og:image:height', $height);
|
||||
}
|
||||
$this->_image_type = 'site';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_image_type = 'none';
|
||||
}
|
||||
|
||||
// Add tags and hashtags for articles.
|
||||
|
|
@ -574,6 +585,33 @@ class HTMLDisplayHandler
|
|||
Context::addOpenGraphData('og:article:modified_time', $oDocument->getUpdate('c'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Twitter metadata tags.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function _addTwitterMetadata()
|
||||
{
|
||||
$card_type = $this->_image_type === 'document' ? 'summary_large_image' : 'summary';
|
||||
Context::addMetaTag('twitter:card', $card_type);
|
||||
|
||||
foreach(Context::getOpenGraphData() as $val)
|
||||
{
|
||||
if ($val['property'] === 'og:title')
|
||||
{
|
||||
Context::addMetaTag('twitter:title', $val['content']);
|
||||
}
|
||||
if ($val['property'] === 'og:description')
|
||||
{
|
||||
Context::addMetaTag('twitter:description', $val['content']);
|
||||
}
|
||||
if ($val['property'] === 'og:image' && $this->_image_type === 'document')
|
||||
{
|
||||
Context::addMetaTag('twitter:image', $val['content']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* import basic .js files.
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ class FrontEndFileHandler extends Handler
|
|||
return;
|
||||
}
|
||||
|
||||
$default_font_config = Context::get('default_font_config') ?: getController('editor')->default_font_config;
|
||||
$default_font_config = Context::get('default_font_config') ?: EditorModel::$default_font_config;
|
||||
$file->vars['enable_xe_btn_styles'] = (defined('DISABLE_XE_BTN_STYLES') && DISABLE_XE_BTN_STYLES) ? 'false' : 'true';
|
||||
$file->vars['enable_xe_msg_styles'] = (defined('DISABLE_XE_MSG_STYLES') && DISABLE_XE_MSG_STYLES) ? 'false' : 'true';
|
||||
$file->vars = array_merge($file->vars, $default_font_config);
|
||||
|
|
|
|||
|
|
@ -12,15 +12,34 @@
|
|||
* */
|
||||
class ModuleHandler extends Handler
|
||||
{
|
||||
var $method = 'GET';
|
||||
var $module_info = null;
|
||||
var $module_srl = null;
|
||||
var $module = null;
|
||||
var $act = null;
|
||||
var $mid = null;
|
||||
var $document_srl = null;
|
||||
var $route = null;
|
||||
var $error = null;
|
||||
var $is_mobile = false;
|
||||
var $httpStatusCode = 200;
|
||||
|
||||
var $module = NULL; ///< Module
|
||||
var $act = NULL; ///< action
|
||||
var $mid = NULL; ///< Module ID
|
||||
var $document_srl = NULL; ///< Document Number
|
||||
var $module_srl = NULL; ///< Module Number
|
||||
var $module_info = NULL; ///< Module Info
|
||||
var $error = NULL; ///< an error code.
|
||||
var $httpStatusCode = NULL; ///< http status code.
|
||||
/**
|
||||
* Valid types and kinds of module instances.
|
||||
*/
|
||||
protected static $_types = array(
|
||||
'model' => 'Model',
|
||||
'view' => 'View',
|
||||
'controller' => 'Controller',
|
||||
'mobile' => 'Mobile',
|
||||
'api' => 'Api',
|
||||
'wap' => 'Wap',
|
||||
'class' => '',
|
||||
);
|
||||
protected static $_kinds = array(
|
||||
'admin' => 'Admin',
|
||||
'svc' => '',
|
||||
);
|
||||
|
||||
/**
|
||||
* prepares variables to use in moduleHandler
|
||||
|
|
@ -62,11 +81,14 @@ class ModuleHandler extends Handler
|
|||
}
|
||||
|
||||
// Set variables from request arguments
|
||||
$this->method = Context::getRequestMethod();
|
||||
$this->module = $module ? $module : Context::get('module');
|
||||
$this->act = $act ? $act : Context::get('act');
|
||||
$this->mid = $mid ? $mid : Context::get('mid');
|
||||
$this->document_srl = $document_srl ? (int) $document_srl : (int) Context::get('document_srl');
|
||||
$this->module_srl = $module_srl ? (int) $module_srl : (int) Context::get('module_srl');
|
||||
$this->route = Context::getRouteInfo() ?: new stdClass;
|
||||
$this->is_mobile = Mobile::isFromMobilePhone();
|
||||
if($entry = Context::get('entry'))
|
||||
{
|
||||
$this->entry = Context::convertEncodingStr($entry);
|
||||
|
|
@ -77,49 +99,13 @@ class ModuleHandler extends Handler
|
|||
Context::set('mid', $this->mid = null);
|
||||
}
|
||||
|
||||
// Validate variables to prevent XSS
|
||||
$isInvalid = false;
|
||||
if($this->module && !preg_match('/^[a-zA-Z0-9_-]+$/', $this->module))
|
||||
{
|
||||
$isInvalid = true;
|
||||
}
|
||||
if($this->mid && !preg_match('/^[a-zA-Z0-9_-]+$/', $this->mid))
|
||||
{
|
||||
$isInvalid = true;
|
||||
}
|
||||
if($this->act && !preg_match('/^[a-zA-Z0-9_-]+$/', $this->act))
|
||||
{
|
||||
$isInvalid = true;
|
||||
}
|
||||
if($isInvalid)
|
||||
{
|
||||
$this->error = 'msg_security_violation';
|
||||
return;
|
||||
}
|
||||
|
||||
if(isset($this->act) && (strlen($this->act) >= 4 && substr_compare($this->act, 'disp', 0, 4) === 0))
|
||||
{
|
||||
if(Context::get('_use_ssl') == 'optional' && Context::isExistsSSLAction($this->act) && !RX_SSL)
|
||||
{
|
||||
if(Context::get('_https_port') != null)
|
||||
{
|
||||
header('location: https://' . $_SERVER['HTTP_HOST'] . ':' . Context::get('_https_port') . $_SERVER['REQUEST_URI']);
|
||||
}
|
||||
else
|
||||
{
|
||||
header('location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// call a trigger before moduleHandler init
|
||||
self::triggerCall('moduleHandler.init', 'before', $this);
|
||||
|
||||
// execute addon (before module initialization)
|
||||
$called_position = 'before_module_init';
|
||||
$oAddonController = getController('addon');
|
||||
$addon_file = $oAddonController->getCacheFilePath(Mobile::isFromMobilePhone() ? 'mobile' : 'pc');
|
||||
$oAddonController = AddonController::getInstance();
|
||||
$addon_file = $oAddonController->getCacheFilePath($this->is_mobile ? 'mobile' : 'pc');
|
||||
if(file_exists($addon_file)) include($addon_file);
|
||||
}
|
||||
|
||||
|
|
@ -129,13 +115,12 @@ class ModuleHandler extends Handler
|
|||
* */
|
||||
public function init()
|
||||
{
|
||||
$oModuleModel = getModel('module');
|
||||
$site_module_info = Context::get('site_module_info');
|
||||
|
||||
// Check unregistered domain action.
|
||||
if (!$site_module_info || !isset($site_module_info->domain_srl) || $site_module_info->is_default_replaced)
|
||||
{
|
||||
$site_module_info = getModel('module')->getDefaultDomainInfo();
|
||||
$site_module_info = ModuleModel::getDefaultDomainInfo();
|
||||
if ($site_module_info)
|
||||
{
|
||||
$domain_action = config('url.unregistered_domain_action') ?: 'redirect_301';
|
||||
|
|
@ -160,112 +145,65 @@ class ModuleHandler extends Handler
|
|||
}
|
||||
}
|
||||
|
||||
// if success_return_url and error_return_url is incorrect
|
||||
$urls = array(Context::get('success_return_url'), Context::get('error_return_url'));
|
||||
foreach($urls as $url)
|
||||
// Check success_return_url and error_return_url to prevent dangerous redirects.
|
||||
$urls = array('success_return_url', 'error_return_url');
|
||||
foreach($urls as $key)
|
||||
{
|
||||
if(empty($url))
|
||||
$url = Context::get($key);
|
||||
if ($url && !Rhymix\Framework\URL::isInternalURL($url))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if($host = parse_url($url, PHP_URL_HOST))
|
||||
{
|
||||
$defaultHost = parse_url(Context::getDefaultUrl(), PHP_URL_HOST);
|
||||
if($host !== $defaultHost)
|
||||
{
|
||||
$siteModuleHost = $site_module_info->domain;
|
||||
if(strpos($siteModuleHost, '/') !== false)
|
||||
{
|
||||
$siteModuleHost = parse_url($siteModuleHost, PHP_URL_HOST);
|
||||
}
|
||||
if($host !== $siteModuleHost)
|
||||
{
|
||||
Context::set('success_return_url', null);
|
||||
Context::set('error_return_url', null);
|
||||
}
|
||||
}
|
||||
Context::set($key, null);
|
||||
}
|
||||
}
|
||||
|
||||
// If the Router returned an error earlier, show an error here.
|
||||
if($this->route && $this->route->status > 200)
|
||||
{
|
||||
$this->error = 'msg_module_is_not_exists';
|
||||
$this->httpStatusCode = 404;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Convert document alias (entry) to document_srl
|
||||
if(!$this->document_srl && $this->mid && $this->entry)
|
||||
{
|
||||
$oDocumentModel = getModel('document');
|
||||
$this->document_srl = $oDocumentModel->getDocumentSrlByAlias($this->mid, $this->entry);
|
||||
$this->document_srl = DocumentModel::getDocumentSrlByAlias($this->mid, $this->entry);
|
||||
if($this->document_srl)
|
||||
{
|
||||
Context::set('document_srl', $this->document_srl);
|
||||
}
|
||||
}
|
||||
|
||||
// Get module's information based on document_srl, if it's specified
|
||||
// Get module info from document_srl.
|
||||
if($this->document_srl)
|
||||
{
|
||||
$module_info = $oModuleModel->getModuleInfoByDocumentSrl($this->document_srl);
|
||||
if($module_info)
|
||||
$module_info = $this->_checkDocumentSrl();
|
||||
if ($module_info === false)
|
||||
{
|
||||
// If it exists, compare mid based on the module information
|
||||
// if mids are not matching, set it as the document's mid
|
||||
if(!$this->mid || ($this->mid != $module_info->mid))
|
||||
{
|
||||
if(Context::getRequestMethod() == 'GET')
|
||||
{
|
||||
Context::setCacheControl(0);
|
||||
header('location: ' . getNotEncodedSiteUrl($site_module_info->domain, 'mid', $module_info->mid, 'document_srl', $this->document_srl), true, 301);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->mid = $module_info->mid;
|
||||
Context::set('mid', $this->mid);
|
||||
}
|
||||
}
|
||||
// if requested module is different from one of the document, remove the module information retrieved based on the document number
|
||||
if($this->module && $module_info->module != $this->module)
|
||||
{
|
||||
unset($module_info);
|
||||
}
|
||||
}
|
||||
|
||||
// Block access to secret or temporary documents.
|
||||
if(Context::getRequestMethod() == 'GET')
|
||||
{
|
||||
$oDocumentModel = getModel('document');
|
||||
$oDocument = $oDocumentModel->getDocument($this->document_srl);
|
||||
if($oDocument->isExists() && !$oDocument->isAccessible())
|
||||
{
|
||||
$this->httpStatusCode = '403';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If module_info is not set yet, and there exists mid information, get module information based on the mid
|
||||
|
||||
// Get module info from mid.
|
||||
if(!$module_info && $this->mid)
|
||||
{
|
||||
$module_info = $oModuleModel->getModuleInfoByMid($this->mid, $site_module_info->site_srl);
|
||||
//if($this->module && $module_info->module != $this->module) unset($module_info);
|
||||
$module_info = ModuleModel::getModuleInfoByMid($this->mid);
|
||||
}
|
||||
|
||||
// If module_info is not set still, and $module does not exist, find the default module
|
||||
// Set module info as the default module for the domain.
|
||||
if(!$module_info && !$this->module && !$this->mid)
|
||||
{
|
||||
$module_info = $site_module_info;
|
||||
}
|
||||
|
||||
if(!$module_info && !$this->module && $site_module_info->module_site_srl)
|
||||
{
|
||||
$module_info = $site_module_info;
|
||||
}
|
||||
|
||||
// Set index document
|
||||
if($site_module_info->index_document_srl && !$this->module && !$this->mid && !$this->document_srl && Context::getRequestMethod() === 'GET' && !count($_GET))
|
||||
// Set the index document.
|
||||
if($site_module_info->index_document_srl && !$this->module && !$this->mid && !$this->document_srl && $this->method === 'GET' && !$this->route->args)
|
||||
{
|
||||
Context::set('document_srl', $this->document_srl = $site_module_info->index_document_srl, true);
|
||||
}
|
||||
|
||||
// redirect, if site start module
|
||||
if(!$site_module_info->index_document_srl && Context::getRequestMethod() === 'GET' && isset($_GET['mid']) && $_GET['mid'] === $site_module_info->mid && count($_GET) === 1)
|
||||
// Redirect if the index module was requested.
|
||||
if(!$site_module_info->index_document_srl && $this->method === 'GET' && isset($this->route->args['mid']) && $this->route->args['mid'] === $site_module_info->mid && count($this->route->args) === 1)
|
||||
{
|
||||
Context::setCacheControl(0);
|
||||
header('location: ' . getNotEncodedSiteUrl($site_module_info->domain), true, 301);
|
||||
|
|
@ -275,57 +213,18 @@ class ModuleHandler extends Handler
|
|||
// If module info was set, retrieve variables from the module information
|
||||
if($module_info)
|
||||
{
|
||||
// Set instance variables and SEO info.
|
||||
$this->module = $module_info->module;
|
||||
$this->mid = $module_info->mid;
|
||||
$this->module_info = $module_info;
|
||||
if ($module_info->mid == $site_module_info->mid)
|
||||
{
|
||||
$seo_title = config('seo.main_title') ?: '$SITE_TITLE - $SITE_SUBTITLE';
|
||||
}
|
||||
else
|
||||
{
|
||||
$seo_title = config('seo.subpage_title') ?: '$SITE_TITLE - $SUBPAGE_TITLE';
|
||||
}
|
||||
$this->_setModuleSEOInfo($module_info, $site_module_info);
|
||||
|
||||
getController('module')->replaceDefinedLangCode($seo_title);
|
||||
Context::setBrowserTitle($seo_title, array(
|
||||
'site_title' => Context::getSiteTitle(),
|
||||
'site_subtitle' => Context::getSiteSubtitle(),
|
||||
'subpage_title' => $module_info->browser_title,
|
||||
'page' => Context::get('page') ?: 1,
|
||||
));
|
||||
|
||||
$module_config = $oModuleModel->getModuleConfig('module');
|
||||
if ($module_info->meta_keywords)
|
||||
{
|
||||
Context::addMetaTag('keywords', $module_info->meta_keywords);
|
||||
}
|
||||
elseif ($site_module_info->settings->meta_keywords)
|
||||
{
|
||||
Context::addMetaTag('keywords', $site_module_info->settings->meta_keywords);
|
||||
}
|
||||
elseif ($module_config->meta_keywords)
|
||||
{
|
||||
Context::addMetaTag('keywords', $module_config->meta_keywords);
|
||||
}
|
||||
|
||||
if ($module_info->meta_description)
|
||||
{
|
||||
Context::addMetaTag('description', $module_info->meta_description);
|
||||
}
|
||||
elseif ($site_module_info->settings->meta_description)
|
||||
{
|
||||
Context::addMetaTag('description', $site_module_info->settings->meta_description);
|
||||
}
|
||||
elseif($module_config->meta_description)
|
||||
{
|
||||
Context::addMetaTag('description', $module_config->meta_description);
|
||||
}
|
||||
|
||||
$viewType = (Mobile::isFromMobilePhone()) ? 'M' : 'P';
|
||||
// Check if the current request is from a mobile device.
|
||||
$this->is_mobile = Mobile::isFromMobilePhone();
|
||||
$viewType = $this->is_mobile ? 'M' : 'P';
|
||||
$targetSrl = $viewType === 'M' ? 'mlayout_srl' : 'layout_srl';
|
||||
|
||||
// use the site default layout.
|
||||
// Apply default layouts.
|
||||
if($module_info->{$targetSrl} == -1)
|
||||
{
|
||||
$oLayoutAdminModel = getAdminModel('layout');
|
||||
|
|
@ -346,29 +245,28 @@ class ModuleHandler extends Handler
|
|||
$layoutSrl = $module_info->{$targetSrl};
|
||||
}
|
||||
|
||||
// reset a layout_srl in module_info.
|
||||
// Reset layout_srl in module_info.
|
||||
$module_info->{$targetSrl} = $layoutSrl;
|
||||
|
||||
$part_config = $oModuleModel->getModulePartConfig('layout', $layoutSrl);
|
||||
|
||||
// Add layout header script.
|
||||
$part_config = ModuleModel::getModulePartConfig('layout', $layoutSrl);
|
||||
Context::addHtmlHeader($part_config->header_script);
|
||||
}
|
||||
|
||||
// Set module and mid into module_info
|
||||
if(!isset($this->module_info))
|
||||
else
|
||||
{
|
||||
$this->module_info = new stdClass();
|
||||
$this->module_info = new stdClass;
|
||||
$this->module_info->module = $this->module;
|
||||
$this->module_info->mid = $this->mid;
|
||||
}
|
||||
$this->module_info->module = $this->module;
|
||||
$this->module_info->mid = $this->mid;
|
||||
|
||||
// Set site_srl add 2011 08 09
|
||||
// Always overwrite site_srl (deprecated)
|
||||
$this->module_info->site_srl = $site_module_info->site_srl;
|
||||
|
||||
// Still no module? it's an error
|
||||
if(!$this->module)
|
||||
{
|
||||
$this->error = 'msg_module_is_not_exists';
|
||||
$this->httpStatusCode = '404';
|
||||
$this->httpStatusCode = 404;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -398,26 +296,17 @@ class ModuleHandler extends Handler
|
|||
* */
|
||||
public function procModule()
|
||||
{
|
||||
$oModuleModel = getModel('module');
|
||||
$display_mode = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
|
||||
// Set the display mode for the current device type.
|
||||
$this->is_mobile = Mobile::isFromMobilePhone();
|
||||
|
||||
// If error occurred while preparation, return a message instance
|
||||
if($this->error)
|
||||
{
|
||||
self::_setInputErrorToContext();
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
if($this->httpStatusCode)
|
||||
{
|
||||
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
|
||||
}
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, $this->error, $this->httpStatusCode);
|
||||
}
|
||||
|
||||
// Get action information with conf/module.xml
|
||||
$xml_info = $oModuleModel->getModuleActionXml($this->module);
|
||||
$xml_info = ModuleModel::getModuleActionXml($this->module);
|
||||
|
||||
// If not installed yet, modify act
|
||||
if($this->module == "install")
|
||||
|
|
@ -437,19 +326,7 @@ class ModuleHandler extends Handler
|
|||
// still no act means error
|
||||
if(!$this->act)
|
||||
{
|
||||
$this->error = 'msg_module_is_not_exists';
|
||||
$this->httpStatusCode = '404';
|
||||
|
||||
self::_setInputErrorToContext();
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
if($this->httpStatusCode)
|
||||
{
|
||||
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
|
||||
}
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, 'msg_module_is_not_exists', 404);
|
||||
}
|
||||
|
||||
// get type, kind
|
||||
|
|
@ -483,12 +360,7 @@ class ModuleHandler extends Handler
|
|||
|
||||
if(!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList))
|
||||
{
|
||||
$this->error = 'msg_invalid_request';
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, 'msg_method_not_allowed', 405);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -497,13 +369,7 @@ class ModuleHandler extends Handler
|
|||
{
|
||||
if($xml_info->action->{$this->act} && $xml_info->action->{$this->act}->check_csrf !== 'false' && !checkCSRF())
|
||||
{
|
||||
$this->_setInputErrorToContext();
|
||||
$this->error = 'msg_invalid_request';
|
||||
$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, 'msg_security_violation');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -515,7 +381,7 @@ class ModuleHandler extends Handler
|
|||
$logged_info = Context::get('logged_info');
|
||||
|
||||
// if(type == view, and case for using mobilephone)
|
||||
if($type == "view" && Mobile::isFromMobilePhone() && Context::isInstalled())
|
||||
if($type == "view" && $this->is_mobile && Context::isInstalled())
|
||||
{
|
||||
$orig_type = "view";
|
||||
$type = "mobile";
|
||||
|
|
@ -536,16 +402,7 @@ class ModuleHandler extends Handler
|
|||
|
||||
if(!is_object($oModule))
|
||||
{
|
||||
self::_setInputErrorToContext();
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
if($this->httpStatusCode)
|
||||
{
|
||||
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
|
||||
}
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, $this->error, $this->httpStatusCode);
|
||||
}
|
||||
|
||||
// If there is no such action in the module object
|
||||
|
|
@ -553,24 +410,14 @@ class ModuleHandler extends Handler
|
|||
{
|
||||
if(!Context::isInstalled())
|
||||
{
|
||||
self::_setInputErrorToContext();
|
||||
$this->error = 'msg_invalid_request';
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
if($this->httpStatusCode)
|
||||
{
|
||||
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
|
||||
}
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, 'msg_invalid_request');
|
||||
}
|
||||
|
||||
// 1. Look for the module with action name
|
||||
if(preg_match('/^([a-z]+)([A-Z])([a-z0-9\_]+)(.*)$/', $this->act, $matches))
|
||||
{
|
||||
$module = strtolower($matches[2] . $matches[3]);
|
||||
$xml_info = $oModuleModel->getModuleActionXml($module);
|
||||
$xml_info = ModuleModel::getModuleActionXml($module);
|
||||
|
||||
if($xml_info->action->{$this->act} && ($this->module == 'admin' || $xml_info->action->{$this->act}->standalone != 'false'))
|
||||
{
|
||||
|
|
@ -583,19 +430,13 @@ class ModuleHandler extends Handler
|
|||
}
|
||||
else
|
||||
{
|
||||
$this->error = 'msg_invalid_request';
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, 'msg_invalid_request');
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($forward->module))
|
||||
{
|
||||
$forward = $oModuleModel->getActionForward($this->act);
|
||||
$forward = ModuleModel::getActionForward($this->act);
|
||||
}
|
||||
|
||||
if(!empty($forward->module))
|
||||
|
|
@ -610,20 +451,14 @@ class ModuleHandler extends Handler
|
|||
Context::addMetaTag('robots', 'noindex');
|
||||
}
|
||||
|
||||
$xml_info = $oModuleModel->getModuleActionXml($forward->module);
|
||||
$xml_info = ModuleModel::getModuleActionXml($forward->module);
|
||||
|
||||
// Protect admin action
|
||||
if(($this->module == 'admin' || $kind == 'admin') && !$oModuleModel->getGrant($forward, $logged_info)->root)
|
||||
if(($this->module == 'admin' || $kind == 'admin') && !ModuleModel::getGrant($forward, $logged_info)->root)
|
||||
{
|
||||
if($this->module == 'admin' || empty($xml_info->permission->{$this->act}))
|
||||
if($this->module == 'admin' || empty($xml_info->action->{$this->act}->permission->target))
|
||||
{
|
||||
self::_setInputErrorToContext();
|
||||
$this->error = 'admin.msg_is_not_administrator';
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, 'admin.msg_is_not_administrator');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -644,12 +479,7 @@ class ModuleHandler extends Handler
|
|||
|
||||
if(!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList))
|
||||
{
|
||||
$this->error = 'msg_security_violation';
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, 'msg_method_not_allowed', 405);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -658,17 +488,11 @@ class ModuleHandler extends Handler
|
|||
{
|
||||
if($xml_info->action->{$this->act} && $xml_info->action->{$this->act}->check_csrf !== 'false' && !checkCSRF())
|
||||
{
|
||||
$this->_setInputErrorToContext();
|
||||
$this->error = 'msg_security_violation';
|
||||
$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage();
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, 'msg_security_violation');
|
||||
}
|
||||
}
|
||||
|
||||
if($type == "view" && Mobile::isFromMobilePhone())
|
||||
if($type == "view" && $this->is_mobile)
|
||||
{
|
||||
$orig_type = "view";
|
||||
$type = "mobile";
|
||||
|
|
@ -688,16 +512,7 @@ class ModuleHandler extends Handler
|
|||
|
||||
if(!is_object($oModule))
|
||||
{
|
||||
self::_setInputErrorToContext();
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage('msg_module_is_not_exists');
|
||||
$oMessageObject->dispMessage();
|
||||
if($this->httpStatusCode)
|
||||
{
|
||||
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
|
||||
}
|
||||
return $oMessageObject;
|
||||
return self::_createErrorMessage(-1, 'msg_module_is_not_exists', 404);
|
||||
}
|
||||
|
||||
// Admin page layout
|
||||
|
|
@ -726,7 +541,7 @@ class ModuleHandler extends Handler
|
|||
if(!empty($ruleset))
|
||||
{
|
||||
$rulesetModule = !empty($forward->module) ? $forward->module : $this->module;
|
||||
$rulesetFile = $oModuleModel->getValidatorFilePath($rulesetModule, $ruleset, $this->mid);
|
||||
$rulesetFile = ModuleModel::getValidatorFilePath($rulesetModule, $ruleset, $this->mid);
|
||||
if(!empty($rulesetFile))
|
||||
{
|
||||
if($_SESSION['XE_VALIDATOR_ERROR_LANG'])
|
||||
|
|
@ -860,10 +675,140 @@ class ModuleHandler extends Handler
|
|||
}
|
||||
|
||||
/**
|
||||
* set error message to Session.
|
||||
* Check the value of $document_srl. This method is called during init().
|
||||
*
|
||||
* @return object|false
|
||||
*/
|
||||
protected function _checkDocumentSrl()
|
||||
{
|
||||
// Get the module that the document belongs to.
|
||||
$module_info = ModuleModel::getModuleInfoByDocumentSrl($this->document_srl);
|
||||
if($module_info)
|
||||
{
|
||||
// Compare the current mid to the module that the document belongs to.
|
||||
if(!$this->mid || $this->mid !== $module_info->mid)
|
||||
{
|
||||
// If the document is notice-all, preserve the current mid.
|
||||
if($module_info->is_notice === 'A')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// If this is a GET request, redirect to the correct mid.
|
||||
elseif(Context::getRequestMethod() === 'GET')
|
||||
{
|
||||
Context::setCacheControl(0);
|
||||
header('Location: ' . getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $this->document_srl), true, 301);
|
||||
return false;
|
||||
}
|
||||
// If this is NOT a GET request, don't redirect. Just overwrite the mid for the current request.
|
||||
else
|
||||
{
|
||||
$this->mid = $module_info->mid;
|
||||
Context::set('mid', $this->mid);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove module info if a different module has already been selected for the current request.
|
||||
if($this->module && $module_info->module !== $this->module)
|
||||
{
|
||||
$module_info = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Block access to secret or temporary documents.
|
||||
if(Context::getRequestMethod() === 'GET')
|
||||
{
|
||||
$oDocument = DocumentModel::getDocument($this->document_srl);
|
||||
if(!$oDocument->isExists())
|
||||
{
|
||||
$this->httpStatusCode = 404;
|
||||
}
|
||||
elseif(!$oDocument->isAccessible())
|
||||
{
|
||||
$this->httpStatusCode = 403;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the module info for further processing.
|
||||
return $module_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SEO information to Context.
|
||||
*
|
||||
* @param object $module_info
|
||||
* @param object $site_module_info
|
||||
*/
|
||||
protected function _setModuleSEOInfo($module_info, $site_module_info)
|
||||
{
|
||||
// Set the browser title.
|
||||
if ($module_info->mid == $site_module_info->mid)
|
||||
{
|
||||
$seo_title = config('seo.main_title') ?: '$SITE_TITLE - $SITE_SUBTITLE';
|
||||
}
|
||||
else
|
||||
{
|
||||
$seo_title = config('seo.subpage_title') ?: '$SITE_TITLE - $SUBPAGE_TITLE';
|
||||
}
|
||||
ModuleController::getInstance()->replaceDefinedLangCode($seo_title);
|
||||
Context::setBrowserTitle($seo_title, array(
|
||||
'site_title' => Context::getSiteTitle(),
|
||||
'site_subtitle' => Context::getSiteSubtitle(),
|
||||
'subpage_title' => $module_info->browser_title,
|
||||
'page' => Context::get('page') ?: 1,
|
||||
));
|
||||
|
||||
// Set meta keywords.
|
||||
$module_config = ModuleModel::getModuleConfig('module');
|
||||
if ($module_info->meta_keywords)
|
||||
{
|
||||
Context::addMetaTag('keywords', $module_info->meta_keywords);
|
||||
}
|
||||
elseif ($site_module_info->settings->meta_keywords)
|
||||
{
|
||||
Context::addMetaTag('keywords', $site_module_info->settings->meta_keywords);
|
||||
}
|
||||
elseif ($module_config->meta_keywords)
|
||||
{
|
||||
Context::addMetaTag('keywords', $module_config->meta_keywords);
|
||||
}
|
||||
|
||||
// Set meta description.
|
||||
if ($module_info->meta_description)
|
||||
{
|
||||
Context::addMetaTag('description', $module_info->meta_description);
|
||||
}
|
||||
elseif ($site_module_info->settings->meta_description)
|
||||
{
|
||||
Context::addMetaTag('description', $site_module_info->settings->meta_description);
|
||||
}
|
||||
elseif($module_config->meta_description)
|
||||
{
|
||||
Context::addMetaTag('description', $module_config->meta_description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save input values to session so that they can be recovered after returning to the previous form.
|
||||
*
|
||||
* @return void
|
||||
* */
|
||||
public static function _setInputErrorToContext()
|
||||
*/
|
||||
protected static function _setInputValueToSession()
|
||||
{
|
||||
$requestVars = getDestroyXeVars(Context::getRequestVars());
|
||||
unset($requestVars->act, $requestVars->mid, $requestVars->vid);
|
||||
foreach($requestVars as $key => $value)
|
||||
{
|
||||
$_SESSION['INPUT_ERROR'][$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get previous error information and restore it to Context so that it is available to templates.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function _setInputErrorToContext()
|
||||
{
|
||||
if($_SESSION['XE_VALIDATOR_ERROR'] && !Context::get('XE_VALIDATOR_ERROR'))
|
||||
{
|
||||
|
|
@ -897,7 +842,7 @@ class ModuleHandler extends Handler
|
|||
* clear error message to Session.
|
||||
* @return void
|
||||
* */
|
||||
public static function _clearErrorSession()
|
||||
protected static function _clearErrorSession()
|
||||
{
|
||||
unset($_SESSION['XE_VALIDATOR_ERROR']);
|
||||
unset($_SESSION['XE_VALIDATOR_MESSAGE']);
|
||||
|
|
@ -908,17 +853,25 @@ class ModuleHandler extends Handler
|
|||
}
|
||||
|
||||
/**
|
||||
* occured error when, set input values to session.
|
||||
* @return void
|
||||
* */
|
||||
public static function _setInputValueToSession()
|
||||
* Create a message module instance with an error message.
|
||||
*/
|
||||
protected static function _createErrorMessage($error, $message, $status_code = 403, $location = null)
|
||||
{
|
||||
$requestVars = Context::getRequestVars();
|
||||
unset($requestVars->act, $requestVars->mid, $requestVars->vid, $requestVars->success_return_url, $requestVars->error_return_url, $requestVars->xe_validator_id);
|
||||
foreach($requestVars AS $key => $value)
|
||||
$display_mode = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
|
||||
if (!$location)
|
||||
{
|
||||
$_SESSION['INPUT_ERROR'][$key] = $value;
|
||||
$backtrace = debug_backtrace(false);
|
||||
$caller = array_shift($backtrace);
|
||||
$location = $caller['file'] . ':' . $caller['line'];
|
||||
}
|
||||
|
||||
self::_setInputErrorToContext();
|
||||
$oMessageObject = self::getModuleInstance('message', $display_mode);
|
||||
$oMessageObject->setError($error);
|
||||
$oMessageObject->setMessage($message);
|
||||
$oMessageObject->setHttpStatusCode($status_code ?: 403);
|
||||
$oMessageObject->dispMessage('', $location);
|
||||
return $oMessageObject;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -928,11 +881,14 @@ class ModuleHandler extends Handler
|
|||
* */
|
||||
public function displayContent($oModule = NULL)
|
||||
{
|
||||
// Set the display mode for the current device type.
|
||||
$this->is_mobile = Mobile::isFromMobilePhone();
|
||||
|
||||
// If the module is not set or not an object, set error
|
||||
if(!$oModule || !is_object($oModule))
|
||||
{
|
||||
$this->error = 'msg_module_is_not_exists';
|
||||
$this->httpStatusCode = '404';
|
||||
$this->httpStatusCode = 404;
|
||||
}
|
||||
|
||||
// If connection to DB has a problem even though it's not install module, set error
|
||||
|
|
@ -997,11 +953,7 @@ class ModuleHandler extends Handler
|
|||
if($this->error)
|
||||
{
|
||||
// display content with message module instance
|
||||
$type = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
|
||||
$oMessageObject = self::getModuleInstance('message', $type);
|
||||
$oMessageObject->setError(-1);
|
||||
$oMessageObject->setMessage($this->error);
|
||||
$oMessageObject->dispMessage(null, $oModule->get('rx_error_location'));
|
||||
$oMessageObject = self::_createErrorMessage(-1, $this->error, $this->httpStatusCode, $oModule->get('rx_error_location'));
|
||||
|
||||
// display Error Page
|
||||
if(!in_array($oMessageObject->getHttpStatusCode(), array(200, 403)))
|
||||
|
|
@ -1015,8 +967,8 @@ class ModuleHandler extends Handler
|
|||
$oModule->setTemplatePath($oMessageObject->getTemplatePath());
|
||||
$oModule->setTemplateFile($oMessageObject->getTemplateFile());
|
||||
$oModule->setHttpStatusCode($oMessageObject->getHttpStatusCode());
|
||||
// Otherwise, set message instance as the target module
|
||||
}
|
||||
// Otherwise, set message instance as the target module
|
||||
else
|
||||
{
|
||||
$oModule = $oMessageObject;
|
||||
|
|
@ -1026,7 +978,7 @@ class ModuleHandler extends Handler
|
|||
}
|
||||
|
||||
// Check if layout_srl exists for the module
|
||||
$viewType = (Mobile::isFromMobilePhone()) ? 'M' : 'P';
|
||||
$viewType = $this->is_mobile ? 'M' : 'P';
|
||||
if($viewType === 'M')
|
||||
{
|
||||
$layout_srl = $oModule->module_info->mlayout_srl;
|
||||
|
|
@ -1044,14 +996,14 @@ class ModuleHandler extends Handler
|
|||
// if layout_srl is rollback by module, set default layout
|
||||
if($layout_srl == -1)
|
||||
{
|
||||
$oLayoutAdminModel = getAdminModel('layout');
|
||||
$oLayoutAdminModel = LayoutAdminModel::getInstance();
|
||||
$layout_srl = $oLayoutAdminModel->getSiteDefaultLayout($viewType, $oModule->module_info->site_srl);
|
||||
}
|
||||
|
||||
if($layout_srl && !$oModule->getLayoutFile())
|
||||
{
|
||||
// If layout_srl exists, get information of the layout, and set the location of layout_path/ layout_file
|
||||
$oLayoutModel = getModel('layout');
|
||||
$oLayoutModel = LayoutModel::getInstance();
|
||||
$layout_info = $oLayoutModel->getLayout($layout_srl);
|
||||
if($layout_info)
|
||||
{
|
||||
|
|
@ -1183,109 +1135,23 @@ class ModuleHandler extends Handler
|
|||
* */
|
||||
public static function getModuleInstance($module, $type = 'view', $kind = '')
|
||||
{
|
||||
$parent_module = $module;
|
||||
$kind = strtolower($kind);
|
||||
$type = strtolower($type);
|
||||
if (!isset(self::$_types[$type]))
|
||||
{
|
||||
$type = 'view';
|
||||
}
|
||||
|
||||
$kinds = array('svc' => 1, 'admin' => 1);
|
||||
if(!isset($kinds[$kind]))
|
||||
$kind = strtolower($kind);
|
||||
if (!isset(self::$_kinds[$kind]) || $type === 'class')
|
||||
{
|
||||
$kind = 'svc';
|
||||
}
|
||||
|
||||
$key = $module . '.' . ($kind != 'admin' ? '' : 'admin') . '.' . $type;
|
||||
|
||||
if(is_array($GLOBALS['__MODULE_EXTEND__']) && array_key_exists($key, $GLOBALS['__MODULE_EXTEND__']))
|
||||
$class_name = $module . self::$_kinds[$kind] . self::$_types[$type];
|
||||
if (class_exists($class_name))
|
||||
{
|
||||
$module = $extend_module = $GLOBALS['__MODULE_EXTEND__'][$key];
|
||||
return $class_name::getInstance($module);
|
||||
}
|
||||
|
||||
// if there is no instance of the module in global variable, create a new one
|
||||
if(!isset($GLOBALS['_loaded_module'][$module][$type][$kind]))
|
||||
{
|
||||
self::_getModuleFilePath($module, $type, $kind, $class_path, $high_class_file, $class_file, $instance_name);
|
||||
|
||||
if($extend_module && (!is_readable($high_class_file) || !is_readable($class_file)))
|
||||
{
|
||||
$module = $parent_module;
|
||||
self::_getModuleFilePath($module, $type, $kind, $class_path, $high_class_file, $class_file, $instance_name);
|
||||
}
|
||||
|
||||
// Check if the base class and instance class exist
|
||||
if(!class_exists($module, true))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if(!class_exists($instance_name, true))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create an instance
|
||||
$oModule = new $instance_name();
|
||||
if(!is_object($oModule))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Populate default properties
|
||||
if($oModule->user === false)
|
||||
{
|
||||
$oModule->user = Context::get('logged_info') ?: new Rhymix\Framework\Helpers\SessionHelper;
|
||||
}
|
||||
|
||||
// Load language files for the class
|
||||
if($module !== 'module')
|
||||
{
|
||||
Context::loadLang($class_path . 'lang');
|
||||
}
|
||||
if($extend_module)
|
||||
{
|
||||
Context::loadLang(ModuleHandler::getModulePath($parent_module) . 'lang');
|
||||
}
|
||||
|
||||
// Set variables to the instance
|
||||
$oModule->setModule($module);
|
||||
$oModule->setModulePath($class_path);
|
||||
|
||||
// Store the created instance into GLOBALS variable
|
||||
$GLOBALS['_loaded_module'][$module][$type][$kind] = $oModule;
|
||||
}
|
||||
|
||||
// return the instance
|
||||
return $GLOBALS['_loaded_module'][$module][$type][$kind];
|
||||
}
|
||||
|
||||
public static function _getModuleFilePath($module, $type, $kind, &$classPath, &$highClassFile, &$classFile, &$instanceName)
|
||||
{
|
||||
$classPath = self::getModulePath($module);
|
||||
|
||||
$highClassFile = sprintf('%s%s%s.class.php', _XE_PATH_, $classPath, $module);
|
||||
$highClassFile = FileHandler::getRealPath($highClassFile);
|
||||
|
||||
$types = array('view','controller','model','api','wap','mobile','class');
|
||||
if(!in_array($type, $types))
|
||||
{
|
||||
$type = $types[0];
|
||||
}
|
||||
if($type == 'class')
|
||||
{
|
||||
$instanceName = '%s';
|
||||
$classFile = '%s%s.%s.php';
|
||||
}
|
||||
elseif($kind == 'admin' && array_search($type, $types) < 3)
|
||||
{
|
||||
$instanceName = '%sAdmin%s';
|
||||
$classFile = '%s%s.admin.%s.php';
|
||||
}
|
||||
else
|
||||
{
|
||||
$instanceName = '%s%s';
|
||||
$classFile = '%s%s.%s.php';
|
||||
}
|
||||
|
||||
$instanceName = sprintf($instanceName, $module, ucfirst($type));
|
||||
$classFile = FileHandler::getRealPath(sprintf($classFile, $classPath, $module, $type));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1303,16 +1169,12 @@ class ModuleHandler extends Handler
|
|||
return new BaseObject();
|
||||
}
|
||||
|
||||
$oModuleModel = getModel('module');
|
||||
$triggers = $oModuleModel->getTriggers($trigger_name, $called_position);
|
||||
$triggers = ModuleModel::getTriggers($trigger_name, $called_position);
|
||||
if(!$triggers)
|
||||
{
|
||||
$triggers = array();
|
||||
}
|
||||
|
||||
//store before trigger call time
|
||||
$before_trigger_time = microtime(true);
|
||||
|
||||
foreach($triggers as $item)
|
||||
{
|
||||
$module = $item->module;
|
||||
|
|
@ -1362,7 +1224,7 @@ class ModuleHandler extends Handler
|
|||
unset($oModule);
|
||||
}
|
||||
|
||||
$trigger_functions = $oModuleModel->getTriggerFunctions($trigger_name, $called_position);
|
||||
$trigger_functions = ModuleModel::getTriggerFunctions($trigger_name, $called_position);
|
||||
foreach($trigger_functions as $item)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -5,28 +5,38 @@
|
|||
* @class ModuleObject
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* base class of ModuleHandler
|
||||
* */
|
||||
*/
|
||||
class ModuleObject extends BaseObject
|
||||
{
|
||||
// Variables about the current module
|
||||
public $module;
|
||||
public $module_info;
|
||||
public $origin_module_info;
|
||||
public $module_config;
|
||||
public $module_path;
|
||||
public $xml_info;
|
||||
|
||||
var $mid = NULL; ///< string to represent run-time instance of Module (XE Module)
|
||||
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
|
||||
var $act = NULL; ///< a string value to contain the action name
|
||||
var $template_path = NULL; ///< a path of directory where template files reside
|
||||
var $template_file = NULL; ///< name of template file
|
||||
var $layout_path = ''; ///< a path of directory where layout files reside
|
||||
var $layout_file = ''; ///< name of layout file
|
||||
var $edited_layout_file = ''; ///< name of temporary layout files that is modified in an admin mode
|
||||
var $stop_proc = FALSE; ///< a flag to indicating whether to stop the execution of code.
|
||||
var $module_config = NULL;
|
||||
var $ajaxRequestMethod = array('XMLRPC', 'JSON');
|
||||
var $gzhandler_enable = TRUE;
|
||||
var $user = FALSE;
|
||||
// Variables about the current module instance and the current request
|
||||
public $module_srl;
|
||||
public $mid;
|
||||
public $act;
|
||||
|
||||
// Variables about the layout and/or template
|
||||
public $template_path;
|
||||
public $template_file;
|
||||
public $layout_path;
|
||||
public $layout_file;
|
||||
public $edited_layout_file;
|
||||
|
||||
// Variables to control processing
|
||||
public $stop_proc = false;
|
||||
|
||||
// Variables for convenience
|
||||
public $user;
|
||||
|
||||
// Other variables for compatibility
|
||||
public $ajaxRequestMethod = array('XMLRPC', 'JSON');
|
||||
public $gzhandler_enable = true;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
|
@ -35,47 +45,97 @@ class ModuleObject extends BaseObject
|
|||
* @param string $message Error message
|
||||
* @return void
|
||||
*/
|
||||
function __construct($error = 0, $message = 'success')
|
||||
public function __construct($error = 0, $message = 'success')
|
||||
{
|
||||
$this->user = Context::get('logged_info') ?: new Rhymix\Framework\Helpers\SessionHelper;
|
||||
if(!($this->user instanceof Rhymix\Framework\Helpers\SessionHelper))
|
||||
{
|
||||
$this->user = Rhymix\Framework\Session::getMemberInfo();
|
||||
}
|
||||
parent::__construct($error, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton
|
||||
*
|
||||
* @param string $module_hint (optional)
|
||||
* @return self
|
||||
*/
|
||||
public static function getInstance($module_hint = null)
|
||||
{
|
||||
// If an instance already exists, return it.
|
||||
$class_name = static::class;
|
||||
if (isset($GLOBALS['_module_instances_'][$class_name]))
|
||||
{
|
||||
return $GLOBALS['_module_instances_'][$class_name];
|
||||
}
|
||||
|
||||
// Get some information about the class.
|
||||
if ($module_hint)
|
||||
{
|
||||
$module_path = \RX_BASEDIR . 'modules/' . $module_hint . '/';
|
||||
$module = $module_hint;
|
||||
}
|
||||
else
|
||||
{
|
||||
$class_filename = (new ReflectionClass($class_name))->getFileName();
|
||||
preg_match('!^(.+[/\\\\]([^/\\\\]+)[/\\\\])[^/\\\\]+$!', $class_filename, $matches);
|
||||
$module_path = $matches[1];
|
||||
$module = $matches[2];
|
||||
}
|
||||
|
||||
// Create a new instance.
|
||||
$obj = new $class_name;
|
||||
|
||||
// Populate default properties.
|
||||
$obj->setModulePath($module_path);
|
||||
$obj->setModule($module);
|
||||
$obj->user = Context::get('logged_info') ?: new Rhymix\Framework\Helpers\SessionHelper;
|
||||
if(!($obj->user instanceof Rhymix\Framework\Helpers\SessionHelper))
|
||||
{
|
||||
$obj->user = Rhymix\Framework\Session::getMemberInfo();
|
||||
}
|
||||
|
||||
// Load language files.
|
||||
if($module !== 'module')
|
||||
{
|
||||
Context::loadLang($module_path . 'lang');
|
||||
}
|
||||
|
||||
// Return the instance.
|
||||
return $GLOBALS['_module_instances_'][$class_name] = $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter to set the name of module
|
||||
*
|
||||
* @param string $module name of module
|
||||
* @return void
|
||||
* */
|
||||
function setModule($module)
|
||||
* @return $this
|
||||
*/
|
||||
public function setModule($module)
|
||||
{
|
||||
$this->module = $module;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter to set the name of module path
|
||||
*
|
||||
* @param string $path the directory path to a module directory
|
||||
* @return void
|
||||
* */
|
||||
function setModulePath($path)
|
||||
* @return $this
|
||||
*/
|
||||
public function setModulePath($path)
|
||||
{
|
||||
if(substr_compare($path, '/', -1) !== 0)
|
||||
{
|
||||
$path.='/';
|
||||
}
|
||||
$this->module_path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter to set an url for redirection
|
||||
*
|
||||
* @param string $url url for redirection
|
||||
* @remark redirect_url is used only for ajax requests
|
||||
* @return void
|
||||
* */
|
||||
function setRedirectUrl($url = './', $output = NULL)
|
||||
* @return $this
|
||||
*/
|
||||
public function setRedirectUrl($url = './', $output = NULL)
|
||||
{
|
||||
$this->add('redirect_url', $url);
|
||||
|
||||
|
|
@ -83,13 +143,18 @@ class ModuleObject extends BaseObject
|
|||
{
|
||||
return $output;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get url for redirection
|
||||
* @return string redirect_url
|
||||
* */
|
||||
function getRedirectUrl()
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRedirectUrl()
|
||||
{
|
||||
return $this->get('redirect_url');
|
||||
}
|
||||
|
|
@ -98,31 +163,36 @@ class ModuleObject extends BaseObject
|
|||
* Set the template path for refresh.html
|
||||
* refresh.html is executed as a result of method execution
|
||||
* Tpl as the common run of the refresh.html ..
|
||||
* @return void
|
||||
* */
|
||||
function setRefreshPage()
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRefreshPage()
|
||||
{
|
||||
$this->setTemplatePath('./common/tpl');
|
||||
$this->setTemplateFile('refresh');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the action name
|
||||
*
|
||||
* @param string $act
|
||||
* @return void
|
||||
* */
|
||||
function setAct($act)
|
||||
* @return $this
|
||||
*/
|
||||
public function setAct($act)
|
||||
{
|
||||
$this->act = $act;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set module information
|
||||
*
|
||||
* @param object $module_info object containing module information
|
||||
* @param object $xml_info object containing module description
|
||||
* @return void
|
||||
* */
|
||||
function setModuleInfo($module_info, $xml_info)
|
||||
* @return $this
|
||||
*/
|
||||
public function setModuleInfo($module_info, $xml_info)
|
||||
{
|
||||
// Set default variables
|
||||
$this->mid = $module_info->mid;
|
||||
|
|
@ -131,7 +201,7 @@ class ModuleObject extends BaseObject
|
|||
$this->origin_module_info = $module_info;
|
||||
$this->xml_info = $xml_info;
|
||||
$this->skin_vars = $module_info->skin_vars;
|
||||
$this->module_config = getModel('module')->getModuleConfig($this->module, $module_info->site_srl);
|
||||
$this->module_config = ModuleModel::getInstance()->getModuleConfig($this->module, $module_info->site_srl);
|
||||
|
||||
// Set privileges(granted) information
|
||||
if($this->setPrivileges() !== true)
|
||||
|
|
@ -167,21 +237,24 @@ class ModuleObject extends BaseObject
|
|||
$this->stop($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set privileges(granted) information of current user and check permission of current module
|
||||
* @return boolean success : true, fail : false
|
||||
* */
|
||||
function setPrivileges()
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setPrivileges()
|
||||
{
|
||||
if(Context::get('logged_info')->is_admin !== 'Y')
|
||||
{
|
||||
// Get privileges(granted) information for target module by <permission check> of module.xml
|
||||
if(($permission_check = $this->xml_info->permission_check->{$this->act}) && $permission_check->key)
|
||||
if(($permission = $this->xml_info->action->{$this->act}->permission) && $permission->check_var)
|
||||
{
|
||||
// Check parameter
|
||||
if(empty($check_module_srl = trim(Context::get($permission_check->key))))
|
||||
if(empty($check_module_srl = trim(Context::get($permission->check_var))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -204,7 +277,7 @@ class ModuleObject extends BaseObject
|
|||
foreach($check_module_srl as $target_srl)
|
||||
{
|
||||
// Get privileges(granted) information of current user for target module
|
||||
if(($grant = getModel('module')->getPrivilegesBySrl($target_srl, $permission_check->type)) === false)
|
||||
if(($grant = ModuleModel::getInstance()->getPrivilegesBySrl($target_srl, $permission->check_type)) === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -223,7 +296,7 @@ class ModuleObject extends BaseObject
|
|||
if(!isset($grant))
|
||||
{
|
||||
// Get privileges(granted) information of current user for current module
|
||||
$grant = getModel('module')->getGrant($this->module_info, Context::get('logged_info'), $this->xml_info);
|
||||
$grant = ModuleModel::getInstance()->getGrant($this->module_info, Context::get('logged_info'), $this->xml_info);
|
||||
|
||||
// Check permission
|
||||
if($this->checkPermission($grant) !== true)
|
||||
|
|
@ -248,11 +321,12 @@ class ModuleObject extends BaseObject
|
|||
|
||||
/**
|
||||
* Check permission
|
||||
*
|
||||
* @param object $grant privileges(granted) information of user
|
||||
* @param object $member_info member information
|
||||
* @return boolean success : true, fail : false
|
||||
* */
|
||||
function checkPermission($grant = null, $member_info = null)
|
||||
* @return bool
|
||||
*/
|
||||
public function checkPermission($grant = null, $member_info = null)
|
||||
{
|
||||
// Get logged-in member information
|
||||
if(!$member_info)
|
||||
|
|
@ -263,7 +337,7 @@ class ModuleObject extends BaseObject
|
|||
// Get privileges(granted) information of the member for current module
|
||||
if(!$grant)
|
||||
{
|
||||
$grant = getModel('module')->getGrant($this->module_info, $member_info, $this->xml_info);
|
||||
$grant = ModuleModel::getGrant($this->module_info, $member_info, $this->xml_info);
|
||||
}
|
||||
|
||||
// If an administrator, Pass
|
||||
|
|
@ -273,7 +347,7 @@ class ModuleObject extends BaseObject
|
|||
}
|
||||
|
||||
// Get permission types(guest, member, manager, root) of the currently requested action
|
||||
$permission = $this->xml_info->permission->{$this->act};
|
||||
$permission = $this->xml_info->action->{$this->act}->permission->target ?: $this->xml_info->permission->{$this->act};
|
||||
|
||||
// If admin action, set default permission
|
||||
if(empty($permission) && stripos($this->act, 'admin') !== false)
|
||||
|
|
@ -306,17 +380,17 @@ class ModuleObject extends BaseObject
|
|||
if(Context::get('is_logged') && isset($type[2]))
|
||||
{
|
||||
// Manager privilege of the member is found by search all modules, Pass
|
||||
if($type[2] == 'all' && getModel('module')->findManagerPrivilege($member_info) !== false)
|
||||
if($type[2] == 'all' && ModuleModel::findManagerPrivilege($member_info) !== false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Manager privilege of the member is found by search same module as this module, Pass
|
||||
else if($type[2] == 'same' && getModel('module')->findManagerPrivilege($member_info, $this->module) !== false)
|
||||
elseif($type[2] == 'same' && ModuleModel::findManagerPrivilege($member_info, $this->module) !== false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Manager privilege of the member is found by search same module as the module, Pass
|
||||
else if(getModel('module')->findManagerPrivilege($member_info, $type[2]) !== false)
|
||||
elseif(ModuleModel::findManagerPrivilege($member_info, $type[2]) !== false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -348,11 +422,12 @@ class ModuleObject extends BaseObject
|
|||
}
|
||||
|
||||
/**
|
||||
* set the stop_proc and approprate message for msg_code
|
||||
* Stop processing this module instance.
|
||||
*
|
||||
* @param string $msg_code an error code
|
||||
* @return ModuleObject $this
|
||||
* */
|
||||
function stop($msg_code)
|
||||
*/
|
||||
public function stop($msg_code)
|
||||
{
|
||||
if($this->stop_proc !== true)
|
||||
{
|
||||
|
|
@ -385,35 +460,39 @@ class ModuleObject extends BaseObject
|
|||
|
||||
/**
|
||||
* set the file name of the template file
|
||||
*
|
||||
* @param string name of file
|
||||
* @return void
|
||||
* */
|
||||
function setTemplateFile($filename)
|
||||
* @return $this
|
||||
*/
|
||||
public function setTemplateFile($filename)
|
||||
{
|
||||
if(isset($filename) && substr_compare($filename, '.html', -5) !== 0)
|
||||
{
|
||||
$filename .= '.html';
|
||||
}
|
||||
$this->template_file = $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the directory path of the template directory
|
||||
*
|
||||
* @return string
|
||||
* */
|
||||
function getTemplateFile()
|
||||
*/
|
||||
public function getTemplateFile()
|
||||
{
|
||||
return $this->template_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the directory path of the template directory
|
||||
*
|
||||
* @param string path of template directory.
|
||||
* @return void
|
||||
* */
|
||||
function setTemplatePath($path)
|
||||
* @return $this
|
||||
*/
|
||||
public function setTemplatePath($path)
|
||||
{
|
||||
if(!$path) return;
|
||||
if(!$path) return $this;
|
||||
|
||||
if((strlen($path) >= 1 && substr_compare($path, '/', 0, 1) !== 0) && (strlen($path) >= 2 && substr_compare($path, './', 0, 2) !== 0))
|
||||
{
|
||||
|
|
@ -425,70 +504,80 @@ class ModuleObject extends BaseObject
|
|||
$path .= '/';
|
||||
}
|
||||
$this->template_path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the directory path of the template directory
|
||||
*
|
||||
* @return string
|
||||
* */
|
||||
function getTemplatePath()
|
||||
*/
|
||||
public function getTemplatePath()
|
||||
{
|
||||
return $this->template_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the file name of the temporarily modified by admin
|
||||
*
|
||||
* @param string name of file
|
||||
* @return void
|
||||
* */
|
||||
function setEditedLayoutFile($filename)
|
||||
* @return $this
|
||||
*/
|
||||
public function setEditedLayoutFile($filename)
|
||||
{
|
||||
if(!$filename) return;
|
||||
if(!$filename) return $this;
|
||||
|
||||
if(substr_compare($filename, '.html', -5) !== 0)
|
||||
{
|
||||
$filename .= '.html';
|
||||
}
|
||||
$this->edited_layout_file = $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* retreived the file name of edited_layout_file
|
||||
*
|
||||
* @return string
|
||||
* */
|
||||
function getEditedLayoutFile()
|
||||
*/
|
||||
public function getEditedLayoutFile()
|
||||
{
|
||||
return $this->edited_layout_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the file name of the layout file
|
||||
*
|
||||
* @param string name of file
|
||||
* @return void
|
||||
* */
|
||||
function setLayoutFile($filename)
|
||||
* @return $this
|
||||
*/
|
||||
public function setLayoutFile($filename)
|
||||
{
|
||||
if($filename && substr_compare($filename, '.html', -5) !== 0)
|
||||
{
|
||||
$filename .= '.html';
|
||||
}
|
||||
$this->layout_file = $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the file name of the layout file
|
||||
*
|
||||
* @return string
|
||||
* */
|
||||
function getLayoutFile()
|
||||
*/
|
||||
public function getLayoutFile()
|
||||
{
|
||||
return $this->layout_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the directory path of the layout directory
|
||||
*
|
||||
* @param string path of layout directory.
|
||||
* */
|
||||
function setLayoutPath($path)
|
||||
* @return $this
|
||||
*/
|
||||
public function setLayoutPath($path)
|
||||
{
|
||||
if(!$path) return;
|
||||
|
||||
|
|
@ -501,22 +590,24 @@ class ModuleObject extends BaseObject
|
|||
$path .= '/';
|
||||
}
|
||||
$this->layout_path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the directory path of the layout directory
|
||||
*
|
||||
* @return string
|
||||
* */
|
||||
function getLayoutPath($layout_name = "", $layout_type = "P")
|
||||
*/
|
||||
public function getLayoutPath($layout_name = "", $layout_type = "P")
|
||||
{
|
||||
return $this->layout_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* excute the member method specified by $act variable
|
||||
* @return boolean true : success false : fail
|
||||
* */
|
||||
function proc()
|
||||
* @return bool
|
||||
*/
|
||||
public function proc()
|
||||
{
|
||||
// pass if stop_proc is true
|
||||
if($this->stop_proc)
|
||||
|
|
@ -538,7 +629,7 @@ class ModuleObject extends BaseObject
|
|||
|
||||
// execute an addon(call called_position as before_module_proc)
|
||||
$called_position = 'before_module_proc';
|
||||
$oAddonController = getController('addon');
|
||||
$oAddonController = AddonController::getInstance();
|
||||
$addon_file = $oAddonController->getCacheFilePath($is_mobile ? "mobile" : "pc");
|
||||
if(FileHandler::exists($addon_file)) include($addon_file);
|
||||
|
||||
|
|
@ -558,7 +649,6 @@ class ModuleObject extends BaseObject
|
|||
// Set module skin
|
||||
if(isset($this->module_info->skin) && $this->module_info->module === $this->module && strpos($this->act, 'Admin') === false)
|
||||
{
|
||||
$oModuleModel = getModel('module');
|
||||
$skin_type = $is_mobile ? 'M' : 'P';
|
||||
$skin_key = $is_mobile ? 'mskin' : 'skin';
|
||||
$skin_dir = $is_mobile ? 'm.skins' : 'skins';
|
||||
|
|
@ -570,7 +660,7 @@ class ModuleObject extends BaseObject
|
|||
{
|
||||
if($module_skin === '/USE_DEFAULT/')
|
||||
{
|
||||
$module_skin = $oModuleModel->getModuleDefaultSkin($this->module, $skin_type);
|
||||
$module_skin = ModuleModel::getModuleDefaultSkin($this->module, $skin_type);
|
||||
$this->module_info->{$skin_key} = $module_skin;
|
||||
}
|
||||
if($module_skin === '/USE_RESPONSIVE/')
|
||||
|
|
@ -579,7 +669,7 @@ class ModuleObject extends BaseObject
|
|||
$module_skin = $this->module_info->skin ?: '/USE_DEFAULT/';
|
||||
if($module_skin === '/USE_DEFAULT/')
|
||||
{
|
||||
$module_skin = $oModuleModel->getModuleDefaultSkin($this->module, 'P');
|
||||
$module_skin = ModuleModel::getModuleDefaultSkin($this->module, 'P');
|
||||
}
|
||||
}
|
||||
if(!is_dir(sprintf('%s%s/%s', $this->module_path, $skin_dir, $module_skin)))
|
||||
|
|
@ -590,7 +680,7 @@ class ModuleObject extends BaseObject
|
|||
}
|
||||
|
||||
// Set skin variable
|
||||
$oModuleModel->syncSkinInfoToModuleInfo($this->module_info);
|
||||
ModuleModel::syncSkinInfoToModuleInfo($this->module_info);
|
||||
Context::set('module_info', $this->module_info);
|
||||
}
|
||||
|
||||
|
|
@ -642,7 +732,7 @@ class ModuleObject extends BaseObject
|
|||
|
||||
// execute an addon(call called_position as after_module_proc)
|
||||
$called_position = 'after_module_proc';
|
||||
$oAddonController = getController('addon');
|
||||
$oAddonController = AddonController::getInstance();
|
||||
$addon_file = $oAddonController->getCacheFilePath($is_mobile ? "mobile" : "pc");
|
||||
if(FileHandler::exists($addon_file)) include($addon_file);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,30 +8,29 @@
|
|||
*/
|
||||
class BaseObject
|
||||
{
|
||||
|
||||
/**
|
||||
* Error code. If `0`, it is not an error.
|
||||
* @var int
|
||||
*/
|
||||
var $error = 0;
|
||||
public $error = 0;
|
||||
|
||||
/**
|
||||
* Error message. If `success`, it is not an error.
|
||||
* @var string
|
||||
*/
|
||||
var $message = 'success';
|
||||
public $message = 'success';
|
||||
|
||||
/**
|
||||
* An additional variable
|
||||
* @var array
|
||||
*/
|
||||
var $variables = array();
|
||||
public $variables = array();
|
||||
|
||||
/**
|
||||
* http status code.
|
||||
* @var int
|
||||
*/
|
||||
var $httpStatusCode = 200;
|
||||
public $httpStatusCode = 200;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
|
@ -40,7 +39,7 @@ class BaseObject
|
|||
* @param string $message Error message
|
||||
* @return void
|
||||
*/
|
||||
function __construct($error = 0, $message = 'success')
|
||||
public function __construct($error = 0, $message = 'success')
|
||||
{
|
||||
$this->setError($error);
|
||||
$this->setMessage($message);
|
||||
|
|
@ -81,7 +80,7 @@ class BaseObject
|
|||
* @param int|strong $error error code or message
|
||||
* @return $this
|
||||
*/
|
||||
function setError($error = 0)
|
||||
public function setError($error = 0)
|
||||
{
|
||||
// If the first argument is an integer, treat it as an error code. Otherwise, treat it as an error message.
|
||||
$args = func_get_args();
|
||||
|
|
@ -113,7 +112,7 @@ class BaseObject
|
|||
*
|
||||
* @return int Returns an error code
|
||||
*/
|
||||
function getError()
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
|
@ -124,9 +123,9 @@ class BaseObject
|
|||
* @param int $code HTTP status code. Default value is `200` that means successful
|
||||
* @return $this
|
||||
*/
|
||||
function setHttpStatusCode($code = 200)
|
||||
public function setHttpStatusCode($code = 200)
|
||||
{
|
||||
$this->httpStatusCode = (int) $code;
|
||||
$this->httpStatusCode = (int)$code;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +134,7 @@ class BaseObject
|
|||
*
|
||||
* @return int Returns HTTP status code
|
||||
*/
|
||||
function getHttpStatusCode()
|
||||
public function getHttpStatusCode()
|
||||
{
|
||||
return $this->httpStatusCode;
|
||||
}
|
||||
|
|
@ -147,7 +146,7 @@ class BaseObject
|
|||
* @param string $type type of message (error, info, update)
|
||||
* @return $this
|
||||
*/
|
||||
function setMessage($message = 'success', $type = null)
|
||||
public function setMessage($message = 'success', $type = null)
|
||||
{
|
||||
$this->message = lang($message);
|
||||
if($type !== null)
|
||||
|
|
@ -162,7 +161,7 @@ class BaseObject
|
|||
*
|
||||
* @return string Returns message
|
||||
*/
|
||||
function getMessage()
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
|
@ -172,9 +171,9 @@ class BaseObject
|
|||
* @param string $type type of message (error, info, update)
|
||||
* @return $this
|
||||
* */
|
||||
function setMessageType($type)
|
||||
public function setMessageType($type)
|
||||
{
|
||||
$this->add('message_type', $type);
|
||||
$this->variables['message_type'] = strval($type);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +181,7 @@ class BaseObject
|
|||
* get type of message
|
||||
* @return string $type
|
||||
* */
|
||||
function getMessageType()
|
||||
public function getMessageType()
|
||||
{
|
||||
$type = $this->get('message_type');
|
||||
$typeList = array('error' => 1, 'info' => 1, 'update' => 1);
|
||||
|
|
@ -200,19 +199,28 @@ class BaseObject
|
|||
* @param mixed $val A value for the variable
|
||||
* @return $this
|
||||
*/
|
||||
function add($key, $val)
|
||||
public function set($key, $val)
|
||||
{
|
||||
$this->variables[$key] = $val;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set multiple key/value pairs as an additional variables
|
||||
* Alias to set().
|
||||
*/
|
||||
public function add($key, $val)
|
||||
{
|
||||
$this->variables[$key] = $val;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set multiple key/value pairs as additional variables
|
||||
*
|
||||
* @param object|array $vars Either object or array containg key/value pairs to be added
|
||||
* @return $this
|
||||
*/
|
||||
function adds($vars)
|
||||
public function sets($vars)
|
||||
{
|
||||
if(is_object($vars))
|
||||
{
|
||||
|
|
@ -228,13 +236,21 @@ class BaseObject
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias to sets().
|
||||
*/
|
||||
public function adds($vars)
|
||||
{
|
||||
return $this->sets($vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to retrieve a corresponding value to a given key
|
||||
*
|
||||
* @param string $key
|
||||
* @return string Returns value to a given key
|
||||
*/
|
||||
function get($key)
|
||||
public function get($key)
|
||||
{
|
||||
return $this->variables[$key];
|
||||
}
|
||||
|
|
@ -244,7 +260,7 @@ class BaseObject
|
|||
*
|
||||
* @return object Returns an object containing key/value pairs
|
||||
*/
|
||||
function gets()
|
||||
public function gets()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$output = new stdClass();
|
||||
|
|
@ -260,7 +276,7 @@ class BaseObject
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getVariables()
|
||||
public function getVariables()
|
||||
{
|
||||
return $this->variables;
|
||||
}
|
||||
|
|
@ -270,14 +286,9 @@ class BaseObject
|
|||
*
|
||||
* @return object
|
||||
*/
|
||||
function getObjectVars()
|
||||
public function getObjectVars()
|
||||
{
|
||||
$output = new stdClass();
|
||||
foreach($this->variables as $key => $val)
|
||||
{
|
||||
$output->{$key} = $val;
|
||||
}
|
||||
return $output;
|
||||
return (object)($this->variables);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -285,7 +296,7 @@ class BaseObject
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function unset($key)
|
||||
public function unset($key)
|
||||
{
|
||||
unset($this->variables[$key]);
|
||||
}
|
||||
|
|
@ -295,7 +306,7 @@ class BaseObject
|
|||
*
|
||||
* @return bool Retruns true : error isn't 0 or false : otherwise.
|
||||
*/
|
||||
function toBool()
|
||||
public function toBool()
|
||||
{
|
||||
// TODO This method is misleading in that it returns true if error is 0, which should be true in boolean representation.
|
||||
return ($this->error == 0);
|
||||
|
|
@ -306,7 +317,7 @@ class BaseObject
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
function toBoolean()
|
||||
public function toBoolean()
|
||||
{
|
||||
return $this->toBool();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,114 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* File containing the XE 1.5 XmlQueryParserClass
|
||||
*/
|
||||
if(!defined('__XE_LOADED_XML_CLASS__'))
|
||||
{
|
||||
define('__XE_LOADED_XML_CLASS__', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* New XmlQueryParser class <br />
|
||||
* Parses XE XML query files
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml
|
||||
* @version 0.1
|
||||
*/
|
||||
class XmlQueryParser extends XmlParser
|
||||
{
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @return void
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create XmlQueryParser instance for Singleton
|
||||
*
|
||||
* @return XmlQueryParser object
|
||||
*/
|
||||
function &getInstance()
|
||||
{
|
||||
static $theInstance = NULL;
|
||||
if(!isset($theInstance))
|
||||
{
|
||||
$theInstance = new XmlQueryParser();
|
||||
}
|
||||
return $theInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an XML query file
|
||||
*
|
||||
* 1. Read xml file<br />
|
||||
* 2. Check the action<br />
|
||||
* 3. Parse and write cache file <br />
|
||||
*
|
||||
* @param $query_id
|
||||
* @param $xml_file
|
||||
* @param $cache_file
|
||||
*
|
||||
* @return QueryParser object
|
||||
*/
|
||||
function &parse_xml_query($query_id, $xml_file, $cache_file)
|
||||
{
|
||||
// Read xml file
|
||||
$xml_obj = $this->getXmlFileContent($xml_file);
|
||||
|
||||
// insert, update, delete, select action
|
||||
$action = strtolower($xml_obj->query->attrs->action);
|
||||
if(!$action)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Write query cache file
|
||||
$parser = new QueryParser($xml_obj->query);
|
||||
FileHandler::writeFile($cache_file, $parser->toString());
|
||||
|
||||
return $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override for parent "parse" method
|
||||
*
|
||||
* @param null $query_id
|
||||
* @param null $xml_file
|
||||
* @param null $cache_file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function parse($query_id = NULL, $xml_file = NULL, $cache_file = NULL)
|
||||
{
|
||||
$this->parse_xml_query($query_id, $xml_file, $cache_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns XML file contents as an object
|
||||
* or NULL in case of error
|
||||
*
|
||||
* @param $xml_file
|
||||
* @return array|NULL
|
||||
*/
|
||||
function getXmlFileContent($xml_file)
|
||||
{
|
||||
$buff = FileHandler::readFile($xml_file);
|
||||
$xml_obj = parent::parse($buff);
|
||||
if(!$xml_obj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
unset($buff);
|
||||
return $xml_obj;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file XmlQueryParser.class.php */
|
||||
/* Location: ./classes/xml/XmlQueryParser.class.php */
|
||||
|
|
@ -1,333 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* File containing the DBParser class
|
||||
*/
|
||||
|
||||
/**
|
||||
* Escapes query statements: <br />
|
||||
* - column names: member.member_srl => "member"."member_srl" <br />
|
||||
* - expressions: SUM(member.member_srl) => SUM("member"."member_srl") <br />
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery
|
||||
* @version 0.1
|
||||
*/
|
||||
class DBParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Character for escape target value on the left
|
||||
*
|
||||
* For example, in CUBRID left and right escape
|
||||
* chars are the same, the double quote - " <br />
|
||||
* But for SQL Server, the escape is made with
|
||||
* [double brackets], so the left and right char differ
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $escape_char_left;
|
||||
|
||||
/**
|
||||
* Character for escape target value on the right
|
||||
*
|
||||
* For example, in CUBRID left and right escape
|
||||
* chars are the same, the double quote - " <br />
|
||||
* But for SQL Server, the escape is made with
|
||||
* [double brackets], so the left and right char differ
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $escape_char_right;
|
||||
|
||||
/**
|
||||
* Table prefix string
|
||||
*
|
||||
* Default is "xe_"
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $table_prefix;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $escape_char_left
|
||||
* @param string $escape_char_right
|
||||
* @param string $table_prefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __construct($escape_char_left, $escape_char_right = "", $table_prefix = "xe_")
|
||||
{
|
||||
$this->escape_char_left = $escape_char_left;
|
||||
if($escape_char_right !== "")
|
||||
{
|
||||
$this->escape_char_right = $escape_char_right;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->escape_char_right = $escape_char_left;
|
||||
}
|
||||
$this->table_prefix = $table_prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get escape character
|
||||
*
|
||||
* @param string $leftOrRight left or right
|
||||
* @return string
|
||||
*/
|
||||
function getEscapeChar($leftOrRight)
|
||||
{
|
||||
if($leftOrRight === 'left')
|
||||
{
|
||||
return $this->escape_char_left;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->escape_char_right;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape the value
|
||||
*
|
||||
* @param mixed $name
|
||||
* @return string
|
||||
*/
|
||||
function escape($name)
|
||||
{
|
||||
return $this->escape_char_left . $name . $this->escape_char_right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape the string value
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
function escapeString($name)
|
||||
{
|
||||
return "'" . $this->escapeStringValue($name) . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape the string value
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
function escapeStringValue($value)
|
||||
{
|
||||
if($value == "*")
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
if(is_string($value))
|
||||
{
|
||||
return $value = str_replace("'", "''", $value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return table full name
|
||||
*
|
||||
* @param string $name table name without table prefix
|
||||
*
|
||||
* @return string table full name with table prefix
|
||||
*/
|
||||
function parseTableName($name)
|
||||
{
|
||||
return $this->table_prefix . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return column name after escape
|
||||
*
|
||||
* @param string $name column name before escape
|
||||
*
|
||||
* @return string column name after escape
|
||||
*/
|
||||
function parseColumnName($name)
|
||||
{
|
||||
return $this->escapeColumn($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape column name
|
||||
*
|
||||
* @param string $column_name
|
||||
* @return string column name with db name
|
||||
*/
|
||||
function escapeColumn($column_name)
|
||||
{
|
||||
if($this->isUnqualifiedColumnName($column_name))
|
||||
{
|
||||
return $this->escape($column_name);
|
||||
}
|
||||
if($this->isQualifiedColumnName($column_name))
|
||||
{
|
||||
list($table, $column) = explode('.', $column_name);
|
||||
// $table can also be an alias, so the prefix should not be added
|
||||
return $this->escape($table) . '.' . $this->escape($column);
|
||||
//return $this->escape($this->parseTableName($table)).'.'.$this->escape($column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a given column name is unqualified
|
||||
*
|
||||
* Ex: "member_srl" -> unqualified <br />
|
||||
* "member"."member_srl" -> qualified
|
||||
*
|
||||
* @param string $column_name
|
||||
* @return bool
|
||||
*/
|
||||
function isUnqualifiedColumnName($column_name)
|
||||
{
|
||||
if(strpos($column_name, '.') === FALSE && strpos($column_name, '(') === FALSE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a given column name is qualified
|
||||
*
|
||||
* Ex: "member_srl" -> unqualified <br />
|
||||
* "member"."member_srl" -> qualified
|
||||
*
|
||||
* @param string $column_name
|
||||
* @return bool
|
||||
*/
|
||||
function isQualifiedColumnName($column_name)
|
||||
{
|
||||
if(strpos($column_name, '.') !== FALSE && strpos($column_name, '(') === FALSE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a query expression
|
||||
*
|
||||
* An expression can be: <br />
|
||||
* <ul>
|
||||
* <li> a column name: "member_srl" or "xe_member"."member_srl"
|
||||
* <li> an expression:
|
||||
* <ul>
|
||||
* <li> LEFT(UPPER("content")) <br />
|
||||
* <li> readed_count + voted_count <br />
|
||||
* <li> CAST(regdate as DATE) </li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param $column_name
|
||||
* @return string
|
||||
*/
|
||||
function parseExpression($column_name)
|
||||
{
|
||||
$functions = preg_split('/([\+\-\*\/\ ])/', $column_name, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
foreach($functions as $k => $v)
|
||||
{
|
||||
$function = &$functions[$k];
|
||||
if(strlen($function) == 1)
|
||||
{
|
||||
continue; // skip delimiters
|
||||
}
|
||||
$pos = strrpos("(", $function);
|
||||
$matches = preg_split('/([a-zA-Z0-9_*]+)/', $function, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
$total_brackets = substr_count($function, "(");
|
||||
$brackets = 0;
|
||||
foreach($matches as $i => $j)
|
||||
{
|
||||
$match = &$matches[$i];
|
||||
if($match == '(')
|
||||
{
|
||||
$brackets++;
|
||||
continue;
|
||||
}
|
||||
if(strpos($match, ')') !== FALSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(in_array($match, array(',', '.')))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if($brackets == $total_brackets)
|
||||
{
|
||||
if(!is_numeric($match) && !in_array(strtoupper($match), array('UNSIGNED', 'INTEGER', 'AS')) && !preg_match('/^[A-Z]+$/', $match))
|
||||
{
|
||||
$match = $this->escapeColumnExpression($match);
|
||||
}
|
||||
}
|
||||
}
|
||||
$function = implode('', $matches);
|
||||
}
|
||||
return implode('', $functions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given argument is an asterisk
|
||||
*
|
||||
* @param string $column_name
|
||||
* @return bool
|
||||
*/
|
||||
function isStar($column_name)
|
||||
{
|
||||
if(substr($column_name, -1) == '*')
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if expression is an aggregate star function
|
||||
* like count(*)
|
||||
*
|
||||
* @param string $column_name
|
||||
* @return bool
|
||||
*/
|
||||
function isStarFunction($column_name)
|
||||
{
|
||||
if(strpos($column_name, "(*)") !== FALSE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return column name after escape
|
||||
* @param string $column_name
|
||||
* @return string
|
||||
*/
|
||||
function escapeColumnExpression($column_name)
|
||||
{
|
||||
if($this->isStar($column_name))
|
||||
{
|
||||
return $column_name;
|
||||
}
|
||||
if($this->isStarFunction($column_name))
|
||||
{
|
||||
return $column_name;
|
||||
}
|
||||
if(stripos($column_name, 'distinct') !== FALSE)
|
||||
{
|
||||
return $column_name;
|
||||
}
|
||||
return $this->escapeColumn($column_name);
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file DBParser.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/DBParser.class.php */
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* File containing the QueryParser class
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parses an XML Object and returns a string used for generating the PHP cache file <br />
|
||||
* The XML Object structure must be the one defined in the XmlParser class
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery
|
||||
* @version 0.1
|
||||
*/
|
||||
class QueryParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Property containing the associated QueryTag object
|
||||
*
|
||||
* @var QueryTag object
|
||||
*/
|
||||
var $queryTag;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param object $query XML object obtained after reading the XML Query file
|
||||
* @param bool $isSubQuery
|
||||
* @return void
|
||||
*/
|
||||
function __construct($query = NULL, $isSubQuery = FALSE)
|
||||
{
|
||||
if($query)
|
||||
{
|
||||
$this->queryTag = new QueryTag($query, $isSubQuery);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns table information
|
||||
*
|
||||
* Used for finding column type info (string/numeric) <br />
|
||||
* Obtains the table info from XE's XML schema files
|
||||
*
|
||||
* @param object $query_id
|
||||
* @param bool $table_name
|
||||
* @return array
|
||||
*/
|
||||
function getTableInfo($query_id, $table_name)
|
||||
{
|
||||
$column_type = array();
|
||||
$module = '';
|
||||
|
||||
$id_args = explode('.', $query_id);
|
||||
if(count($id_args) == 2)
|
||||
{
|
||||
$target = 'modules';
|
||||
$module = $id_args[0];
|
||||
$id = $id_args[1];
|
||||
}
|
||||
else if(count($id_args) == 3)
|
||||
{
|
||||
$target = $id_args[0];
|
||||
$targetList = array('modules' => 1, 'addons' => 1, 'widgets' => 1);
|
||||
if(!isset($targetList[$target]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
$module = $id_args[1];
|
||||
$id = $id_args[2];
|
||||
}
|
||||
|
||||
// get column properties from the table
|
||||
$table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $module, $table_name);
|
||||
if(!file_exists($table_file))
|
||||
{
|
||||
$searched_list = FileHandler::readDir(_XE_PATH_ . 'modules');
|
||||
$searched_count = count($searched_list);
|
||||
for($i = 0; $i < $searched_count; $i++)
|
||||
{
|
||||
$table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $searched_list[$i], $table_name);
|
||||
if(file_exists($table_file))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(file_exists($table_file))
|
||||
{
|
||||
$table_xml = FileHandler::readFile($table_file);
|
||||
$xml_parser = new XmlParser();
|
||||
$table_obj = $xml_parser->parse($table_xml);
|
||||
if($table_obj->table)
|
||||
{
|
||||
if(isset($table_obj->table->column) && !is_array($table_obj->table->column))
|
||||
{
|
||||
$table_obj->table->column = array($table_obj->table->column);
|
||||
}
|
||||
|
||||
foreach($table_obj->table->column as $k => $v)
|
||||
{
|
||||
$column_type[$v->attrs->name] = $v->attrs->type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $column_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents for the query cache file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
return "<?php if(!defined('__XE__')) exit();\n"
|
||||
. $this->queryTag->toString()
|
||||
. 'return $query; ?>';
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file QueryParser.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/QueryParser.class.php */
|
||||
|
|
@ -1,396 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Argument class
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/xml/xmlquery/argument
|
||||
* @version 0.1
|
||||
*/
|
||||
class Argument
|
||||
{
|
||||
|
||||
/**
|
||||
* argument value
|
||||
* @var mixed
|
||||
*/
|
||||
var $value;
|
||||
|
||||
/**
|
||||
* argument name
|
||||
* @var string
|
||||
*/
|
||||
var $name;
|
||||
|
||||
/**
|
||||
* argument type
|
||||
* @var string
|
||||
*/
|
||||
var $type;
|
||||
|
||||
/**
|
||||
* result of argument type check
|
||||
* @var bool
|
||||
*/
|
||||
var $isValid;
|
||||
|
||||
/**
|
||||
* error message
|
||||
* @var BaseObject
|
||||
*/
|
||||
var $errorMessage;
|
||||
|
||||
/**
|
||||
* column operation
|
||||
*/
|
||||
var $column_operation;
|
||||
|
||||
/**
|
||||
* Check if arg value is user submnitted or default
|
||||
* @var mixed
|
||||
*/
|
||||
var $uses_default_value;
|
||||
|
||||
/**
|
||||
* Caches escaped and toString value so that the parsing won't happen multiple times
|
||||
* @var mixed
|
||||
*/
|
||||
var $_value; //
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function __construct($name, $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->name = $name;
|
||||
$this->isValid = TRUE;
|
||||
}
|
||||
|
||||
function getType()
|
||||
{
|
||||
if(isset($this->type))
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
if(is_string($this->value))
|
||||
{
|
||||
return 'column_name';
|
||||
}
|
||||
|
||||
return 'number';
|
||||
}
|
||||
|
||||
function setColumnType($value)
|
||||
{
|
||||
$this->type = $value;
|
||||
}
|
||||
|
||||
function setColumnOperation($operation)
|
||||
{
|
||||
$this->column_operation = $operation;
|
||||
}
|
||||
|
||||
function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
function getValue()
|
||||
{
|
||||
if(!isset($this->_value))
|
||||
{
|
||||
$value = $this->getEscapedValue();
|
||||
$this->_value = $this->toString($value);
|
||||
}
|
||||
return $this->_value;
|
||||
}
|
||||
|
||||
function getPureValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
function getColumnOperation()
|
||||
{
|
||||
return $this->column_operation;
|
||||
}
|
||||
|
||||
function getEscapedValue()
|
||||
{
|
||||
return $this->escapeValue($this->value);
|
||||
}
|
||||
|
||||
function getUnescapedValue()
|
||||
{
|
||||
if($this->value === 'null')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* mixed value to string
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
function toString($value)
|
||||
{
|
||||
if(is_array($value))
|
||||
{
|
||||
if(count($value) === 0)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
if(count($value) === 1 && $value[0] === '')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
return '(' . implode(',', $value) . ')';
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* escape value
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
function escapeValue($value)
|
||||
{
|
||||
$column_type = $this->getType();
|
||||
if($column_type == 'column_name')
|
||||
{
|
||||
$dbParser = DB::getParser();
|
||||
return $dbParser->parseExpression($value);
|
||||
}
|
||||
if(!isset($value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$columnTypeList = array('date' => 1, 'varchar' => 1, 'char' => 1, 'text' => 1, 'bigtext' => 1);
|
||||
if(isset($columnTypeList[$column_type]))
|
||||
{
|
||||
if(!is_array($value))
|
||||
{
|
||||
$value = $this->_escapeStringValue($value);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($value as $key=>$val)
|
||||
{
|
||||
$value[$key] = $this->_escapeStringValue($val);
|
||||
}
|
||||
}
|
||||
}
|
||||
if($this->uses_default_value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
if($column_type == 'number')
|
||||
{
|
||||
if(is_array($value))
|
||||
{
|
||||
foreach($value AS $key => $val)
|
||||
{
|
||||
if(isset($val) && $val !== '')
|
||||
{
|
||||
$value[$key] = (int) $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = (int) $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* escape string value
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
function _escapeStringValue($value)
|
||||
{
|
||||
// Remove non-utf8 chars.
|
||||
$regex = '@((?:[\x00-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}){1,100})|([\xF0-\xF7][\x80-\xBF]{3})|([\x80-\xBF])|([\xC0-\xFF])@x';
|
||||
|
||||
$value = preg_replace_callback($regex, array($this, 'utf8Replacer'), $value);
|
||||
$db = DB::getInstance();
|
||||
$value = $db->addQuotes($value);
|
||||
return '\'' . $value . '\'';
|
||||
}
|
||||
|
||||
function utf8Replacer($captures)
|
||||
{
|
||||
if(strlen($captures[1]))
|
||||
{
|
||||
// Valid byte sequence. Return unmodified.
|
||||
return $captures[1];
|
||||
}
|
||||
else if(strlen($captures[2]))
|
||||
{
|
||||
// Remove user defined area
|
||||
if("\xF3\xB0\x80\x80" <= $captures[2])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
return $captures[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function isValid()
|
||||
{
|
||||
return $this->isValid;
|
||||
}
|
||||
|
||||
function isColumnName()
|
||||
{
|
||||
$type = $this->getType();
|
||||
$value = $this->getUnescapedValue();
|
||||
if($type == 'column_name')
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if($type == 'number' && is_null($value))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if($type == 'number' && !is_numeric($value) && $this->uses_default_value)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function getErrorMessage()
|
||||
{
|
||||
return $this->errorMessage;
|
||||
}
|
||||
|
||||
function ensureDefaultValue($default_value)
|
||||
{
|
||||
if($this->value === NULL || $this->value === '')
|
||||
{
|
||||
$this->value = $default_value;
|
||||
$this->uses_default_value = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check filter by filter type
|
||||
* @param string $filter_type
|
||||
* @return void
|
||||
*/
|
||||
function checkFilter($filter_type)
|
||||
{
|
||||
if(isset($this->value) && $this->value != '')
|
||||
{
|
||||
global $lang;
|
||||
$val = $this->value;
|
||||
$key = $this->name;
|
||||
switch($filter_type)
|
||||
{
|
||||
case 'email' :
|
||||
case 'email_address' :
|
||||
if(!preg_match('/^[\w-]+((?:\.|\+|\~)[\w-]+)*@[\w-]+(\.[\w-]+)+$/is', $val))
|
||||
{
|
||||
$this->isValid = FALSE;
|
||||
$this->errorMessage = new BaseObject(-1, sprintf($lang->filter->invalid_email, $lang->{$key} ? $lang->{$key} : $key));
|
||||
}
|
||||
break;
|
||||
case 'homepage' :
|
||||
if(!preg_match('/^(http|https)+(:\/\/)+[0-9a-z_-]+\.[^ ]+$/is', $val))
|
||||
{
|
||||
$this->isValid = FALSE;
|
||||
$this->errorMessage = new BaseObject(-1, sprintf($lang->filter->invalid_homepage, $lang->{$key} ? $lang->{$key} : $key));
|
||||
}
|
||||
break;
|
||||
case 'userid' :
|
||||
case 'user_id' :
|
||||
if(!preg_match('/^[a-zA-Z]+([_0-9a-zA-Z]+)*$/is', $val))
|
||||
{
|
||||
$this->isValid = FALSE;
|
||||
$this->errorMessage = new BaseObject(-1, sprintf($lang->filter->invalid_userid, $lang->{$key} ? $lang->{$key} : $key));
|
||||
}
|
||||
break;
|
||||
case 'number' :
|
||||
case 'numbers' :
|
||||
if(is_array($val))
|
||||
{
|
||||
$val = join(',', $val);
|
||||
}
|
||||
if(!preg_match('/^(-?)[0-9]+(,\-?[0-9]+)*$/is', $val))
|
||||
{
|
||||
$this->isValid = FALSE;
|
||||
$this->errorMessage = new BaseObject(-1, sprintf($lang->filter->invalid_number, $lang->{$key} ? $lang->{$key} : $key));
|
||||
}
|
||||
break;
|
||||
case 'alpha' :
|
||||
if(!preg_match('/^[a-z]+$/is', $val))
|
||||
{
|
||||
$this->isValid = FALSE;
|
||||
$this->errorMessage = new BaseObject(-1, sprintf($lang->filter->invalid_alpha, $lang->{$key} ? $lang->{$key} : $key));
|
||||
}
|
||||
break;
|
||||
case 'alpha_number' :
|
||||
if(!preg_match('/^[0-9a-z]+$/is', $val))
|
||||
{
|
||||
$this->isValid = FALSE;
|
||||
$this->errorMessage = new BaseObject(-1, sprintf($lang->filter->invalid_alpha_number, $lang->{$key} ? $lang->{$key} : $key));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkMaxLength($length)
|
||||
{
|
||||
if($this->value && (strlen($this->value) > $length))
|
||||
{
|
||||
global $lang;
|
||||
$this->isValid = FALSE;
|
||||
$key = $this->name;
|
||||
$this->errorMessage = new BaseObject(-1, sprintf($lang->filter->outofrange, $lang->{$key} ? $lang->{$key} : $key));
|
||||
}
|
||||
}
|
||||
|
||||
function checkMinLength($length)
|
||||
{
|
||||
if($this->value && (strlen($this->value) < $length))
|
||||
{
|
||||
global $lang;
|
||||
$this->isValid = FALSE;
|
||||
$key = $this->name;
|
||||
$this->errorMessage = new BaseObject(-1, sprintf($lang->filter->outofrange, $lang->{$key} ? $lang->{$key} : $key));
|
||||
}
|
||||
}
|
||||
|
||||
function checkNotNull()
|
||||
{
|
||||
if(!isset($this->value))
|
||||
{
|
||||
global $lang;
|
||||
$this->isValid = FALSE;
|
||||
$key = $this->name;
|
||||
$this->errorMessage = new BaseObject(-1, sprintf($lang->filter->isnull, $lang->{$key} ? $lang->{$key} : $key));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file Argument.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/argument/Argument.class.php */
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* ConditionArgument class
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/xml/xmlquery/argument
|
||||
* @version 0.1
|
||||
*/
|
||||
class ConditionArgument extends Argument
|
||||
{
|
||||
|
||||
/**
|
||||
* Operator keyword. for example 'in', 'notint', 'between'
|
||||
* @var string
|
||||
*/
|
||||
var $operation;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param string $operation
|
||||
* @return void
|
||||
*/
|
||||
function __construct($name, $value, $operation)
|
||||
{
|
||||
$operationList = array('in' => 1, 'notin' => 1, 'not_in' => 1, 'between' => 1);
|
||||
if(isset($value) && isset($operationList[$operation]) && !is_array($value) && $value != '')
|
||||
{
|
||||
$value = str_replace(' ', '', $value);
|
||||
$value = str_replace('\'', '', $value);
|
||||
$value = explode(',', $value);
|
||||
}
|
||||
parent::__construct($name, $value);
|
||||
$this->operation = $operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* create condition value. set $this->value
|
||||
* @return void
|
||||
*/
|
||||
function createConditionValue()
|
||||
{
|
||||
if(!isset($this->value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$operation = $this->operation;
|
||||
$value = $this->value;
|
||||
|
||||
switch($operation)
|
||||
{
|
||||
case 'like_prefix' :
|
||||
if(defined('__CUBRID_VERSION__') && __CUBRID_VERSION__ >= '8.4.1')
|
||||
{
|
||||
$this->value = '^' . str_replace('%', '(.*)', preg_quote($value));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->value = $value . '%';
|
||||
}
|
||||
break;
|
||||
case 'like_tail' :
|
||||
if(defined('__CUBRID_VERSION__') && __CUBRID_VERSION__ >= '8.4.1')
|
||||
{
|
||||
$this->value = str_replace('%', '(.*)', preg_quote($value)) . '$';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->value = '%' . $value;
|
||||
}
|
||||
break;
|
||||
case 'like' :
|
||||
if(defined('__CUBRID_VERSION__') && __CUBRID_VERSION__ >= '8.4.1')
|
||||
{
|
||||
$this->value = str_replace('%', '(.*)', preg_quote($value));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->value = '%' . $value . '%';
|
||||
}
|
||||
break;
|
||||
case 'notlike' :
|
||||
$this->value = '%' . $value . '%';
|
||||
break;
|
||||
case 'notlike_prefix' :
|
||||
$this->value = $value . '%';
|
||||
break;
|
||||
case 'notlike_tail' :
|
||||
$this->value = '%' . $value;
|
||||
break;
|
||||
case 'in':
|
||||
if(!is_array($value))
|
||||
{
|
||||
$this->value = array($value);
|
||||
}
|
||||
break;
|
||||
case 'notin':
|
||||
case 'not_in':
|
||||
if(!is_array($value))
|
||||
{
|
||||
$this->value = array($value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Since ConditionArgument is used in WHERE clause,
|
||||
* where the argument value is compared to a table column,
|
||||
* it is assumed that all arguments have type. There are cases though
|
||||
* where the column does not have any type - if it was removed from
|
||||
* the XML schema for example - see the is_secret column in xe_documents table.
|
||||
* In this case, the column type is retrieved according to argument
|
||||
* value type (using the PHP function is_numeric).
|
||||
*
|
||||
* @return type string
|
||||
*/
|
||||
function getType()
|
||||
{
|
||||
if($this->type)
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
else if(!is_numeric($this->value))
|
||||
{
|
||||
return 'varchar';
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function setColumnType($column_type)
|
||||
{
|
||||
if(!isset($this->value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if($column_type === '')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->type = $column_type;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ConditionArgument.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/argument/ConditionArgument.class.php */
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* SortArgument class
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/xml/xmlquery/argument
|
||||
* @version 0.1
|
||||
*/
|
||||
class SortArgument extends Argument
|
||||
{
|
||||
|
||||
function getValue()
|
||||
{
|
||||
return $this->getUnescapedValue();
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file SortArgument.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/argument/SortArgument.class.php */
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* DefaultValue class
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/xml/xmlquery/queryargument
|
||||
* @version 0.1
|
||||
*/
|
||||
class DefaultValue
|
||||
{
|
||||
|
||||
/**
|
||||
* Column name
|
||||
* @var string
|
||||
*/
|
||||
var $column_name;
|
||||
|
||||
/**
|
||||
* Value
|
||||
* @var mixed
|
||||
*/
|
||||
var $value;
|
||||
|
||||
/**
|
||||
* sequnence status
|
||||
* @var bool
|
||||
*/
|
||||
var $is_sequence = FALSE;
|
||||
|
||||
/**
|
||||
* operation status
|
||||
* @var bool
|
||||
*/
|
||||
var $is_operation = FALSE;
|
||||
|
||||
/**
|
||||
* operation
|
||||
* @var string
|
||||
*/
|
||||
var $operation = '';
|
||||
|
||||
/**
|
||||
* Checks if value is plain string or name of XE function (ipaddress, plus, etc).
|
||||
* @var bool
|
||||
*/
|
||||
var $_is_string = FALSE;
|
||||
|
||||
/**
|
||||
* Checks if value is string resulted from evaluating a piece of PHP code (see $_SERVER[REMOTE_ADDR])
|
||||
* @var bool
|
||||
*/
|
||||
var $_is_string_from_function = FALSE;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $column_name column name
|
||||
* @param mixed $value value
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column_name, $value)
|
||||
{
|
||||
$dbParser = DB::getParser();
|
||||
$this->column_name = $dbParser->parseColumnName($column_name);
|
||||
$this->value = $value;
|
||||
$this->value = $this->_setValue();
|
||||
}
|
||||
|
||||
function isString()
|
||||
{
|
||||
return $this->_is_string;
|
||||
$str_pos = strpos($this->value, '(');
|
||||
if($str_pos === false)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function isStringFromFunction()
|
||||
{
|
||||
return $this->_is_string_from_function;
|
||||
}
|
||||
|
||||
function isSequence()
|
||||
{
|
||||
return $this->is_sequence;
|
||||
}
|
||||
|
||||
function isOperation()
|
||||
{
|
||||
return $this->is_operation;
|
||||
}
|
||||
|
||||
function getOperation()
|
||||
{
|
||||
return $this->operation;
|
||||
}
|
||||
|
||||
function _setValue()
|
||||
{
|
||||
if(!isset($this->value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If value contains comma separated values and does not contain paranthesis
|
||||
// -> default value is an array
|
||||
if(strpos($this->value, ',') !== FALSE && strpos($this->value, '(') === FALSE)
|
||||
{
|
||||
return sprintf('array(%s)', $this->value);
|
||||
}
|
||||
|
||||
$str_pos = strpos($this->value, '(');
|
||||
// // TODO Replace this with parseExpression
|
||||
if($str_pos === FALSE)
|
||||
{
|
||||
$this->_is_string = TRUE;
|
||||
return '\'' . $this->value . '\'';
|
||||
}
|
||||
//if($str_pos===false) return $this->value;
|
||||
|
||||
$func_name = substr($this->value, 0, $str_pos);
|
||||
$args = substr($this->value, $str_pos + 1, -1);
|
||||
|
||||
switch($func_name)
|
||||
{
|
||||
case 'ipaddress' :
|
||||
$val = '\\RX_CLIENT_IP';
|
||||
$this->_is_string_from_function = TRUE;
|
||||
break;
|
||||
case 'unixtime' :
|
||||
$val = '\\RX_TIME';
|
||||
$this->_is_string_from_function = TRUE;
|
||||
break;
|
||||
case 'curdate' :
|
||||
$val = 'getInternalDateTime()';
|
||||
$this->_is_string_from_function = TRUE;
|
||||
break;
|
||||
case 'sequence' :
|
||||
$this->is_sequence = TRUE;
|
||||
$val = '$sequence';
|
||||
break;
|
||||
case 'plus' :
|
||||
$args = abs($args);
|
||||
$this->is_operation = TRUE;
|
||||
$this->operation = '+';
|
||||
$val = sprintf('%d', $args);
|
||||
break;
|
||||
case 'minus' :
|
||||
$args = abs($args);
|
||||
$this->is_operation = TRUE;
|
||||
$this->operation = '-';
|
||||
$val = sprintf('%d', $args);
|
||||
break;
|
||||
case 'multiply' :
|
||||
$args = intval($args);
|
||||
$this->is_operation = TRUE;
|
||||
$this->operation = '*';
|
||||
$val = sprintf('%d', $args);
|
||||
break;
|
||||
default :
|
||||
$val = '\'' . $this->value . '\'';
|
||||
//$val = $this->value;
|
||||
}
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file DefaultValue.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/queryargument/DefaultValue.class.php */
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* QueryArgument class
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/xml/xmlquery/queryargument
|
||||
* @version 0.1
|
||||
*/
|
||||
class QueryArgument
|
||||
{
|
||||
|
||||
/**
|
||||
* Argument name
|
||||
* @var string
|
||||
*/
|
||||
var $argument_name;
|
||||
|
||||
/**
|
||||
* Variable name
|
||||
* @var string
|
||||
*/
|
||||
var $variable_name;
|
||||
|
||||
/**
|
||||
* Argument validator
|
||||
* @var QueryArgumentValidator
|
||||
*/
|
||||
var $argument_validator;
|
||||
|
||||
/**
|
||||
* Column name
|
||||
* @var string
|
||||
*/
|
||||
var $column_name;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
* @var string
|
||||
*/
|
||||
var $table_name;
|
||||
|
||||
/**
|
||||
* Operation
|
||||
* @var string
|
||||
*/
|
||||
var $operation;
|
||||
|
||||
/**
|
||||
* Ignore value
|
||||
* @var bool
|
||||
*/
|
||||
var $ignore_value;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param object $tag tag object
|
||||
* @param bool $ignore_value
|
||||
* @return void
|
||||
*/
|
||||
function __construct($tag, $ignore_value = FALSE)
|
||||
{
|
||||
static $number_of_arguments = 0;
|
||||
|
||||
$this->argument_name = $tag->attrs->var;
|
||||
if(!$this->argument_name)
|
||||
{
|
||||
$this->argument_name = str_replace('.', '_', $tag->attrs->name);
|
||||
}
|
||||
if(!$this->argument_name)
|
||||
{
|
||||
$this->argument_name = str_replace('.', '_', $tag->attrs->column);
|
||||
}
|
||||
|
||||
$this->variable_name = $this->argument_name;
|
||||
|
||||
$number_of_arguments++;
|
||||
$this->argument_name .= $number_of_arguments;
|
||||
|
||||
$name = $tag->attrs->name;
|
||||
if(!$name)
|
||||
{
|
||||
$name = $tag->attrs->column;
|
||||
}
|
||||
if(strpos($name, '.') === FALSE)
|
||||
{
|
||||
$this->column_name = $name;
|
||||
}
|
||||
else
|
||||
{
|
||||
list($prefix, $name) = explode('.', $name);
|
||||
$this->column_name = $name;
|
||||
$this->table_name = $prefix;
|
||||
}
|
||||
|
||||
if($tag->attrs->operation)
|
||||
{
|
||||
$this->operation = $tag->attrs->operation;
|
||||
}
|
||||
|
||||
$this->argument_validator = new QueryArgumentValidator($tag, $this);
|
||||
$this->ignore_value = $ignore_value;
|
||||
}
|
||||
|
||||
function getArgumentName()
|
||||
{
|
||||
return $this->argument_name;
|
||||
}
|
||||
|
||||
function getColumnName()
|
||||
{
|
||||
return $this->column_name;
|
||||
}
|
||||
|
||||
function getTableName()
|
||||
{
|
||||
return $this->table_name;
|
||||
}
|
||||
|
||||
function getValidatorString()
|
||||
{
|
||||
return $this->argument_validator->toString();
|
||||
}
|
||||
|
||||
function isConditionArgument()
|
||||
{
|
||||
if($this->operation)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change QueryArgument object to string
|
||||
* @return string
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
if($this->isConditionArgument())
|
||||
{
|
||||
// Instantiation
|
||||
$arg = sprintf("\n" . '${\'%s_argument\'} = new ConditionArgument(\'%s\', %s, \'%s\');' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->variable_name
|
||||
, '$args->' . $this->variable_name
|
||||
, $this->operation
|
||||
);
|
||||
// Call methods to validate argument and ensure default value
|
||||
$arg .= $this->argument_validator->toString();
|
||||
|
||||
// Prepare condition string
|
||||
$arg .= sprintf('${\'%s_argument\'}->createConditionValue();' . "\n"
|
||||
, $this->argument_name
|
||||
);
|
||||
|
||||
// Check that argument passed validation, else return
|
||||
$arg .= sprintf('if(!${\'%s_argument\'}->isValid()) return ${\'%s_argument\'}->getErrorMessage();' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->argument_name
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$arg = sprintf("\n" . '${\'%s_argument\'} = new Argument(\'%s\', %s);' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->variable_name
|
||||
, $this->ignore_value ? 'NULL' : '$args->{\'' . $this->variable_name . '\'}');
|
||||
|
||||
$arg .= $this->argument_validator->toString();
|
||||
|
||||
$arg .= sprintf('if(!${\'%s_argument\'}->isValid()) return ${\'%s_argument\'}->getErrorMessage();' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->argument_name
|
||||
);
|
||||
}
|
||||
|
||||
// If the argument is null, skip it
|
||||
if($this->argument_validator->isIgnorable())
|
||||
{
|
||||
$arg = sprintf("if(isset(%s)) {", '$args->' . $this->variable_name)
|
||||
. $arg
|
||||
. sprintf("} else\n" . '${\'%s_argument\'} = NULL;', $this->argument_name);
|
||||
}
|
||||
|
||||
return $arg;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file QueryArgument.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/queryargument/QueryArgument.class.php */
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* SortQueryArgument class
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/xml/xmlquery/queryargument
|
||||
* @version 0.1
|
||||
*/
|
||||
class SortQueryArgument extends QueryArgument
|
||||
{
|
||||
|
||||
/**
|
||||
* Change SortQueryArgument object to string
|
||||
* @return string
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
$arg = sprintf("\n" . '${\'%s_argument\'} = new SortArgument(\'%s\', %s);' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->argument_name
|
||||
, '$args->' . $this->variable_name);
|
||||
$arg .= $this->argument_validator->toString();
|
||||
|
||||
$arg .= sprintf('if(!${\'%s_argument\'}->isValid()) return ${\'%s_argument\'}->getErrorMessage();' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->argument_name
|
||||
);
|
||||
return $arg;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file DefaultValue.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/queryargument/DefaultValue.class.php */
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* QueryArgumentValidator class
|
||||
* @author NAVER (developers@xpressengine.com)
|
||||
* @package /classes/xml/xmlquery/queryargument/validator
|
||||
* @version 0.1
|
||||
*/
|
||||
class QueryArgumentValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* Argument name
|
||||
* @var string
|
||||
*/
|
||||
var $argument_name;
|
||||
|
||||
/**
|
||||
* Default value
|
||||
* @var string
|
||||
*/
|
||||
var $default_value;
|
||||
|
||||
/**
|
||||
* Notnull status setting, if value should be not null, this value is 'notnull'
|
||||
* @var string
|
||||
*/
|
||||
var $notnull;
|
||||
|
||||
/**
|
||||
* Filter for value type, for example number
|
||||
* @var string
|
||||
*/
|
||||
var $filter;
|
||||
|
||||
/**
|
||||
* Minimum length for value
|
||||
* @var int
|
||||
*/
|
||||
var $min_length;
|
||||
|
||||
/**
|
||||
* Maximum length for value
|
||||
* @var int
|
||||
*/
|
||||
var $max_length;
|
||||
var $validator_string;
|
||||
|
||||
/**
|
||||
* Query argument for validate
|
||||
* @var QueryArgument object
|
||||
*/
|
||||
var $argument;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param Xml_Node_ $tag tag object by Query xml file parse
|
||||
* @param QueryArgument $argument
|
||||
* @return void
|
||||
*/
|
||||
function __construct($tag, $argument)
|
||||
{
|
||||
$this->argument = $argument;
|
||||
$this->argument_name = $this->argument->getArgumentName();
|
||||
|
||||
$this->default_value = $tag->attrs->default;
|
||||
$this->notnull = $tag->attrs->notnull;
|
||||
$this->filter = $tag->attrs->filter;
|
||||
$this->min_length = $tag->attrs->min_length;
|
||||
$this->max_length = $tag->attrs->max_length;
|
||||
}
|
||||
|
||||
function isIgnorable()
|
||||
{
|
||||
if(isset($this->default_value) || isset($this->notnull))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
$validator = '';
|
||||
if($this->filter)
|
||||
{
|
||||
$validator .= sprintf('${\'%s_argument\'}->checkFilter(\'%s\');' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->filter
|
||||
);
|
||||
}
|
||||
if($this->min_length)
|
||||
{
|
||||
$validator .= sprintf('${\'%s_argument\'}->checkMinLength(%s);' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->min_length
|
||||
);
|
||||
}
|
||||
if($this->max_length)
|
||||
{
|
||||
$validator .= sprintf('${\'%s_argument\'}->checkMaxLength(%s);' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->max_length
|
||||
);
|
||||
}
|
||||
if(isset($this->default_value))
|
||||
{
|
||||
$this->default_value = new DefaultValue($this->argument_name, $this->default_value);
|
||||
if($this->default_value->isSequence())
|
||||
$validator .= '$db = DB::getInstance(); $sequence = $db->getNextSequence(); ';
|
||||
if($this->default_value->isOperation())
|
||||
{
|
||||
$validator .= sprintf('${\'%s_argument\'}->setColumnOperation(\'%s\');' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->default_value->getOperation()
|
||||
);
|
||||
}
|
||||
$validator .= sprintf('${\'%s_argument\'}->ensureDefaultValue(%s);' . "\n"
|
||||
, $this->argument_name
|
||||
, $this->default_value->toString()
|
||||
);
|
||||
}
|
||||
if($this->notnull)
|
||||
{
|
||||
$validator .= sprintf('${\'%s_argument\'}->checkNotNull();' . "\n"
|
||||
, $this->argument_name
|
||||
);
|
||||
}
|
||||
return $validator;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file QueryArgumentValidator.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/queryargument/validator/QueryArgumentValidator.class.php */
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Models the <column> tag inside an XML Query file <br />
|
||||
* Since the <column> tag supports different attributes depending on
|
||||
* the type of query (select, update, insert, delete) this is only
|
||||
* the base class for the classes that will model each type <column> tag.
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery\tags\column
|
||||
* @version 0.1
|
||||
*/
|
||||
class ColumnTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Column name
|
||||
* @var string
|
||||
*/
|
||||
var $name;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ColumnTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/column/ColumnTag.class.php */
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Models the <column> tag inside an XML Query file whose action is 'insert'
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery\tags\column
|
||||
* @version 0.1
|
||||
*/
|
||||
class InsertColumnTag extends ColumnTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Argument
|
||||
*
|
||||
* @var QueryArgument object
|
||||
*/
|
||||
var $argument;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param object $column
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column)
|
||||
{
|
||||
parent::__construct($column->attrs->name);
|
||||
$dbParser = DB::getParser();
|
||||
$this->name = $dbParser->parseColumnName($this->name);
|
||||
$this->argument = new QueryArgument($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string to be output in the cache file
|
||||
* used for instantiating an InsertExpression when a
|
||||
* query is executed
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getExpressionString()
|
||||
{
|
||||
return sprintf('new InsertExpression(\'%s\', ${\'%s_argument\'})'
|
||||
, $this->name
|
||||
, $this->argument->argument_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the QueryArgument object associated with this INSERT statement
|
||||
*
|
||||
* @return QueryArgument
|
||||
*/
|
||||
function getArgument()
|
||||
{
|
||||
return $this->argument;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file InsertColumnTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/column/InsertColumnTag.class.php */
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Models the <column> tag inside an XML Query file whose action is 'insert-select'
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery\tags\column
|
||||
* @version 0.1
|
||||
*/
|
||||
class InsertColumnTagWithoutArgument extends ColumnTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param object $column
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column)
|
||||
{
|
||||
parent::__construct($column->attrs->name);
|
||||
$dbParser = DB::getParser();
|
||||
$this->name = $dbParser->parseColumnName($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string to be output in the cache file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getExpressionString()
|
||||
{
|
||||
return sprintf('new Expression(\'%s\')', $this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the QueryArgument object associated with this INSERT statement
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function getArgument()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file InsertColumnTagWithoutArgument.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/column/InsertColumnTagWithoutArgument.class.php */
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Models the <columns> tag inside an XML Query file whose action is 'insert'
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery\tags\column
|
||||
* @version 0.1
|
||||
*/
|
||||
class InsertColumnsTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Column list
|
||||
*
|
||||
* @var array value is InsertColumnTag object
|
||||
*/
|
||||
var $columns;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|string $xml_columns
|
||||
* @return void
|
||||
*/
|
||||
function __construct($xml_columns)
|
||||
{
|
||||
$this->columns = array();
|
||||
|
||||
if(!$xml_columns)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is_array($xml_columns))
|
||||
{
|
||||
$xml_columns = array($xml_columns);
|
||||
}
|
||||
|
||||
foreach($xml_columns as $column)
|
||||
{
|
||||
if($column->name === 'query')
|
||||
{
|
||||
$this->columns[] = new QueryTag($column, TRUE);
|
||||
}
|
||||
else if(!isset($column->attrs->var) && !isset($column->attrs->default))
|
||||
{
|
||||
$this->columns[] = new InsertColumnTagWithoutArgument($column);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->columns[] = new InsertColumnTag($column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* InsertColumnTag object to string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
$output_columns = 'array(' . PHP_EOL;
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
$output_columns .= $column->getExpressionString() . PHP_EOL . ',';
|
||||
}
|
||||
$output_columns = substr($output_columns, 0, -1);
|
||||
$output_columns .= ')';
|
||||
return $output_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return argument list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
$arguments[] = $column->getArgument();
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file InsertColumnsTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php */
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Models the <column> tag inside an XML Query file whose action is 'select'
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery\tags\column
|
||||
* @version 0.1
|
||||
*/
|
||||
class SelectColumnTag extends ColumnTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Column alias
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $alias;
|
||||
|
||||
/**
|
||||
* Click count status
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
var $click_count;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string|object $column
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column)
|
||||
{
|
||||
if($column == "*" || $column->attrs->name == '*')
|
||||
{
|
||||
parent::__construct(NULL);
|
||||
$this->name = "*";
|
||||
}
|
||||
else
|
||||
{
|
||||
parent::__construct($column->attrs->name);
|
||||
$dbParser = DB::getParser();
|
||||
$this->name = $dbParser->parseExpression($this->name);
|
||||
|
||||
$this->alias = $column->attrs->alias;
|
||||
$this->click_count = $column->attrs->click_count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string to be output in the cache file
|
||||
*
|
||||
* A select column tag in an XML query can be used for:
|
||||
* <ul>
|
||||
* <li> a star expression: SELECT *
|
||||
* <li> a click count expression: SELECT + UPDATE
|
||||
* <li> any other select expression (column name, function call etc). </li>
|
||||
* </ul>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getExpressionString()
|
||||
{
|
||||
if($this->name == '*')
|
||||
{
|
||||
return "new StarExpression()";
|
||||
}
|
||||
if($this->click_count)
|
||||
{
|
||||
return sprintf('new ClickCountExpression(\'%s\', %s, $args->%s)', $this->name, $this->alias ? '\'' . $this->alias . '\'' : "''", $this->click_count);
|
||||
}
|
||||
if(strpos($this->name, '$') === 0)
|
||||
{
|
||||
return sprintf('new SelectExpression($args->%s)', substr($this->name, 1));
|
||||
}
|
||||
$dbParser = DB::getParser();
|
||||
return sprintf('new SelectExpression(\'%s\'%s)', $this->name, $this->alias ? ', \'' . $dbParser->escape($this->alias) . '\'' : '');
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file SelectColumnTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/column/SelectColumnTag.class.php */
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Models the <columns> tag inside an XML Query file whose action is 'select'
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery\tags\column
|
||||
* @version 0.1
|
||||
*/
|
||||
class SelectColumnsTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Column list
|
||||
*
|
||||
* @var array value is SelectColumnTag object
|
||||
*/
|
||||
var $columns;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param $xml_columns_tag
|
||||
* @internal param \Xml_Node_ $xml_columns
|
||||
* @return void
|
||||
*/
|
||||
function __construct($xml_columns_tag)
|
||||
{
|
||||
if(!$xml_columns_tag)
|
||||
{
|
||||
$xml_columns_tag = new Xml_Node_();
|
||||
}
|
||||
|
||||
$xml_columns = $xml_columns_tag->column;
|
||||
$xml_queries = $xml_columns_tag->query;
|
||||
|
||||
$this->columns = array();
|
||||
|
||||
if(!$xml_columns)
|
||||
{
|
||||
$this->columns[] = new SelectColumnTag("*");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is_array($xml_columns))
|
||||
{
|
||||
$xml_columns = array($xml_columns);
|
||||
}
|
||||
|
||||
foreach($xml_columns as $column)
|
||||
{
|
||||
$this->columns[] = new SelectColumnTag($column);
|
||||
}
|
||||
|
||||
|
||||
if(!$xml_queries)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is_array($xml_queries))
|
||||
{
|
||||
$xml_queries = array($xml_queries);
|
||||
}
|
||||
|
||||
foreach($xml_queries as $column)
|
||||
{
|
||||
$this->columns[] = new QueryTag($column, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string to be output in the cache file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
$output_columns = 'array(' . PHP_EOL;
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
if(is_a($column, 'QueryTag'))
|
||||
{
|
||||
$output_columns .= $column->toString() . PHP_EOL . ',';
|
||||
}
|
||||
else
|
||||
{
|
||||
$output_columns .= $column->getExpressionString() . PHP_EOL . ',';
|
||||
}
|
||||
}
|
||||
$output_columns = substr($output_columns, 0, -1);
|
||||
$output_columns .= ')';
|
||||
return $output_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return argument list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
if(is_a($column, 'QueryTag'))
|
||||
{
|
||||
$arguments = array_merge($arguments, $column->getArguments());
|
||||
}
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file SelectColumnsTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/column/SelectColumnsTag.class.php */
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Models the <column> tag inside an XML Query file whose action is 'update'
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery\tags\column
|
||||
* @version 0.1
|
||||
*/
|
||||
class UpdateColumnTag extends ColumnTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Argument
|
||||
*
|
||||
* @var QueryArgument object
|
||||
*/
|
||||
var $argument;
|
||||
|
||||
/**
|
||||
* Default value
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $default_value;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param object $column
|
||||
* @return void
|
||||
*/
|
||||
function __construct($column)
|
||||
{
|
||||
parent::__construct($column->attrs->name);
|
||||
|
||||
$dbParser = DB::getParser();
|
||||
$this->name = $dbParser->parseColumnName($this->name);
|
||||
|
||||
if($column->attrs->var)
|
||||
{
|
||||
$this->argument = new QueryArgument($column);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(strpos($column->attrs->default, '.') !== FALSE)
|
||||
{
|
||||
$this->default_value = "'" . $dbParser->parseColumnName($column->attrs->default) . "'";
|
||||
}
|
||||
else
|
||||
{
|
||||
$default_value = new DefaultValue($this->name, $column->attrs->default);
|
||||
if($default_value->isOperation())
|
||||
{
|
||||
$this->argument = new QueryArgument($column, TRUE);
|
||||
}
|
||||
//else $this->default_value = $dbParser->parseColumnName($column->attrs->default);
|
||||
else
|
||||
{
|
||||
$this->default_value = $default_value->toString();
|
||||
if($default_value->isStringFromFunction())
|
||||
{
|
||||
$this->default_value = '"\'".' . $this->default_value . '."\'"';
|
||||
}
|
||||
if($default_value->isString())
|
||||
{
|
||||
$this->default_value = '"' . $this->default_value . '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string to be output in the cache file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getExpressionString()
|
||||
{
|
||||
if($this->argument)
|
||||
{
|
||||
return sprintf('new UpdateExpression(\'%s\', ${\'%s_argument\'})'
|
||||
, $this->name
|
||||
, $this->argument->argument_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return sprintf('new UpdateExpressionWithoutArgument(\'%s\', %s)'
|
||||
, $this->name
|
||||
, $this->default_value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Argument associated with this update statement
|
||||
*
|
||||
* @return QueryArgument
|
||||
*/
|
||||
function getArgument()
|
||||
{
|
||||
return $this->argument;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file UpdateColumnTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/column/UpdateColumnTag.class.php */
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* Models the <columns> tag inside an XML Query file whose action is 'update'
|
||||
*
|
||||
* @author Corina Udrescu (corina.udrescu@arnia.ro)
|
||||
* @package classes\xml\xmlquery\tags\column
|
||||
* @version 0.1
|
||||
*/
|
||||
class UpdateColumnsTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Column list
|
||||
*
|
||||
* @var array value is UpdateColumnTag object
|
||||
*/
|
||||
var $columns;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|object $xml_columns
|
||||
* @return void
|
||||
*/
|
||||
function __construct($xml_columns)
|
||||
{
|
||||
$this->columns = array();
|
||||
|
||||
if(!is_array($xml_columns))
|
||||
{
|
||||
$xml_columns = array($xml_columns);
|
||||
}
|
||||
|
||||
foreach($xml_columns as $column)
|
||||
{
|
||||
if($column->name === 'query')
|
||||
{
|
||||
$this->columns[] = new QueryTag($column, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->columns[] = new UpdateColumnTag($column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string to be output in the cache file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
$output_columns = 'array(' . PHP_EOL;
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
$output_columns .= $column->getExpressionString() . PHP_EOL . ',';
|
||||
}
|
||||
$output_columns = substr($output_columns, 0, -1);
|
||||
$output_columns .= ')';
|
||||
return $output_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return argument list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
foreach($this->columns as $column)
|
||||
{
|
||||
$arguments[] = $column->getArgument();
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file UpdateColumnsTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/column/UpdateColumnsTag.class.php */
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* ConditionGroupTag class
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/xml/xmlquery/tags/condition
|
||||
* @version 0.1
|
||||
*/
|
||||
class ConditionGroupTag
|
||||
{
|
||||
|
||||
/**
|
||||
* condition list
|
||||
* @var string|array value is ConditionTag object
|
||||
*/
|
||||
var $conditions;
|
||||
|
||||
/**
|
||||
* pipe
|
||||
* @var string
|
||||
*/
|
||||
var $pipe;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string|array $conditions
|
||||
* @param string $pipe
|
||||
* @return void
|
||||
*/
|
||||
function __construct($conditions, $pipe = 'and')
|
||||
{
|
||||
$this->pipe = $pipe;
|
||||
|
||||
if(!is_array($conditions))
|
||||
{
|
||||
$conditions = array($conditions);
|
||||
}
|
||||
|
||||
foreach($conditions as $condition)
|
||||
{
|
||||
if($condition->node_name === 'group')
|
||||
{
|
||||
$subconditions = $condition->condition;
|
||||
$subgroups = $condition->group;
|
||||
$subconditions = $subconditions ? (is_array($subconditions) ? $subconditions : [$subconditions]) : [];
|
||||
$subgroups = $subgroups ? (is_array($subgroups) ? $subgroups : [$subgroups]) : [];
|
||||
$this->conditions[] = new ConditionGroupTag(array_merge($subconditions, $subgroups), $condition->attrs->pipe);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->conditions[] = new ConditionTag($condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getConditions()
|
||||
{
|
||||
return $this->conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* ConditionTag object to string
|
||||
* @return string
|
||||
*/
|
||||
function getConditionGroupString()
|
||||
{
|
||||
$conditions_string = 'array(' . PHP_EOL;
|
||||
foreach($this->conditions as $condition)
|
||||
{
|
||||
if($condition instanceof ConditionGroupTag)
|
||||
{
|
||||
$conditions_string .= $condition->getConditionGroupString() . PHP_EOL . ',';
|
||||
}
|
||||
else
|
||||
{
|
||||
$conditions_string .= $condition->getConditionString() . PHP_EOL . ',';
|
||||
}
|
||||
}
|
||||
$conditions_string = substr($conditions_string, 0, -2); //remove ','
|
||||
$conditions_string .= ')';
|
||||
|
||||
return sprintf("new ConditionGroup(%s%s)", $conditions_string, $this->pipe ? ',\'' . $this->pipe . '\'' : '');
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
foreach($this->conditions as $condition)
|
||||
{
|
||||
$arguments = array_merge($arguments, $condition->getArguments());
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ConditionGroupTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/condition/ConditionGroupTag.class.php */
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* ConditionTag
|
||||
* Models the <condition> tag inside an XML Query file. Base class.
|
||||
*
|
||||
* @author Corina
|
||||
* @package /classes/xml/xmlquery/tags/condition
|
||||
* @version 0.1
|
||||
*/
|
||||
class ConditionTag
|
||||
{
|
||||
|
||||
/**
|
||||
* operation for example 'in', 'between', 'not in'...
|
||||
* @var string
|
||||
*/
|
||||
var $operation;
|
||||
|
||||
/**
|
||||
* Column name
|
||||
* @var string
|
||||
*/
|
||||
var $column_name;
|
||||
|
||||
/**
|
||||
* Pipe
|
||||
* @var string
|
||||
*/
|
||||
var $pipe;
|
||||
|
||||
/**
|
||||
* Argument name
|
||||
* @var string
|
||||
*/
|
||||
var $argument_name;
|
||||
|
||||
/**
|
||||
* QueryArgument object
|
||||
* @var QueryArgument
|
||||
*/
|
||||
var $argument;
|
||||
|
||||
/**
|
||||
* Default column
|
||||
* @var string
|
||||
*/
|
||||
var $default_column;
|
||||
|
||||
/**
|
||||
* QueryTag object
|
||||
* @var QueryTag
|
||||
*/
|
||||
var $query;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param object $condition
|
||||
* @return void
|
||||
*/
|
||||
function __construct($condition)
|
||||
{
|
||||
$this->operation = $condition->attrs->operation;
|
||||
$this->pipe = $condition->attrs->pipe ?: 'and';
|
||||
$dbParser = DB::getParser();
|
||||
$this->column_name = $dbParser->parseExpression($condition->attrs->column);
|
||||
|
||||
// If default value is column name, it should be escaped
|
||||
if($isColumnName = (strpos($condition->attrs->default, '.') !== FALSE
|
||||
&& strpos($condition->attrs->default, '.') !== 0
|
||||
&& strpos($condition->attrs->default, '%') === FALSE ))
|
||||
{
|
||||
$condition->attrs->default = $dbParser->parseExpression($condition->attrs->default);
|
||||
}
|
||||
|
||||
if($condition->node_name == 'query')
|
||||
{
|
||||
$this->query = new QueryTag($condition, TRUE);
|
||||
$this->default_column = $this->query->toString();
|
||||
}
|
||||
else if($condition->attrs->var && !strpos($condition->attrs->var, '.'))
|
||||
{
|
||||
$this->argument = new QueryArgument($condition);
|
||||
$this->argument_name = $this->argument->getArgumentName();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isset($condition->attrs->default))
|
||||
{
|
||||
$operationList = array('in' => 1, 'between' => 1, 'notin' => 1, 'not_in' => 1);
|
||||
if(isset($operationList[$this->operation]))
|
||||
{
|
||||
$default_value = $condition->attrs->default;
|
||||
if(strpos($default_value, "'") !== FALSE)
|
||||
{
|
||||
$default_value = "\"" . $default_value . "\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
$default_value = "'" . $default_value . "'";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$default_value_object = new DefaultValue($this->column_name, $condition->attrs->default);
|
||||
$default_value = $default_value_object->toString();
|
||||
|
||||
if($default_value_object->isStringFromFunction())
|
||||
{
|
||||
$default_value = '"\'".' . $default_value . '."\'"';
|
||||
}
|
||||
|
||||
if($default_value_object->isString() && !$isColumnName && !is_numeric($condition->attrs->default))
|
||||
{
|
||||
if(strpos($default_value, "'") !== FALSE)
|
||||
{
|
||||
$default_value = "\"" . $default_value . "\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
$default_value = "'" . $default_value . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->default_column = $default_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->default_column = "'" . $dbParser->parseColumnName($condition->attrs->var) . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setPipe($pipe)
|
||||
{
|
||||
$this->pipe = $pipe;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
if($this->query)
|
||||
{
|
||||
$arguments = array_merge($arguments, $this->query->getArguments());
|
||||
}
|
||||
if($this->argument)
|
||||
{
|
||||
$arguments[] = $this->argument;
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
function getConditionString()
|
||||
{
|
||||
if($this->query)
|
||||
{
|
||||
return sprintf("new ConditionSubquery('%s',%s,%s%s)"
|
||||
, $this->column_name
|
||||
, $this->default_column
|
||||
, '"' . $this->operation . '"'
|
||||
, $this->pipe ? ", '" . $this->pipe . "'" : ''
|
||||
);
|
||||
}
|
||||
else if(isset($this->default_column))
|
||||
{
|
||||
return sprintf("new ConditionWithoutArgument('%s',%s,%s%s)"
|
||||
, $this->column_name
|
||||
, $this->default_column
|
||||
, '"' . $this->operation . '"'
|
||||
, $this->pipe ? ", '" . $this->pipe . "'" : ''
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return sprintf("new ConditionWithArgument('%s',%s,%s%s)"
|
||||
, $this->column_name
|
||||
, '$' . $this->argument_name . '_argument'
|
||||
, '"' . $this->operation . '"'
|
||||
, $this->pipe ? ", '" . $this->pipe . "'" : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ConditionTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/condition/ConditionTag.class.php */
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* ConditionsTag class
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/xml/xmlquery/tags/condition
|
||||
* @version 0.1
|
||||
*/
|
||||
class ConditionsTag
|
||||
{
|
||||
|
||||
/**
|
||||
* ConditionGroupTag list
|
||||
* @var array value is ConditionGroupTag object
|
||||
*/
|
||||
var $condition_groups;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param object $xml_conditions
|
||||
* @return void
|
||||
*/
|
||||
function __construct($xml_conditions)
|
||||
{
|
||||
$this->condition_groups = array();
|
||||
if(!$xml_conditions)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$xml_condition_list = array();
|
||||
if($xml_conditions->condition)
|
||||
{
|
||||
$xml_condition_list = $xml_conditions->condition;
|
||||
}
|
||||
|
||||
if($xml_conditions->query)
|
||||
{
|
||||
if(!is_array($xml_condition_list))
|
||||
{
|
||||
$xml_condition_list = array($xml_condition_list);
|
||||
}
|
||||
if(!is_array($xml_conditions->query))
|
||||
{
|
||||
$xml_conditions->query = array($xml_conditions->query);
|
||||
}
|
||||
$xml_condition_list = array_merge($xml_condition_list, $xml_conditions->query);
|
||||
}
|
||||
if($xml_condition_list)
|
||||
{
|
||||
$this->condition_groups[] = new ConditionGroupTag($xml_condition_list);
|
||||
}
|
||||
|
||||
$xml_groups = $xml_conditions->group;
|
||||
if($xml_groups)
|
||||
{
|
||||
if(!is_array($xml_groups))
|
||||
{
|
||||
$xml_groups = array($xml_groups);
|
||||
}
|
||||
foreach($xml_groups as $group)
|
||||
{
|
||||
$subconditions = $group->condition;
|
||||
$subgroups = $group->group;
|
||||
$subconditions = $subconditions ? (is_array($subconditions) ? $subconditions : [$subconditions]) : [];
|
||||
$subgroups = $subgroups ? (is_array($subgroups) ? $subgroups : [$subgroups]) : [];
|
||||
$this->condition_groups[] = new ConditionGroupTag(array_merge($subconditions, $subgroups), $group->attrs->pipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ConditionGroupTag object to string
|
||||
* @return string
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
$output_conditions = 'array(' . PHP_EOL;
|
||||
foreach($this->condition_groups as $condition)
|
||||
{
|
||||
$output_conditions .= $condition->getConditionGroupString() . PHP_EOL . ',';
|
||||
}
|
||||
$output_conditions = substr($output_conditions, 0, -1);
|
||||
$output_conditions .= ')';
|
||||
return $output_conditions;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
foreach($this->condition_groups as $condition)
|
||||
{
|
||||
$arguments = array_merge($arguments, $condition->getArguments());
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file ConditionsTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/condition/ConditionsTag.class.php */
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* JoinConditionsTag class
|
||||
*
|
||||
* @author Corina
|
||||
* @package /classes/xml/xmlquery/tags/condition
|
||||
* @version 0.1
|
||||
*/
|
||||
class JoinConditionsTag extends ConditionsTag
|
||||
{
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param object $xml_conditions
|
||||
* @return void
|
||||
*/
|
||||
function __construct($xml_conditions)
|
||||
{
|
||||
parent::__construct($xml_conditions);
|
||||
$this->condition_groups[0]->conditions[0]->setPipe("");
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file JoinConditionsTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/condition/JoinConditionsTag.class.php */
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* GroupsTag class
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/xml/xmlquery/tags/group
|
||||
* @version 0.1
|
||||
*/
|
||||
class GroupsTag
|
||||
{
|
||||
|
||||
/**
|
||||
* column list
|
||||
* @var array
|
||||
*/
|
||||
var $groups;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param array|string $xml_groups
|
||||
* @return void
|
||||
*/
|
||||
function __construct($xml_groups)
|
||||
{
|
||||
$this->groups = array();
|
||||
|
||||
if($xml_groups)
|
||||
{
|
||||
if(!is_array($xml_groups))
|
||||
{
|
||||
$xml_groups = array($xml_groups);
|
||||
}
|
||||
|
||||
$dbParser = &DB::getParser();
|
||||
for($i = 0; $i < count($xml_groups); $i++)
|
||||
{
|
||||
$group = $xml_groups[$i];
|
||||
$column = trim($group->attrs->column);
|
||||
if(!$column)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$column = $dbParser->parseExpression($column);
|
||||
$this->groups[] = $column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
$output = 'array(' . PHP_EOL;
|
||||
foreach($this->groups as $group)
|
||||
{
|
||||
$output .= "'" . $group . "' ,";
|
||||
}
|
||||
$output = substr($output, 0, -1);
|
||||
$output .= ')';
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file GroupsTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/group/GroupsTag.class.php */
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* IndexTag class
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/xml/xmlquery/tags/navigation
|
||||
* @version 0.1
|
||||
*/
|
||||
class IndexTag
|
||||
{
|
||||
|
||||
/**
|
||||
* argument name
|
||||
* @var string
|
||||
*/
|
||||
var $argument_name;
|
||||
|
||||
/**
|
||||
* QueryArgument object
|
||||
* @var QueryArgument
|
||||
*/
|
||||
var $argument;
|
||||
|
||||
/**
|
||||
* Default value
|
||||
* @var string
|
||||
*/
|
||||
var $default;
|
||||
|
||||
/**
|
||||
* Sort order
|
||||
* @var string
|
||||
*/
|
||||
var $sort_order;
|
||||
|
||||
/**
|
||||
* Sort order argument
|
||||
* @var SortQueryArgument object
|
||||
*/
|
||||
var $sort_order_argument;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param object $index
|
||||
* @return void
|
||||
*/
|
||||
function __construct($index)
|
||||
{
|
||||
$this->argument_name = $index->attrs->var;
|
||||
|
||||
// Sort index - column by which to sort
|
||||
//$dbParser = new DB(); $dbParser = &$dbParser->getParser();
|
||||
//$index->attrs->default = $dbParser->parseExpression($index->attrs->default);
|
||||
$this->default = $index->attrs->default;
|
||||
$this->argument = new QueryArgument($index);
|
||||
|
||||
// Sort order - asc / desc
|
||||
$this->sort_order = $index->attrs->order;
|
||||
$sortList = array('asc' => 1, 'desc' => 1);
|
||||
if(!isset($sortList[$this->sort_order]))
|
||||
{
|
||||
$arg = new Xml_Node_();
|
||||
$arg->attrs = new Xml_Node_();
|
||||
$arg->attrs->var = $this->sort_order;
|
||||
$arg->attrs->default = 'asc';
|
||||
$this->sort_order_argument = new SortQueryArgument($arg);
|
||||
$this->sort_order = '$' . $this->sort_order_argument->getArgumentName() . '_argument';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->sort_order = '"' . $this->sort_order . '"';
|
||||
}
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
return sprintf('new OrderByColumn(${\'%s_argument\'}, %s)', $this->argument->getArgumentName(), $this->sort_order);
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
$arguments[] = $this->argument;
|
||||
if($this->sort_order_argument)
|
||||
{
|
||||
$arguments[] = $this->sort_order_argument;
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file IndexTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/navigation/IndexTag.class.php */
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* LimitTag class
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/xml/xmlquery/tags/navigation
|
||||
* @version 0.1
|
||||
*/
|
||||
class LimitTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Value is relate to limit query
|
||||
* @var array
|
||||
*/
|
||||
var $arguments;
|
||||
|
||||
/**
|
||||
* QueryArgument object
|
||||
* @var QueryArgument
|
||||
*/
|
||||
var $page;
|
||||
|
||||
/**
|
||||
* QueryArgument object
|
||||
* @var QueryArgument
|
||||
*/
|
||||
var $page_count;
|
||||
|
||||
/**
|
||||
* QueryArgument object
|
||||
* @var QueryArgument
|
||||
*/
|
||||
var $list_count;
|
||||
|
||||
/**
|
||||
* QueryArgument object
|
||||
* @var QueryArgument
|
||||
*/
|
||||
var $offset;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param object $index
|
||||
* @return void
|
||||
*/
|
||||
function __construct($index)
|
||||
{
|
||||
if($index->page && $index->page->attrs && $index->page_count && $index->page_count->attrs)
|
||||
{
|
||||
if(!isset($index->page->attrs->default))
|
||||
$index->page->attrs->default = 1;
|
||||
if(!isset($index->page_count->attrs->default))
|
||||
$index->page_count->attrs->default = 10;
|
||||
$this->page = new QueryArgument($index->page);
|
||||
$this->page_count = new QueryArgument($index->page_count);
|
||||
$this->arguments[] = $this->page;
|
||||
$this->arguments[] = $this->page_count;
|
||||
}
|
||||
|
||||
if(!isset($index->list_count->attrs->default))
|
||||
$index->list_count->attrs->default = 0;
|
||||
$this->list_count = new QueryArgument($index->list_count);
|
||||
$this->arguments[] = $this->list_count;
|
||||
|
||||
if(isset($index->offset) && isset($index->offset->attrs))
|
||||
{
|
||||
$this->offset = new QueryArgument($index->offset);
|
||||
$this->arguments[] = $this->offset;
|
||||
}
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
if($this->page)
|
||||
{
|
||||
return sprintf('new Limit(${\'%s_argument\'}, ${\'%s_argument\'}, ${\'%s_argument\'})', $this->list_count->getArgumentName(), $this->page->getArgumentName(), $this->page_count->getArgumentName());
|
||||
}
|
||||
elseif($this->offset)
|
||||
{
|
||||
return sprintf('new Limit(${\'%s_argument\'}, NULL, NULL, ${\'%s_argument\'})', $this->list_count->getArgumentName(), $this->offset->getArgumentName());
|
||||
}
|
||||
else
|
||||
{
|
||||
return sprintf('new Limit(${\'%s_argument\'})', $this->list_count->getArgumentName());
|
||||
}
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file LimitTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/navigation/LimitTag.class.php */
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* NavigationTag class
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/xml/xmlquery/tags/navigation
|
||||
* @version 0.1
|
||||
*/
|
||||
class NavigationTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Order
|
||||
* @var array
|
||||
*/
|
||||
var $order;
|
||||
|
||||
/**
|
||||
* List count
|
||||
* @var int
|
||||
*/
|
||||
var $list_count;
|
||||
|
||||
/**
|
||||
* Page count
|
||||
* @var int
|
||||
*/
|
||||
var $page_count;
|
||||
|
||||
/**
|
||||
* Page
|
||||
* @var int
|
||||
*/
|
||||
var $page;
|
||||
|
||||
/**
|
||||
* Limit
|
||||
* @var LimitTag object
|
||||
*/
|
||||
var $limit;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param object $xml_navigation
|
||||
* @return void
|
||||
*/
|
||||
function __construct($xml_navigation)
|
||||
{
|
||||
$this->order = array();
|
||||
if($xml_navigation)
|
||||
{
|
||||
$order = $xml_navigation->index;
|
||||
if($order)
|
||||
{
|
||||
if(!is_array($order))
|
||||
{
|
||||
$order = array($order);
|
||||
}
|
||||
foreach($order as $order_info)
|
||||
{
|
||||
$this->order[] = new IndexTag($order_info);
|
||||
}
|
||||
|
||||
if($xml_navigation->page && $xml_navigation->page->attrs || $xml_navigation->list_count && $xml_navigation->list_count->attrs)
|
||||
{
|
||||
$this->limit = new LimitTag($xml_navigation);
|
||||
}
|
||||
|
||||
if($xml_navigation->list_count)
|
||||
{
|
||||
$this->list_count = $xml_navigation->list_count->attrs;
|
||||
}
|
||||
|
||||
if($xml_navigation->page_count)
|
||||
{
|
||||
$this->page_count = $xml_navigation->page_count->attrs;
|
||||
}
|
||||
|
||||
if($xml_navigation->page)
|
||||
{
|
||||
$this->page = $xml_navigation->page->attrs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NavigationTag object to string
|
||||
* @return string
|
||||
*/
|
||||
function getOrderByString()
|
||||
{
|
||||
$output = 'array(' . PHP_EOL;
|
||||
foreach($this->order as $order)
|
||||
{
|
||||
$output .= $order->toString() . PHP_EOL . ',';
|
||||
}
|
||||
$output = substr($output, 0, -1);
|
||||
$output .= ')';
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* LimitTag object to string
|
||||
* @return string
|
||||
*/
|
||||
function getLimitString()
|
||||
{
|
||||
if($this->limit)
|
||||
{
|
||||
return $this->limit->toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
foreach($this->order as $order)
|
||||
{
|
||||
$arguments = array_merge($order->getArguments(), $arguments);
|
||||
}
|
||||
if($this->limit)
|
||||
{
|
||||
$arguments = array_merge($this->limit->getArguments(), $arguments);
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file NavigationTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/navigation/NavigationTag.class.php */
|
||||
|
|
@ -1,407 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* QueryTag class
|
||||
*
|
||||
* @author Arnia Software
|
||||
* @package /classes/xml/xmlquery/tags/query
|
||||
* @version 0.1
|
||||
*/
|
||||
class QueryTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Action for example, 'select', 'insert', 'delete'...
|
||||
* @var string
|
||||
*/
|
||||
var $action;
|
||||
|
||||
/**
|
||||
* Query id
|
||||
* @var string
|
||||
*/
|
||||
var $query_id;
|
||||
|
||||
/**
|
||||
* Priority
|
||||
* @var string
|
||||
*/
|
||||
var $priority;
|
||||
|
||||
/**
|
||||
* column type list
|
||||
* @var array
|
||||
*/
|
||||
var $column_type;
|
||||
|
||||
/**
|
||||
* Query stdClass object
|
||||
* @var object
|
||||
*/
|
||||
var $query;
|
||||
|
||||
/**
|
||||
* Columns in xml tags
|
||||
* @var object
|
||||
*/
|
||||
var $columns;
|
||||
|
||||
/**
|
||||
* Tables in xml tags
|
||||
* @var object
|
||||
*/
|
||||
var $tables;
|
||||
|
||||
/**
|
||||
* Subquery in xml tags
|
||||
* @var object
|
||||
*/
|
||||
var $subquery;
|
||||
|
||||
/**
|
||||
* Conditions in xml tags
|
||||
* @var object
|
||||
*/
|
||||
var $conditions;
|
||||
|
||||
/**
|
||||
* Groups in xml tags
|
||||
* @var object
|
||||
*/
|
||||
var $groups;
|
||||
|
||||
/**
|
||||
* Having in xml tags
|
||||
* @var object
|
||||
*/
|
||||
var $having;
|
||||
|
||||
/**
|
||||
* Navigation in xml tags
|
||||
* @var object
|
||||
*/
|
||||
var $navigation;
|
||||
|
||||
/**
|
||||
* Arguments in xml tags
|
||||
* @var object
|
||||
*/
|
||||
var $arguments;
|
||||
|
||||
/**
|
||||
* PreBuff
|
||||
* @var string
|
||||
*/
|
||||
var $preBuff;
|
||||
|
||||
/**
|
||||
* Buff
|
||||
* @var string
|
||||
*/
|
||||
var $buff;
|
||||
|
||||
/**
|
||||
* Subquery status
|
||||
* @var bool
|
||||
*/
|
||||
var $isSubQuery;
|
||||
|
||||
/**
|
||||
* Join type
|
||||
* @var string
|
||||
*/
|
||||
var $join_type;
|
||||
|
||||
/**
|
||||
* alias
|
||||
* @var string
|
||||
*/
|
||||
var $alias;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param object $query
|
||||
* @param bool $isSubQuery
|
||||
* @return void
|
||||
*/
|
||||
function __construct($query, $isSubQuery = FALSE)
|
||||
{
|
||||
$this->action = $query->attrs->action;
|
||||
$this->query_id = $query->attrs->id;
|
||||
$this->priority = $query->attrs->priority;
|
||||
$this->query = $query;
|
||||
$this->isSubQuery = $isSubQuery;
|
||||
if($this->isSubQuery)
|
||||
{
|
||||
$this->action = 'select';
|
||||
}
|
||||
if($query->attrs->alias)
|
||||
{
|
||||
$dbParser = DB::getParser();
|
||||
$this->alias = $dbParser->escape($query->attrs->alias);
|
||||
}
|
||||
$this->join_type = $query->attrs->join_type;
|
||||
|
||||
$this->getColumns();
|
||||
$tables = $this->getTables();
|
||||
$this->setTableColumnTypes($tables);
|
||||
$this->getSubquery(); // Used for insert-select
|
||||
$this->getConditions();
|
||||
$this->getGroups();
|
||||
$this->getNavigation();
|
||||
|
||||
$this->getPrebuff();
|
||||
$this->getBuff();
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function getQueryId()
|
||||
{
|
||||
return $this->query->attrs->query_id ? $this->query->attrs->query_id : $this->query->attrs->id;
|
||||
}
|
||||
|
||||
function getPriority()
|
||||
{
|
||||
return $this->query->attrs->priority;
|
||||
}
|
||||
|
||||
function getAction()
|
||||
{
|
||||
return $this->query->attrs->action;
|
||||
}
|
||||
|
||||
function setTableColumnTypes($tables)
|
||||
{
|
||||
$query_id = $this->getQueryId();
|
||||
if(!isset($this->column_type[$query_id]))
|
||||
{
|
||||
$table_tags = $tables->getTables();
|
||||
$column_type = array();
|
||||
foreach($table_tags as $table_tag)
|
||||
{
|
||||
if(is_a($table_tag, 'TableTag'))
|
||||
{
|
||||
$table_name = $table_tag->getTableName();
|
||||
$table_alias = $table_tag->getTableAlias();
|
||||
$tag_column_type = QueryParser::getTableInfo($query_id, $table_name);
|
||||
$column_type[$table_alias] = $tag_column_type;
|
||||
}
|
||||
}
|
||||
$this->column_type[$query_id] = $column_type;
|
||||
}
|
||||
}
|
||||
|
||||
function getColumns()
|
||||
{
|
||||
if($this->action == 'select')
|
||||
{
|
||||
return $this->columns = new SelectColumnsTag($this->query->columns);
|
||||
}
|
||||
else if($this->action == 'insert' || $this->action == 'insert-select')
|
||||
{
|
||||
return $this->columns = new InsertColumnsTag($this->query->columns->column);
|
||||
}
|
||||
else if($this->action == 'update')
|
||||
{
|
||||
return $this->columns = new UpdateColumnsTag($this->query->columns->column);
|
||||
}
|
||||
else if($this->action == 'delete')
|
||||
{
|
||||
return $this->columns = null;
|
||||
}
|
||||
}
|
||||
|
||||
function getPrebuff()
|
||||
{
|
||||
if($this->isSubQuery)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// TODO Check if this work with arguments in join clause
|
||||
$arguments = $this->getArguments();
|
||||
|
||||
$prebuff = '';
|
||||
foreach($arguments as $argument)
|
||||
{
|
||||
if(isset($argument))
|
||||
{
|
||||
$arg_name = $argument->getArgumentName();
|
||||
if($arg_name)
|
||||
{
|
||||
unset($column_type);
|
||||
$prebuff .= $argument->toString();
|
||||
|
||||
$table_alias = $argument->getTableName();
|
||||
if(isset($table_alias))
|
||||
{
|
||||
if(isset($this->column_type[$this->getQueryId()][$table_alias][$argument->getColumnName()]))
|
||||
{
|
||||
$column_type = $this->column_type[$this->getQueryId()][$table_alias][$argument->getColumnName()];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$current_tables = $this->column_type[$this->getQueryId()];
|
||||
$column_name = $argument->getColumnName();
|
||||
foreach($current_tables as $current_table)
|
||||
{
|
||||
if(isset($current_table[$column_name]))
|
||||
{
|
||||
$column_type = $current_table[$column_name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($column_type))
|
||||
{
|
||||
$prebuff .= sprintf('if(${\'%s_argument\'} !== null) ${\'%s_argument\'}->setColumnType(\'%s\');' . "\n"
|
||||
, $arg_name
|
||||
, $arg_name
|
||||
, $column_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$prebuff .= "\n";
|
||||
|
||||
return $this->preBuff = $prebuff;
|
||||
}
|
||||
|
||||
function getBuff()
|
||||
{
|
||||
$buff = '';
|
||||
if($this->isSubQuery)
|
||||
{
|
||||
$buff = 'new Subquery(';
|
||||
$buff .= "'" . $this->alias . '\', ';
|
||||
$buff .= ($this->columns ? $this->columns->toString() : 'null' ) . ', ' . PHP_EOL;
|
||||
$buff .= $this->tables->toString() . ',' . PHP_EOL;
|
||||
$buff .= $this->conditions->toString() . ',' . PHP_EOL;
|
||||
$buff .= $this->groups->toString() . ',' . PHP_EOL;
|
||||
$buff .= $this->navigation->getOrderByString() . ',' . PHP_EOL;
|
||||
$limit = $this->navigation->getLimitString();
|
||||
$buff .= $limit ? $limit : 'null' . PHP_EOL;
|
||||
$buff .= $this->join_type ? "'" . $this->join_type . "'" : '';
|
||||
$buff .= ')';
|
||||
|
||||
$this->buff = $buff;
|
||||
return $this->buff;
|
||||
}
|
||||
|
||||
$buff .= '$query = new Query();' . PHP_EOL;
|
||||
$buff .= sprintf('$query->setQueryId("%s");%s', $this->query_id, "\n");
|
||||
$buff .= sprintf('$query->setAction("%s");%s', $this->action, "\n");
|
||||
$buff .= sprintf('$query->setPriority("%s");%s', $this->priority, "\n");
|
||||
$buff .= $this->preBuff;
|
||||
if($this->columns)
|
||||
{
|
||||
$buff .= '$query->setColumns(' . $this->columns->toString() . ');' . PHP_EOL;
|
||||
}
|
||||
|
||||
$buff .= '$query->setTables(' . $this->tables->toString() . ');' . PHP_EOL;
|
||||
if($this->action == 'insert-select')
|
||||
{
|
||||
$buff .= '$query->setSubquery(' . $this->subquery->toString() . ');' . PHP_EOL;
|
||||
}
|
||||
$buff .= '$query->setConditions(' . $this->conditions->toString() . ');' . PHP_EOL;
|
||||
$buff .= '$query->setGroups(' . $this->groups->toString() . ');' . PHP_EOL;
|
||||
$buff .= '$query->setHaving(' . $this->having->toString() . ');' . PHP_EOL;
|
||||
$buff .= '$query->setOrder(' . $this->navigation->getOrderByString() . ');' . PHP_EOL;
|
||||
$buff .= '$query->setLimit(' . $this->navigation->getLimitString() . ');' . PHP_EOL;
|
||||
|
||||
$this->buff = $buff;
|
||||
return $this->buff;
|
||||
}
|
||||
|
||||
function getTables()
|
||||
{
|
||||
if($this->query->index_hint && ($this->query->index_hint->attrs->for == 'ALL' || Context::getDBType() == strtolower($this->query->index_hint->attrs->for)))
|
||||
{
|
||||
return $this->tables = new TablesTag($this->query->tables, $this->query->index_hint);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->tables = new TablesTag($this->query->tables);
|
||||
}
|
||||
}
|
||||
|
||||
function getSubquery()
|
||||
{
|
||||
if($this->query->query)
|
||||
{
|
||||
$this->subquery = new QueryTag($this->query->query, true);
|
||||
}
|
||||
}
|
||||
|
||||
function getConditions()
|
||||
{
|
||||
return $this->conditions = new ConditionsTag($this->query->conditions);
|
||||
}
|
||||
|
||||
function getGroups()
|
||||
{
|
||||
if($this->query->groups)
|
||||
{
|
||||
$this->groups = new GroupsTag($this->query->groups->group);
|
||||
$this->having = new ConditionsTag($this->query->groups->having);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->groups = new GroupsTag(NULL);
|
||||
$this->having = new ConditionsTag(array());
|
||||
}
|
||||
|
||||
return $this->groups;
|
||||
}
|
||||
|
||||
function getNavigation()
|
||||
{
|
||||
return $this->navigation = new NavigationTag($this->query->navigation);
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
return $this->buff;
|
||||
}
|
||||
|
||||
function getTableString()
|
||||
{
|
||||
return $this->buff;
|
||||
}
|
||||
|
||||
function getConditionString()
|
||||
{
|
||||
return $this->buff;
|
||||
}
|
||||
|
||||
function getExpressionString()
|
||||
{
|
||||
return $this->buff;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
if($this->columns)
|
||||
{
|
||||
$arguments = array_merge($arguments, $this->columns->getArguments());
|
||||
}
|
||||
if($this->action == 'insert-select')
|
||||
{
|
||||
$arguments = array_merge($arguments, $this->subquery->getArguments());
|
||||
}
|
||||
$arguments = array_merge($arguments, $this->tables->getArguments());
|
||||
$arguments = array_merge($arguments, $this->conditions->getArguments());
|
||||
$arguments = array_merge($arguments, $this->having->getArguments());
|
||||
$arguments = array_merge($arguments, $this->navigation->getArguments());
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file QueryTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/navigation/QueryTag.class.php */
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* HintTableTag
|
||||
* Models the <table> tag inside an XML Query file and the corresponding <index_hint> tag
|
||||
*
|
||||
* @author Arnia Sowftare
|
||||
* @package /classes/xml/xmlquery/tags/table
|
||||
* @version 0.1
|
||||
*/
|
||||
class HintTableTag extends TableTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Action for example, 'select', 'insert', 'delete'...
|
||||
* @var array
|
||||
*/
|
||||
var $index;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* Initialises Table Tag properties
|
||||
* @param object $table XML <table> tag
|
||||
* @param array $index
|
||||
* @return void
|
||||
*/
|
||||
function __construct($table, $index)
|
||||
{
|
||||
parent::__construct($table);
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
function getTableString()
|
||||
{
|
||||
$dbParser = DB::getParser();
|
||||
$dbType = ucfirst(Context::getDBType());
|
||||
|
||||
$result = sprintf('new %sTableWithHint(\'%s\'%s, array('
|
||||
, starts_with('mysql', $dbType, false) ? 'Mysql' : $dbType
|
||||
, $dbParser->escape($this->name)
|
||||
, $this->alias ? ', \'' . $dbParser->escape($this->alias) . '\'' : ', null'
|
||||
//, ', \'' . $dbParser->escape($this->index->name) .'\', \'' . $this->index->type .'\''
|
||||
);
|
||||
foreach($this->index as $indx)
|
||||
{
|
||||
$result .= "new IndexHint(";
|
||||
$result .= '\'' . $dbParser->escape($indx->name) . '\', \'' . $indx->type . '\'' . ') , ';
|
||||
}
|
||||
$result = substr($result, 0, -2);
|
||||
$result .= '))';
|
||||
return $result;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
if(!isset($this->conditionsTag))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
return $this->conditionsTag->getArguments();
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file HintTableTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/table/HintTableTag.class.php */
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* TableTag
|
||||
* Models the <table> tag inside an XML Query file
|
||||
* @abstract
|
||||
* Example
|
||||
* <table name="modules" />
|
||||
* <table name="documents" alias="doc" />
|
||||
* Attributes
|
||||
* name - name of the table - table prefix will be automatically added
|
||||
* alias - table alias. If no value is specified, the table name will be set as default alias
|
||||
* join_type - in case the table is part of a join clause, this specifies the type of join: left, right etc.
|
||||
* - permitted values: 'left join','left outer join','right join','right outer join'
|
||||
* Children
|
||||
* Can have children of type <conditions>
|
||||
*
|
||||
* @author Arnia Sowftare
|
||||
* @package /classes/xml/xmlquery/tags/table
|
||||
* @version 0.1
|
||||
*/
|
||||
class TableTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Unescaped name
|
||||
* @var string
|
||||
*/
|
||||
var $unescaped_name;
|
||||
|
||||
/**
|
||||
* name
|
||||
* @var string
|
||||
*/
|
||||
var $name;
|
||||
|
||||
/**
|
||||
* alias
|
||||
* @var string
|
||||
*/
|
||||
var $alias;
|
||||
|
||||
/**
|
||||
* Join type
|
||||
* @example 'left join', 'left outer join', 'right join', 'right outer join'
|
||||
* @var string
|
||||
*/
|
||||
var $join_type;
|
||||
|
||||
/**
|
||||
* Condition object
|
||||
* @var object
|
||||
*/
|
||||
var $conditions;
|
||||
|
||||
/**
|
||||
* JoinConditionsTag
|
||||
* @var JoinConditionsTag object
|
||||
*/
|
||||
var $conditionsTag;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* Initialises Table Tag properties
|
||||
* @param object $table XML <table> tag
|
||||
* @return void
|
||||
*/
|
||||
function __construct($table)
|
||||
{
|
||||
$dbParser = DB::getParser();
|
||||
|
||||
$this->unescaped_name = $table->attrs->name;
|
||||
$this->name = $dbParser->parseTableName($table->attrs->name);
|
||||
|
||||
$this->alias = $table->attrs->alias;
|
||||
if(!$this->alias)
|
||||
{
|
||||
$this->alias = $table->attrs->name;
|
||||
}
|
||||
|
||||
$this->join_type = $table->attrs->type;
|
||||
|
||||
$this->conditions = $table->conditions;
|
||||
|
||||
if($this->isJoinTable())
|
||||
{
|
||||
$this->conditionsTag = new JoinConditionsTag($this->conditions);
|
||||
}
|
||||
}
|
||||
|
||||
function isJoinTable()
|
||||
{
|
||||
$joinList = array('left join' => 1, 'left outer join' => 1, 'right join' => 1, 'right outer join' => 1);
|
||||
if(isset($joinList[$this->join_type]) && countobj($this->conditions))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getTableAlias()
|
||||
{
|
||||
return $this->alias;
|
||||
}
|
||||
|
||||
function getTableName()
|
||||
{
|
||||
return $this->unescaped_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string for printing in PHP query cache file
|
||||
* The string contains code for instantiation of either
|
||||
* a Table or a JoinTable object
|
||||
* @return string
|
||||
*/
|
||||
function getTableString()
|
||||
{
|
||||
$dbParser = DB::getParser();
|
||||
|
||||
if($this->isJoinTable())
|
||||
{
|
||||
return sprintf('new JoinTable(\'%s\', \'%s\', "%s", %s)'
|
||||
, $dbParser->escape($this->name)
|
||||
, $dbParser->escape($this->alias)
|
||||
, $this->join_type, $this->conditionsTag->toString());
|
||||
}
|
||||
return sprintf('new Table(\'%s\'%s)'
|
||||
, $dbParser->escape($this->name)
|
||||
, $this->alias ? ', \'' . $dbParser->escape($this->alias) . '\'' : '');
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
if(!isset($this->conditionsTag))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
return $this->conditionsTag->getArguments();
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file TableTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/table/TableTag.class.php */
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
<?php
|
||||
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
||||
|
||||
/**
|
||||
* TablesTag class
|
||||
* Models the <tables> tag inside an XML Query file
|
||||
* @abstract
|
||||
* Example
|
||||
* <tables>
|
||||
* <table name="documents" alias="doc" />
|
||||
* </tables>
|
||||
* Attributes
|
||||
* None.
|
||||
* Children
|
||||
* Can have children of type <table> or <query>
|
||||
*
|
||||
* @author Arnia Sowftare
|
||||
* @package /classes/xml/xmlquery/tags/table
|
||||
* @version 0.1
|
||||
*/
|
||||
class TablesTag
|
||||
{
|
||||
|
||||
/**
|
||||
* Table list
|
||||
* @var array
|
||||
*/
|
||||
var $tables;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param object $xml_tables_tag
|
||||
* @param object $xml_index_hints_tag
|
||||
* @return void
|
||||
*/
|
||||
function __construct($xml_tables_tag, $xml_index_hints_tag = NULL)
|
||||
{
|
||||
$this->tables = array();
|
||||
|
||||
$xml_tables = $xml_tables_tag->table;
|
||||
if(!is_array($xml_tables))
|
||||
{
|
||||
$xml_tables = array($xml_tables);
|
||||
}
|
||||
|
||||
if($xml_index_hints_tag)
|
||||
{
|
||||
$index_nodes = $xml_index_hints_tag->index;
|
||||
if(!is_array($index_nodes))
|
||||
{
|
||||
$index_nodes = array($index_nodes);
|
||||
}
|
||||
foreach($index_nodes as $index_node)
|
||||
{
|
||||
if(!isset($indexes[$index_node->attrs->table]))
|
||||
{
|
||||
$indexes[$index_node->attrs->table] = array();
|
||||
}
|
||||
$count = count($indexes[$index_node->attrs->table]);
|
||||
$indexes[$index_node->attrs->table][$count] = (object) NULL;
|
||||
$indexes[$index_node->attrs->table][$count]->name = $index_node->attrs->name;
|
||||
$indexes[$index_node->attrs->table][$count]->type = $index_node->attrs->type;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($xml_tables as $tag)
|
||||
{
|
||||
if($tag->attrs->query == 'true')
|
||||
{
|
||||
$this->tables[] = new QueryTag($tag, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isset($indexes[$tag->attrs->name]) && $indexes[$tag->attrs->name])
|
||||
{
|
||||
$this->tables[] = new HintTableTag($tag, $indexes[$tag->attrs->name]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->tables[] = new TableTag($tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTables()
|
||||
{
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
$output_tables = 'array(' . PHP_EOL;
|
||||
foreach($this->tables as $table)
|
||||
{
|
||||
if(is_a($table, 'QueryTag'))
|
||||
{
|
||||
$output_tables .= $table->toString() . PHP_EOL . ',';
|
||||
}
|
||||
else
|
||||
{
|
||||
$output_tables .= $table->getTableString() . PHP_EOL . ',';
|
||||
}
|
||||
}
|
||||
$output_tables = substr($output_tables, 0, -1);
|
||||
$output_tables .= ')';
|
||||
return $output_tables;
|
||||
}
|
||||
|
||||
function getArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
foreach($this->tables as $table)
|
||||
{
|
||||
$arguments = array_merge($arguments, $table->getArguments());
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
}
|
||||
/* End of file TablesTag.class.php */
|
||||
/* Location: ./classes/xml/xmlquery/tags/table/TablesTag.class.php */
|
||||
|
|
@ -49,27 +49,6 @@ $GLOBALS['RX_AUTOLOAD_FILE_MAP'] = array_change_key_case(array(
|
|||
'CacheHandler' => 'classes/cache/CacheHandler.class.php',
|
||||
'Context' => 'classes/context/Context.class.php',
|
||||
'DB' => 'classes/db/DB.class.php',
|
||||
'Query' => 'classes/db/queryparts/Query.class.php',
|
||||
'Subquery' => 'classes/db/queryparts/Subquery.class.php',
|
||||
'Condition' => 'classes/db/queryparts/condition/Condition.class.php',
|
||||
'ConditionGroup' => 'classes/db/queryparts/condition/ConditionGroup.class.php',
|
||||
'ConditionSubquery' => 'classes/db/queryparts/condition/ConditionSubquery.class.php',
|
||||
'ConditionWithArgument' => 'classes/db/queryparts/condition/ConditionWithArgument.class.php',
|
||||
'ConditionWithoutArgument' => 'classes/db/queryparts/condition/ConditionWithoutArgument.class.php',
|
||||
'ClickCountExpression' => 'classes/db/queryparts/expression/ClickCountExpression.class.php',
|
||||
'DeleteExpression' => 'classes/db/queryparts/expression/DeleteExpression.class.php',
|
||||
'Expression' => 'classes/db/queryparts/expression/Expression.class.php',
|
||||
'InsertExpression' => 'classes/db/queryparts/expression/InsertExpression.class.php',
|
||||
'SelectExpression' => 'classes/db/queryparts/expression/SelectExpression.class.php',
|
||||
'StarExpression' => 'classes/db/queryparts/expression/StarExpression.class.php',
|
||||
'UpdateExpression' => 'classes/db/queryparts/expression/UpdateExpression.class.php',
|
||||
'UpdateExpressionWithoutArgument' => 'classes/db/queryparts/expression/UpdateExpressionWithoutArgument.class.php',
|
||||
'Limit' => 'classes/db/queryparts/limit/Limit.class.php',
|
||||
'OrderByColumn' => 'classes/db/queryparts/order/OrderByColumn.class.php',
|
||||
'IndexHint' => 'classes/db/queryparts/table/IndexHint.class.php',
|
||||
'JoinTable' => 'classes/db/queryparts/table/JoinTable.class.php',
|
||||
'MysqlTableWithHint' => 'classes/db/queryparts/table/MysqlTableWithHint.class.php',
|
||||
'Table' => 'classes/db/queryparts/table/Table.class.php',
|
||||
'DisplayHandler' => 'classes/display/DisplayHandler.class.php',
|
||||
'HTMLDisplayHandler' => 'classes/display/HTMLDisplayHandler.php',
|
||||
'JSCallbackDisplayHandler' => 'classes/display/JSCallbackDisplayHandler.php',
|
||||
|
|
@ -104,36 +83,6 @@ $GLOBALS['RX_AUTOLOAD_FILE_MAP'] = array_change_key_case(array(
|
|||
'XmlJsFilter' => 'classes/xml/XmlJsFilter.class.php',
|
||||
'XmlLangParser' => 'classes/xml/XmlLangParser.class.php',
|
||||
'XmlParser' => 'classes/xml/XmlParser.class.php',
|
||||
'XmlQueryParser' => 'classes/xml/XmlQueryParser.class.php',
|
||||
'DBParser' => 'classes/xml/xmlquery/DBParser.class.php',
|
||||
'QueryParser' => 'classes/xml/xmlquery/QueryParser.class.php',
|
||||
'Argument' => 'classes/xml/xmlquery/argument/Argument.class.php',
|
||||
'ConditionArgument' => 'classes/xml/xmlquery/argument/ConditionArgument.class.php',
|
||||
'SortArgument' => 'classes/xml/xmlquery/argument/SortArgument.class.php',
|
||||
'DefaultValue' => 'classes/xml/xmlquery/queryargument/DefaultValue.class.php',
|
||||
'QueryArgument' => 'classes/xml/xmlquery/queryargument/QueryArgument.class.php',
|
||||
'SortQueryArgument' => 'classes/xml/xmlquery/queryargument/SortQueryArgument.class.php',
|
||||
'QueryArgumentValidator' => 'classes/xml/xmlquery/queryargument/validator/QueryArgumentValidator.class.php',
|
||||
'ColumnTag' => 'classes/xml/xmlquery/tags/column/ColumnTag.class.php',
|
||||
'InsertColumnTag' => 'classes/xml/xmlquery/tags/column/InsertColumnTag.class.php',
|
||||
'InsertColumnTagWithoutArgument' => 'classes/xml/xmlquery/tags/column/InsertColumnTagWithoutArgument.class.php',
|
||||
'InsertColumnsTag' => 'classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php',
|
||||
'SelectColumnTag' => 'classes/xml/xmlquery/tags/column/SelectColumnTag.class.php',
|
||||
'SelectColumnsTag' => 'classes/xml/xmlquery/tags/column/SelectColumnsTag.class.php',
|
||||
'UpdateColumnTag' => 'classes/xml/xmlquery/tags/column/UpdateColumnTag.class.php',
|
||||
'UpdateColumnsTag' => 'classes/xml/xmlquery/tags/column/UpdateColumnsTag.class.php',
|
||||
'ConditionGroupTag' => 'classes/xml/xmlquery/tags/condition/ConditionGroupTag.class.php',
|
||||
'ConditionTag' => 'classes/xml/xmlquery/tags/condition/ConditionTag.class.php',
|
||||
'ConditionsTag' => 'classes/xml/xmlquery/tags/condition/ConditionsTag.class.php',
|
||||
'JoinConditionsTag' => 'classes/xml/xmlquery/tags/condition/JoinConditionsTag.class.php',
|
||||
'GroupsTag' => 'classes/xml/xmlquery/tags/group/GroupsTag.class.php',
|
||||
'IndexTag' => 'classes/xml/xmlquery/tags/navigation/IndexTag.class.php',
|
||||
'LimitTag' => 'classes/xml/xmlquery/tags/navigation/LimitTag.class.php',
|
||||
'NavigationTag' => 'classes/xml/xmlquery/tags/navigation/NavigationTag.class.php',
|
||||
'QueryTag' => 'classes/xml/xmlquery/tags/query/QueryTag.class.php',
|
||||
'HintTableTag' => 'classes/xml/xmlquery/tags/table/HintTableTag.class.php',
|
||||
'TableTag' => 'classes/xml/xmlquery/tags/table/TableTag.class.php',
|
||||
'TablesTag' => 'classes/xml/xmlquery/tags/table/TablesTag.class.php',
|
||||
'Bmp' => 'common/libraries/bmp.php',
|
||||
'Ftp' => 'common/libraries/ftp.php',
|
||||
'Tar' => 'common/libraries/tar.php',
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ return array(
|
|||
),
|
||||
),
|
||||
'cache' => array(
|
||||
'type' => null,
|
||||
'ttl' => 86400,
|
||||
'servers' => array(),
|
||||
'truncate_method' => 'delete',
|
||||
),
|
||||
'ftp' => array(
|
||||
|
|
@ -50,6 +53,7 @@ return array(
|
|||
'http_port' => null,
|
||||
'https_port' => null,
|
||||
'ssl' => 'none',
|
||||
'rewrite' => 1,
|
||||
),
|
||||
'session' => array(
|
||||
'delay' => false,
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ foreach ($ranges as $range)
|
|||
$content = '<' . '?php' . "\n\n" . '/**' . "\n" . ' * Source: ' . $referer_url . "\n";
|
||||
$content .= ' * Last Updated: ' . date('Y-m-d') . "\n" . ' */' . "\n";
|
||||
$content .= 'return ' . var_export($ranges_final, true) . ';' . "\n";
|
||||
file_put_contents(__DIR__ . '/../../common/defaults/korea.ipv4.php', $content);
|
||||
file_put_contents(__DIR__ . '/../korea.ipv4.php', $content);
|
||||
|
||||
/**
|
||||
* Report status.
|
||||
|
|
@ -84,7 +84,7 @@ foreach ($ranges as $range)
|
|||
$content = '<' . '?php' . "\n\n" . '/**' . "\n" . ' * Source: ' . $referer_url . "\n";
|
||||
$content .= ' * Last Updated: ' . date('Y-m-d') . "\n" . ' */' . "\n";
|
||||
$content .= 'return ' . var_export($ranges_final, true) . ';' . "\n";
|
||||
file_put_contents(__DIR__ . '/../../common/defaults/korea.ipv6.php', $content);
|
||||
file_put_contents(__DIR__ . '/../korea.ipv6.php', $content);
|
||||
|
||||
/**
|
||||
* Report status.
|
||||
|
|
@ -140,14 +140,9 @@ class Config
|
|||
$result = Storage::write(\RX_BASEDIR . self::$config_filename, $buff) ? true : false;
|
||||
|
||||
// Save XE-compatible config files.
|
||||
$db_info = \Context::convertDBInfo(self::$_config);
|
||||
$ftp_info = $db_info->ftp_info;
|
||||
$db_info_without_ftp = clone $db_info;
|
||||
unset($db_info_without_ftp->ftp_info);
|
||||
$warning = '// DO NOT EDIT THIS FILE. CHANGES WILL NOT BE APPLIED.' . "\n" . '// TO CHANGE RHYMIX SYSTEM CONFIGURATION, EDIT config.php INSTEAD.';
|
||||
$buff = '<?php' . "\n\n" . $warning . "\n\n" . '$db_info = ' . self::serialize($db_info_without_ftp) . ';' . "\n";
|
||||
$warning = '// THIS FILE IS NOT USED IN RHYMIX.' . "\n" . '// TO MODIFY SYSTEM CONFIGURATION, EDIT config.php INSTEAD.';
|
||||
$buff = '<?php' . "\n" . $warning . "\n";
|
||||
Storage::write(\RX_BASEDIR . self::$old_db_config_filename, $buff);
|
||||
$buff = '<?php' . "\n\n" . $warning . "\n\n" . '$ftp_info = ' . self::serialize($ftp_info) . ';' . "\n";
|
||||
Storage::write(\RX_BASEDIR . self::$old_ftp_config_filename, $buff);
|
||||
return $result;
|
||||
}
|
||||
|
|
|
|||
1306
common/framework/db.php
Normal file
1306
common/framework/db.php
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -355,7 +355,7 @@ class Debug
|
|||
'query_id' => $query['query_id'],
|
||||
'query_connection' => $query['connection'],
|
||||
'query_string' => $query['query'],
|
||||
'query_time' => $query['elapsed_time'],
|
||||
'query_time' => floatval($query['elapsed_time']),
|
||||
'file' => $query['called_file'],
|
||||
'line' => $query['called_line'],
|
||||
'method' => $query['called_method'],
|
||||
|
|
@ -746,6 +746,7 @@ class Debug
|
|||
public static function getDebugData()
|
||||
{
|
||||
// Collect debug information.
|
||||
$db = DB::getInstance();
|
||||
$data = (object)array(
|
||||
'timestamp' => DateTime::formatTimestamp('Y-m-d H:i:s', \RX_TIME),
|
||||
'url' => getCurrentPageUrl(),
|
||||
|
|
@ -761,8 +762,8 @@ class Debug
|
|||
'total' => sprintf('%0.4f sec', microtime(true) - \RX_MICROTIME),
|
||||
'template' => sprintf('%0.4f sec (count: %d)', $GLOBALS['__template_elapsed__'], $GLOBALS['__TemplateHandlerCalled__']),
|
||||
'xmlparse' => sprintf('%0.4f sec', $GLOBALS['__xmlparse_elapsed__']),
|
||||
'db_query' => sprintf('%0.4f sec (count: %d)', $GLOBALS['__db_elapsed_time__'], count(self::$_queries)),
|
||||
'db_class' => sprintf('%0.4f sec', $GLOBALS['__dbclass_elapsed_time__'] - $GLOBALS['__db_elapsed_time__']),
|
||||
'db_query' => sprintf('%0.4f sec (count: %d)', $db->getQueryElapsedTime(), count(self::$_queries)),
|
||||
'db_class' => sprintf('%0.4f sec', $db->getTotalElapsedTime() - $db->getQueryElapsedTime()),
|
||||
'layout' => sprintf('%0.4f sec', $GLOBALS['__layout_compile_elapsed__']),
|
||||
'widget' => sprintf('%0.4f sec', $GLOBALS['__widget_excute_elapsed__']),
|
||||
'remote' => sprintf('%0.4f sec', $GLOBALS['__remote_request_elapsed__']),
|
||||
|
|
|
|||
87
common/framework/drivers/push/apns.php
Normal file
87
common/framework/drivers/push/apns.php
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Drivers\Push;
|
||||
|
||||
/**
|
||||
* The APNs (Apple) Push driver.
|
||||
*/
|
||||
class APNs extends Base implements \Rhymix\Framework\Drivers\PushInterface
|
||||
{
|
||||
/**
|
||||
* Config keys used by this driver are stored here.
|
||||
*/
|
||||
protected static $_required_config = array('certificate', 'passphrase');
|
||||
protected static $_optional_config = array();
|
||||
|
||||
/**
|
||||
* Get the human-readable name of this Push driver.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'iOS (APNs)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current Push driver is supported on this server.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupported(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @param object $message
|
||||
* @param array $tokens
|
||||
* @return object
|
||||
*/
|
||||
public function send(\Rhymix\Framework\Push $message, array $tokens)
|
||||
{
|
||||
$output = new \stdClass;
|
||||
$output->success = [];
|
||||
$output->invalid = [];
|
||||
$output->needUpdate = [];
|
||||
|
||||
// Set parameters
|
||||
$local_cert = $this->_config['certificate'];
|
||||
$passphrase = $this->_config['passphrase'];
|
||||
$alert = [];
|
||||
$alert['title'] = $message->getSubject();
|
||||
$alert['body'] = $message->getContent();
|
||||
|
||||
$body['aps'] = array('alert' => $alert);
|
||||
$payload = json_encode($body);
|
||||
|
||||
foreach($tokens as $token)
|
||||
{
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_option($ctx, 'ssl', 'local_cert', $local_cert);
|
||||
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
|
||||
|
||||
$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 5, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
|
||||
if(!$fp)
|
||||
{
|
||||
$message->addError('Failed to connect socket - error code: '. $err .' - '. $errstr);
|
||||
}
|
||||
$msg = chr(0) . pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload;
|
||||
$result = fwrite($fp, $msg, strlen($msg));
|
||||
if(!$result)
|
||||
{
|
||||
$message->addError('APNs return empty response.');
|
||||
}
|
||||
$output->success[] = $token;
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
97
common/framework/drivers/push/base.php
Normal file
97
common/framework/drivers/push/base.php
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Drivers\Push;
|
||||
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* The base class for other Push drivers.
|
||||
*/
|
||||
abstract class Base implements \Rhymix\Framework\Drivers\PushInterface
|
||||
{
|
||||
/**
|
||||
* The configuration is stored here.
|
||||
*/
|
||||
protected $_config = null;
|
||||
|
||||
/**
|
||||
* Config keys used by this driver are stored here.
|
||||
*/
|
||||
protected static $_required_config = array();
|
||||
protected static $_optional_config = array();
|
||||
|
||||
/**
|
||||
* Direct invocation of the constructor is not permitted.
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
$this->_config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the current Push driver, using the given settings.
|
||||
*
|
||||
* @param array $config
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance(array $config): object
|
||||
{
|
||||
return new static($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the human-readable name of this Push driver.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return class_basename(get_called_class());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of configuration fields required by this Push driver.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getRequiredConfig(): array
|
||||
{
|
||||
return static::$_required_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of configuration fields optionally used by this Push driver.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getOptionalConfig(): array
|
||||
{
|
||||
return static::$_optional_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current Push driver is supported on this server.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupported(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @param object $message
|
||||
* @param array $tokens
|
||||
* @return object
|
||||
*/
|
||||
public function send(\Rhymix\Framework\Push $message, array $tokens)
|
||||
{
|
||||
return new \stdClass;
|
||||
}
|
||||
}
|
||||
114
common/framework/drivers/push/fcm.php
Normal file
114
common/framework/drivers/push/fcm.php
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Drivers\Push;
|
||||
|
||||
/**
|
||||
* The FCM (Google) Push driver.
|
||||
*/
|
||||
class FCM extends Base implements \Rhymix\Framework\Drivers\PushInterface
|
||||
{
|
||||
/**
|
||||
* Config keys used by this driver are stored here.
|
||||
*/
|
||||
protected static $_required_config = array('api_key');
|
||||
protected static $_optional_config = array();
|
||||
|
||||
/**
|
||||
* Get the human-readable name of this Push driver.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'Android (FCM)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current Push driver is supported on this server.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupported(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @param object $message
|
||||
* @param array $tokens
|
||||
* @return object
|
||||
*/
|
||||
public function send(\Rhymix\Framework\Push $message, array $tokens)
|
||||
{
|
||||
$output = new \stdClass;
|
||||
$output->success = [];
|
||||
$output->invalid = [];
|
||||
$output->needUpdate = [];
|
||||
|
||||
$url = 'https://fcm.googleapis.com/fcm/send';
|
||||
$api_key = $this->_config['api_key'];
|
||||
$headers = array(
|
||||
'Authorization' => 'key=' . $api_key,
|
||||
'Content-Type' => 'application/json',
|
||||
);
|
||||
|
||||
// Set notification
|
||||
$notification = [];
|
||||
$notification['title'] = $message->getSubject();
|
||||
$notification['body'] = $message->getContent();
|
||||
if($message->getClickAction())
|
||||
{
|
||||
$notification['click_action'] = $message->getClickAction();
|
||||
}
|
||||
|
||||
$chunked_token = array_chunk($tokens, 1000);
|
||||
foreach($chunked_token as $token_unit)
|
||||
{
|
||||
$data = json_encode(array(
|
||||
'registration_ids' => $token_unit,
|
||||
'notification' => $notification,
|
||||
'priority' => 'normal',
|
||||
'data' => $message->getData() ?: new \stdClass,
|
||||
));
|
||||
|
||||
$response = \FileHandler::getRemoteResource($url, $data, 5, 'POST', 'application/json', $headers);
|
||||
if($response)
|
||||
{
|
||||
$decoded_response = json_decode($response);
|
||||
if(!$decoded_response)
|
||||
{
|
||||
$message->addError('FCM return invalid json : '. $response);
|
||||
return $output;
|
||||
}
|
||||
$results = $decoded_response->results ?: [];
|
||||
foreach($results as $i => $result)
|
||||
{
|
||||
if($result->error)
|
||||
{
|
||||
$message->addError('FCM error code: '. $result->error);
|
||||
$output->invalid[$token_unit[$i]] = $token_unit[$i];
|
||||
}
|
||||
else if($result->message_id && $result->registration_id)
|
||||
{
|
||||
$output->needUpdate[$token_unit[$i]] = $result->registration_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$output->success[$token_unit[$i]] = $result->message_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$message->addError('FCM return empty response.');
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
58
common/framework/drivers/pushinterface.php
Normal file
58
common/framework/drivers/pushinterface.php
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Drivers;
|
||||
|
||||
/**
|
||||
* The Push driver interface.
|
||||
*/
|
||||
interface PushInterface
|
||||
{
|
||||
/**
|
||||
* Create a new instance of the current Push driver, using the given settings.
|
||||
*
|
||||
* @param array $config
|
||||
* @return void
|
||||
*/
|
||||
public static function getInstance(array $config): object;
|
||||
|
||||
/**
|
||||
* Get the human-readable name of this Push driver.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getName(): string;
|
||||
|
||||
/**
|
||||
* Get the list of configuration fields required by this Push driver.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getRequiredConfig(): array;
|
||||
|
||||
/**
|
||||
* Get the list of configuration fields optionally used by this Push driver.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getOptionalConfig(): array;
|
||||
|
||||
/**
|
||||
* Check if the current SMS driver is supported on this server.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupported(): bool;
|
||||
|
||||
/**
|
||||
* Send a message.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @param object $message
|
||||
* @param array $tokens
|
||||
* @return object
|
||||
*/
|
||||
public function send(\Rhymix\Framework\Push $message, array $tokens);
|
||||
}
|
||||
141
common/framework/drivers/sms/apistore.php
Normal file
141
common/framework/drivers/sms/apistore.php
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Drivers\SMS;
|
||||
|
||||
/**
|
||||
* The ApiStore SMS driver.
|
||||
*/
|
||||
class ApiStore extends Base implements \Rhymix\Framework\Drivers\SMSInterface
|
||||
{
|
||||
/**
|
||||
* API specifications.
|
||||
*/
|
||||
protected static $_spec = array(
|
||||
'max_recipients' => 500,
|
||||
'sms_max_length' => 90,
|
||||
'sms_max_length_in_charset' => 'CP949',
|
||||
'lms_supported' => true,
|
||||
'lms_supported_country_codes' => array(82),
|
||||
'lms_max_length' => 2000,
|
||||
'lms_max_length_in_charset' => 'CP949',
|
||||
'lms_subject_supported' => true,
|
||||
'lms_subject_max_length' => 60,
|
||||
'mms_supported' => false,
|
||||
'delay_supported' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Config keys used by this driver are stored here.
|
||||
*/
|
||||
protected static $_required_config = array('api_user', 'api_key');
|
||||
|
||||
/**
|
||||
* Check if the current SMS driver is supported on this server.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the last response.
|
||||
*/
|
||||
protected $_last_response = '';
|
||||
|
||||
/**
|
||||
* Send a message.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @param array $messages
|
||||
* @param object $original
|
||||
* @return bool
|
||||
*/
|
||||
public function send(array $messages, \Rhymix\Framework\SMS $original)
|
||||
{
|
||||
$status = true;
|
||||
|
||||
foreach ($messages as $i => $message)
|
||||
{
|
||||
$data = array();
|
||||
$data['send_phone'] = $message->from;
|
||||
$data['dest_phone'] = implode(',', $message->to);
|
||||
$data['msg_body'] = strval($message->content);
|
||||
if ($message->type !== 'SMS' && $message->subject)
|
||||
{
|
||||
$data['subject'] = $message->subject;
|
||||
}
|
||||
|
||||
$result = $this->_apiCall(sprintf('message/%s', strtolower($message->type)), $data);
|
||||
if (!$result)
|
||||
{
|
||||
$message->errors[] = 'ApiStore API returned invalid response: ' . $this->_getLastResponse();
|
||||
$status = false;
|
||||
}
|
||||
if ($result->result_message !== 'OK')
|
||||
{
|
||||
$message->errors[] = 'ApiStore API error: ' . $result->result_code . ' ' . $result->result_message;
|
||||
}
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* API call.
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $data
|
||||
* @param string $method (optional)
|
||||
* @return object|false
|
||||
*/
|
||||
protected function _apiCall(string $url, array $data, string $method = 'POST')
|
||||
{
|
||||
// Build the request URL.
|
||||
if ($data['version'])
|
||||
{
|
||||
$version = $data['version'];
|
||||
unset($data['version']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$version = 1;
|
||||
}
|
||||
$url = sprintf('http://api.apistore.co.kr/ppurio/%d/%s/%s', $version, trim($url, '/'), $this->_config['api_user']);
|
||||
|
||||
// Set the API key in the header.
|
||||
$headers = array(
|
||||
'x-waple-authorization' => $this->_config['api_key'],
|
||||
);
|
||||
|
||||
// Send the API reqeust.
|
||||
if ($method === 'GET')
|
||||
{
|
||||
if ($data)
|
||||
{
|
||||
$url .= '?' . http_build_query($data);
|
||||
}
|
||||
$this->_last_response = \FileHandler::getRemoteResource($url, null, 5, $method, null, $headers) ?: '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_last_response = \FileHandler::getRemoteResource($url, $data, 5, $method, null, $headers) ?: '';
|
||||
}
|
||||
$result = @json_decode($this->_last_response);
|
||||
return $result ?: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the last API response.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getLastResponse()
|
||||
{
|
||||
return $this->_last_response;
|
||||
}
|
||||
}
|
||||
116
common/framework/drivers/sms/cafe24.php
Normal file
116
common/framework/drivers/sms/cafe24.php
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Drivers\SMS;
|
||||
|
||||
/**
|
||||
* The Cafe24 SMS driver.
|
||||
*/
|
||||
class Cafe24 extends Base implements \Rhymix\Framework\Drivers\SMSInterface
|
||||
{
|
||||
/**
|
||||
* API specifications.
|
||||
*/
|
||||
protected static $_spec = array(
|
||||
'max_recipients' => 1000,
|
||||
'sms_max_length' => 90,
|
||||
'sms_max_length_in_charset' => 'CP949',
|
||||
'lms_supported' => true,
|
||||
'lms_supported_country_codes' => array(82),
|
||||
'lms_max_length' => 2000,
|
||||
'lms_max_length_in_charset' => 'CP949',
|
||||
'lms_subject_supported' => true,
|
||||
'lms_subject_max_length' => 50,
|
||||
'mms_supported' => false,
|
||||
'delay_supported' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Config keys used by this driver are stored here.
|
||||
*/
|
||||
protected static $_required_config = array('api_user', 'api_key');
|
||||
|
||||
/**
|
||||
* Check if the current SMS driver is supported on this server.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @param array $messages
|
||||
* @param object $original
|
||||
* @return bool
|
||||
*/
|
||||
public function send(array $messages, \Rhymix\Framework\SMS $original)
|
||||
{
|
||||
$status = true;
|
||||
|
||||
foreach ($messages as $i => $message)
|
||||
{
|
||||
// Authentication and basic information
|
||||
$data = array();
|
||||
$data['user_id'] = $this->_config['api_user'];
|
||||
$data['secure'] = $this->_config['api_key'];
|
||||
$data['nointeractive'] = 1;
|
||||
if ($message->type === 'LMS')
|
||||
{
|
||||
$data['smsType'] = 'L';
|
||||
}
|
||||
|
||||
// Sender and recipient
|
||||
$from = explode('-', \Rhymix\Framework\Korea::formatPhoneNumber($message->from));
|
||||
$data['sphone1'] = $from[0];
|
||||
$data['sphone2'] = $from[1];
|
||||
if (isset($from[2]))
|
||||
{
|
||||
$data['sphone3'] = $from[2];
|
||||
}
|
||||
$data['rphone'] = implode(',', array_map(function($num) {
|
||||
return \Rhymix\Framework\Korea::formatPhoneNumber($num);
|
||||
}, $message->to));
|
||||
|
||||
// Subject and content
|
||||
if ($message->type === 'LMS' && $message->subject)
|
||||
{
|
||||
$data['subject'] = $message->subject;
|
||||
}
|
||||
$data['msg'] = $message->content;
|
||||
|
||||
// Set delay
|
||||
if ($message->delay && $message->delay > time() + 600)
|
||||
{
|
||||
$data['rdate'] = gmdate('Ymd', $message->delay + (3600 * 9));
|
||||
$data['rtime'] = gmdate('His', $message->delay + (3600 * 9));
|
||||
}
|
||||
|
||||
// Send!
|
||||
$url = 'https://sslsms.cafe24.com/sms_sender.php';
|
||||
$result = \FileHandler::getRemoteResource($url, $data, 5, 'POST');
|
||||
if(strval($result) === '')
|
||||
{
|
||||
$original->addError('Unknown API error while sending message ' . ($i + 1) . ' of ' . count($messages));
|
||||
$status = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = explode(',', $result);
|
||||
if ($result[0] !== 'success' && $result[0] !== 'reserved')
|
||||
{
|
||||
$original->addError('API error ' . $result[0] . ' while sending message ' . ($i + 1) . ' of ' . count($messages));
|
||||
$status = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
103
common/framework/drivers/sms/ppurio.php
Normal file
103
common/framework/drivers/sms/ppurio.php
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Drivers\SMS;
|
||||
|
||||
/**
|
||||
* The Ppurio SMS driver.
|
||||
*/
|
||||
class Ppurio extends Base implements \Rhymix\Framework\Drivers\SMSInterface
|
||||
{
|
||||
/**
|
||||
* API specifications.
|
||||
*/
|
||||
protected static $_spec = array(
|
||||
'max_recipients' => 1000,
|
||||
'sms_max_length' => 90,
|
||||
'sms_max_length_in_charset' => 'CP949',
|
||||
'lms_supported' => true,
|
||||
'lms_supported_country_codes' => array(82),
|
||||
'lms_max_length' => 2000,
|
||||
'lms_max_length_in_charset' => 'CP949',
|
||||
'lms_subject_supported' => true,
|
||||
'lms_subject_max_length' => 30,
|
||||
'mms_supported' => false,
|
||||
'delay_supported' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Config keys used by this driver are stored here.
|
||||
*/
|
||||
protected static $_required_config = array('api_user');
|
||||
|
||||
/**
|
||||
* Check if the current SMS driver is supported on this server.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message.
|
||||
*
|
||||
* This method returns true on success and false on failure.
|
||||
*
|
||||
* @param array $messages
|
||||
* @param object $original
|
||||
* @return bool
|
||||
*/
|
||||
public function send(array $messages, \Rhymix\Framework\SMS $original)
|
||||
{
|
||||
$status = true;
|
||||
|
||||
foreach ($messages as $i => $message)
|
||||
{
|
||||
// Authentication and basic information
|
||||
$data = array();
|
||||
$data['userid'] = $this->_config['api_user'];
|
||||
|
||||
// Sender and recipient
|
||||
$data['callback'] = preg_replace('/[^0-9]/', '', $message->from);
|
||||
$data['phone'] = implode('|', array_map(function($num) {
|
||||
return preg_replace('/[^0-9]/', '', $num);
|
||||
}, $message->to));
|
||||
|
||||
// Subject and content
|
||||
if ($message->type === 'LMS' && $message->subject)
|
||||
{
|
||||
$data['subject'] = $message->subject;
|
||||
}
|
||||
$data['msg'] = $message->content;
|
||||
|
||||
// Set delay
|
||||
if ($message->delay && $message->delay > time() + 600)
|
||||
{
|
||||
$data['appdate'] = gmdate('YmdHis', $message->delay + (3600 * 9));
|
||||
}
|
||||
|
||||
// Send!
|
||||
$url = 'https://www.ppurio.com/api/send_utf8_json.php';
|
||||
$result = \FileHandler::getRemoteResource($url, $data, 5, 'POST');
|
||||
if(strval($result) === '')
|
||||
{
|
||||
$original->addError('Unknown API error while sending message ' . ($i + 1) . ' of ' . count($messages));
|
||||
$status = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = @json_decode($result);
|
||||
if ($result->result !== 'ok')
|
||||
{
|
||||
$original->addError('API error (' . $result->result . ') while sending message ' . ($i + 1) . ' of ' . count($messages));
|
||||
$status = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
18
common/framework/exceptions/dberror.php
Normal file
18
common/framework/exceptions/dberror.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Exceptions;
|
||||
|
||||
/**
|
||||
* The DB Error exception class.
|
||||
*/
|
||||
class DBError extends \Rhymix\Framework\Exception
|
||||
{
|
||||
public function __construct($message = '', $code = 0, $previous = null)
|
||||
{
|
||||
if ($message === '')
|
||||
{
|
||||
$message = 'DB Error';
|
||||
}
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
18
common/framework/exceptions/queryerror.php
Normal file
18
common/framework/exceptions/queryerror.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Exceptions;
|
||||
|
||||
/**
|
||||
* The Query Error exception class.
|
||||
*/
|
||||
class QueryError extends DBError
|
||||
{
|
||||
public function __construct($message = '', $code = 0, $previous = null)
|
||||
{
|
||||
if ($message === '')
|
||||
{
|
||||
$message = 'Query Error';
|
||||
}
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ class ConfigHelper
|
|||
{
|
||||
if (!isset(self::$_config_cache[$option[0]]))
|
||||
{
|
||||
self::$_config_cache[$option[0]] = getModel('module')->getModuleConfig($option[0]) ?: new stdClass;
|
||||
self::$_config_cache[$option[0]] = \ModuleModel::getInstance()->getModuleConfig($option[0]) ?: new \stdClass;
|
||||
}
|
||||
$options = explode('.', $option[1]);
|
||||
$temp = self::$_config_cache[$option[0]];
|
||||
|
|
|
|||
148
common/framework/helpers/dbhelper.php
Normal file
148
common/framework/helpers/dbhelper.php
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Helpers;
|
||||
|
||||
use Rhymix\Framework\DB;
|
||||
use Rhymix\Framework\Debug;
|
||||
use Rhymix\Framework\Exceptions\DBError;
|
||||
|
||||
/**
|
||||
* DB helper class.
|
||||
*
|
||||
* We use instances of this class instead of raw PDO in order to provide
|
||||
* better logging and error handling while keeping backward compatibility.
|
||||
*/
|
||||
class DBHelper extends \PDO
|
||||
{
|
||||
/**
|
||||
* Store the database type (e.g. master) here.
|
||||
*/
|
||||
protected $_type = 'master';
|
||||
|
||||
/**
|
||||
* Set the database type.
|
||||
*/
|
||||
public function setType(string $type)
|
||||
{
|
||||
$this->_type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a prepared statement.
|
||||
*
|
||||
* @param string $statement
|
||||
* @param array $driver_options
|
||||
* @return PDOStatement|DBStmtHelper
|
||||
*/
|
||||
public function prepare($statement, $driver_options = null)
|
||||
{
|
||||
$start_time = microtime(true);
|
||||
$db_class = DB::getInstance($this->_type);
|
||||
|
||||
try
|
||||
{
|
||||
/**
|
||||
* $stmt will be an instance of DBStmtHelper.
|
||||
* This allows it to track the parent database's type
|
||||
* and send query logs to the appropriate place.
|
||||
*/
|
||||
$stmt = $driver_options ? parent::prepare($statement, $driver_options) : parent::prepare($statement);
|
||||
$stmt->setFetchMode(\PDO::FETCH_OBJ);
|
||||
$stmt->setType($this->_type);
|
||||
$db_class->clearError();
|
||||
}
|
||||
catch (\PDOException $e)
|
||||
{
|
||||
/**
|
||||
* We only measure the time when the prepared statement fails.
|
||||
* If the statement is successfully prepared, time will be measured
|
||||
* when the statement is executed in DBStmtHelper.
|
||||
*/
|
||||
$elapsed_time = microtime(true) - $start_time;
|
||||
$db_class->addElapsedTime($elapsed_time);
|
||||
$db_class->setError(-1, $e->getMessage());
|
||||
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time));
|
||||
|
||||
/**
|
||||
* This is a new feature in Rhymix 2.0 so we don't have to mess
|
||||
* with status objects. We just throw an exception. Catch it!
|
||||
*/
|
||||
throw new DBError($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a query.
|
||||
*
|
||||
* This method accepts additional parameters, but they are not for creating
|
||||
* prepared statements. They exist because PDO's own query() method accepts
|
||||
* various kinds of additional parameters, and we don't want to touch them.
|
||||
*
|
||||
* @param string $statement
|
||||
* @return PDOStatement|DBStmtHelper
|
||||
*/
|
||||
public function query($statement)
|
||||
{
|
||||
$start_time = microtime(true);
|
||||
$db_class = DB::getInstance($this->_type);
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
|
||||
try
|
||||
{
|
||||
/**
|
||||
* $stmt will be an instance of DBStmtHelper.
|
||||
* This allows it to track the parent database's type
|
||||
* and send query logs to the appropriate place.
|
||||
*/
|
||||
$stmt = parent::query($statement, ...$args);
|
||||
$stmt->setFetchMode(\PDO::FETCH_OBJ);
|
||||
$stmt->setType($this->_type);
|
||||
$db_class->clearError();
|
||||
}
|
||||
catch (\PDOException $e)
|
||||
{
|
||||
$db_class->setError(-1, $e->getMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
$elapsed_time = microtime(true) - $start_time;
|
||||
$db_class->addElapsedTime($elapsed_time);
|
||||
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time));
|
||||
}
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a query and return the number of affected rows.
|
||||
*
|
||||
* @param string $statement
|
||||
* @return bool
|
||||
*/
|
||||
public function exec($query)
|
||||
{
|
||||
$start_time = microtime(true);
|
||||
$db_class = DB::getInstance($this->_type);
|
||||
|
||||
try
|
||||
{
|
||||
$result = parent::exec($query);
|
||||
$db_class->clearError();
|
||||
}
|
||||
catch (\PDOException $e)
|
||||
{
|
||||
$db_class->setError(-1, $e->getMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
$elapsed_time = microtime(true) - $start_time;
|
||||
$db_class->addElapsedTime($elapsed_time);
|
||||
Debug::addQuery($db_class->getQueryLog($query, $elapsed_time));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
65
common/framework/helpers/dbstmthelper.php
Normal file
65
common/framework/helpers/dbstmthelper.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Helpers;
|
||||
|
||||
use Rhymix\Framework\DB;
|
||||
use Rhymix\Framework\Debug;
|
||||
use Rhymix\Framework\Exceptions\DBError;
|
||||
|
||||
/**
|
||||
* DB Statement helper class.
|
||||
*
|
||||
* We use instances of this class instead of raw PDOStatement in order to log
|
||||
* individual execute() calls of prepared statements. This is controlled by
|
||||
* the PDO::ATTR_STATEMENT_CLASS attribute set in the DB class.
|
||||
*/
|
||||
class DBStmtHelper extends \PDOStatement
|
||||
{
|
||||
/**
|
||||
* Store the database type (e.g. master) here.
|
||||
*/
|
||||
protected $_type = 'master';
|
||||
|
||||
/**
|
||||
* Set the database type.
|
||||
*/
|
||||
public function setType(string $type)
|
||||
{
|
||||
$this->_type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a prepared statement.
|
||||
*
|
||||
* We don't set a type for $input_parameters because the original
|
||||
* PDOStatement class accepts both arrays and null. Actually, the null
|
||||
* value must be omitted altogether or it will throw an error.
|
||||
*
|
||||
* @param array $input_parameters
|
||||
* @return bool
|
||||
*/
|
||||
public function execute($input_parameters = null): bool
|
||||
{
|
||||
$start_time = microtime(true);
|
||||
$db_class = DB::getInstance($this->_type);
|
||||
|
||||
try
|
||||
{
|
||||
$result = parent::execute($input_parameters);
|
||||
$db_class->clearError();
|
||||
}
|
||||
catch (\PDOException $e)
|
||||
{
|
||||
$db_class->setError(-1, $e->getMessage());
|
||||
throw new DBError($e->getMessage(), 0, $e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
$elapsed_time = microtime(true) - $start_time;
|
||||
$db_class->addElapsedTime($elapsed_time);
|
||||
Debug::addQuery($db_class->getQueryLog($this->queryString, $elapsed_time));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ class SessionHelper
|
|||
$member_srl = intval($member_srl);
|
||||
if ($member_srl)
|
||||
{
|
||||
$oMemberModel = getModel('member');
|
||||
$oMemberModel = \MemberModel::getInstance();
|
||||
$member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl);
|
||||
if (intval($member_info->member_srl) === $member_srl)
|
||||
{
|
||||
|
|
@ -69,7 +69,7 @@ class SessionHelper
|
|||
*/
|
||||
public function isModuleAdmin($module_srl = null)
|
||||
{
|
||||
return $this->is_admin === 'Y' || getModel('module')->isModuleAdmin($this, $module_srl);
|
||||
return $this->is_admin === 'Y' || \ModuleModel::getInstance()->isModuleAdmin($this, $module_srl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
106
common/framework/parsers/baseparser.php
Normal file
106
common/framework/parsers/baseparser.php
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers;
|
||||
|
||||
/**
|
||||
* This class provides common methods for other parser classes to use.
|
||||
*/
|
||||
abstract class BaseParser
|
||||
{
|
||||
/**
|
||||
* Get all attributes of an element as an associative array.
|
||||
*
|
||||
* @param SimpleXMLElement $element
|
||||
* @param bool $remove_symbols
|
||||
* @return array
|
||||
*/
|
||||
protected static function _getAttributes(\SimpleXMLElement $element, $remove_symbols = true): array
|
||||
{
|
||||
$result = array();
|
||||
foreach ($element->attributes() as $key => $val)
|
||||
{
|
||||
if ($remove_symbols)
|
||||
{
|
||||
$key = preg_replace('/[^a-z]/', '', $key);
|
||||
}
|
||||
$result[trim($key)] = trim($val);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of child elements that match a language.
|
||||
*
|
||||
* @param SimpleXMLElement $parent
|
||||
* @param string $tag_name
|
||||
* @param string $lang
|
||||
* @return string
|
||||
*/
|
||||
protected static function _getChildrenByLang(\SimpleXMLElement $parent, string $tag_name, string $lang): string
|
||||
{
|
||||
// If there is a child element that matches the language, return it.
|
||||
foreach ($parent->{$tag_name} as $child)
|
||||
{
|
||||
$attribs = $child->attributes('xml', true);
|
||||
if (strval($attribs['lang']) === $lang)
|
||||
{
|
||||
return trim($child);
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, return the first child element.
|
||||
foreach ($parent->{$tag_name} as $child)
|
||||
{
|
||||
return trim($child);
|
||||
}
|
||||
|
||||
// If there are no child elements, return an empty string.
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse extra_vars.
|
||||
*
|
||||
* @param SimpleXMLElement $extra_vars
|
||||
* @param string $lang
|
||||
* @return object
|
||||
*/
|
||||
protected static function _getExtraVars(\SimpleXMLElement $extra_vars, string $lang): \stdClass
|
||||
{
|
||||
$result = new \stdClass;
|
||||
$group_name = $extra_vars->getName() === 'group' ? self::_getChildrenByLang($extra_vars, 'title', $lang) : null;
|
||||
foreach ($extra_vars->group ?: [] as $group)
|
||||
{
|
||||
$group_result = self::_getExtraVars($group, $lang);
|
||||
foreach ($group_result as $key => $val)
|
||||
{
|
||||
$result->{$key} = $val;
|
||||
}
|
||||
}
|
||||
foreach ($extra_vars->var ?: [] as $var)
|
||||
{
|
||||
$item = new \stdClass;
|
||||
$item->group = $group_name;
|
||||
$item->name = trim($var['name']);
|
||||
$item->type = trim($var['type']);
|
||||
$item->title = self::_getChildrenByLang($var, 'title', $lang);
|
||||
$item->description = str_replace('\\n', "\n", self::_getChildrenByLang($var, 'description', $lang));
|
||||
$item->default = trim($var['default']) ?: null;
|
||||
$item->value = null;
|
||||
if ($var->options)
|
||||
{
|
||||
$item->options = array();
|
||||
foreach ($var->options as $option)
|
||||
{
|
||||
$option_item = new \stdClass;
|
||||
$option_item->title = self::_getChildrenByLang($option, 'title', $lang);
|
||||
$option_item->value = trim($option['value']);
|
||||
$item->options[$option_item->value] = $option_item;
|
||||
}
|
||||
}
|
||||
|
||||
$result->{$item->name} = $item;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +198,7 @@ class ConfigParser
|
|||
$config['url']['default'] = $default_url ?: (\RX_SSL ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . \RX_BASEURL;
|
||||
$config['url']['http_port'] = $db_info->http_port ?: null;
|
||||
$config['url']['https_port'] = $db_info->https_port ?: null;
|
||||
$config['url']['ssl'] = $db_info->use_ssl ?: 'none';
|
||||
$config['url']['ssl'] = ($db_info->use_ssl === 'none') ? 'none' : 'always';
|
||||
|
||||
// Convert session configuration.
|
||||
$config['session']['delay'] = $db_info->delay_session === 'Y' ? true : false;
|
||||
|
|
|
|||
14
common/framework/parsers/dbquery/columnread.php
Normal file
14
common/framework/parsers/dbquery/columnread.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* ColumnRead class.
|
||||
*/
|
||||
class ColumnRead
|
||||
{
|
||||
public $name;
|
||||
public $alias;
|
||||
public $is_expression = false;
|
||||
public $is_wildcard = false;
|
||||
}
|
||||
18
common/framework/parsers/dbquery/columnwrite.php
Normal file
18
common/framework/parsers/dbquery/columnwrite.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* ColumnWrite class.
|
||||
*/
|
||||
class ColumnWrite extends VariableBase
|
||||
{
|
||||
public $name;
|
||||
public $operation = 'equal';
|
||||
public $var;
|
||||
public $default;
|
||||
public $not_null;
|
||||
public $filter;
|
||||
public $minlength = 0;
|
||||
public $maxlength = 0;
|
||||
}
|
||||
19
common/framework/parsers/dbquery/condition.php
Normal file
19
common/framework/parsers/dbquery/condition.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* Condition class.
|
||||
*/
|
||||
class Condition extends VariableBase
|
||||
{
|
||||
public $operation;
|
||||
public $column;
|
||||
public $var;
|
||||
public $default;
|
||||
public $not_null;
|
||||
public $filter;
|
||||
public $minlength = 0;
|
||||
public $maxlength = 0;
|
||||
public $pipe = 'AND';
|
||||
}
|
||||
12
common/framework/parsers/dbquery/conditiongroup.php
Normal file
12
common/framework/parsers/dbquery/conditiongroup.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* Condition Group class.
|
||||
*/
|
||||
class ConditionGroup
|
||||
{
|
||||
public $conditions = array();
|
||||
public $pipe = 'AND';
|
||||
}
|
||||
14
common/framework/parsers/dbquery/emptystring.php
Normal file
14
common/framework/parsers/dbquery/emptystring.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* Empty string class.
|
||||
*/
|
||||
class EmptyString
|
||||
{
|
||||
public function __toString(): string
|
||||
{
|
||||
return "''";
|
||||
}
|
||||
}
|
||||
12
common/framework/parsers/dbquery/groupby.php
Normal file
12
common/framework/parsers/dbquery/groupby.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* GroupBy class.
|
||||
*/
|
||||
class GroupBy
|
||||
{
|
||||
public $columns = array();
|
||||
public $having = array();
|
||||
}
|
||||
15
common/framework/parsers/dbquery/navigation.php
Normal file
15
common/framework/parsers/dbquery/navigation.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* Navigation class.
|
||||
*/
|
||||
class Navigation
|
||||
{
|
||||
public $orderby = array();
|
||||
public $list_count;
|
||||
public $page_count;
|
||||
public $page;
|
||||
public $offset;
|
||||
}
|
||||
14
common/framework/parsers/dbquery/nullvalue.php
Normal file
14
common/framework/parsers/dbquery/nullvalue.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* Null value class.
|
||||
*/
|
||||
class NullValue
|
||||
{
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'NULL';
|
||||
}
|
||||
}
|
||||
14
common/framework/parsers/dbquery/orderby.php
Normal file
14
common/framework/parsers/dbquery/orderby.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* OrderBy class.
|
||||
*/
|
||||
class OrderBy extends VariableBase
|
||||
{
|
||||
public $var;
|
||||
public $default;
|
||||
public $order_var;
|
||||
public $order_default = 'ASC';
|
||||
}
|
||||
627
common/framework/parsers/dbquery/query.php
Normal file
627
common/framework/parsers/dbquery/query.php
Normal file
|
|
@ -0,0 +1,627 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* Query class.
|
||||
*/
|
||||
class Query extends VariableBase
|
||||
{
|
||||
/**
|
||||
* Attributes common to all queries.
|
||||
*/
|
||||
public $name;
|
||||
public $type;
|
||||
public $tables = array();
|
||||
public $columns = array();
|
||||
public $conditions = array();
|
||||
public $groupby = null;
|
||||
public $navigation = null;
|
||||
public $select_distinct = false;
|
||||
public $update_duplicate = false;
|
||||
public $requires_pagination = false;
|
||||
|
||||
/**
|
||||
* Attributes for subqueries in the <tables> or <columns> section.
|
||||
*/
|
||||
public $alias;
|
||||
public $join_type;
|
||||
public $join_conditions = array();
|
||||
|
||||
/**
|
||||
* Attributes for subqueries in the <conditions> section.
|
||||
*/
|
||||
public $operation;
|
||||
public $column;
|
||||
public $pipe;
|
||||
|
||||
/**
|
||||
* Attributes used during query string generation.
|
||||
*/
|
||||
protected $_prefix = '';
|
||||
protected $_args = array();
|
||||
protected $_column_list = array();
|
||||
protected $_params = array();
|
||||
|
||||
/**
|
||||
* Generate the query string for this query.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @param array $args
|
||||
* @param array $column_list
|
||||
* @param bool $count_only
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryString(string $prefix = '', array $args, array $column_list = [], bool $count_only = false): string
|
||||
{
|
||||
// Save the query information.
|
||||
$this->_prefix = $prefix;
|
||||
$this->_args = $args;
|
||||
$this->_column_list = $column_list;
|
||||
$this->_params = array();
|
||||
|
||||
// Call different internal methods depending on the query type.
|
||||
switch ($this->type)
|
||||
{
|
||||
case 'SELECT':
|
||||
$result = $this->_getSelectQueryString($count_only);
|
||||
break;
|
||||
case 'INSERT':
|
||||
$result = $this->_getInsertQueryString();
|
||||
break;
|
||||
case 'UPDATE':
|
||||
$result = $this->_getUpdateQueryString();
|
||||
break;
|
||||
case 'DELETE':
|
||||
$result = $this->_getDeleteQueryString();
|
||||
break;
|
||||
default:
|
||||
$result = '';
|
||||
}
|
||||
|
||||
// Reset state and return the result.
|
||||
$this->_prefix = '';
|
||||
$this->_args = array();
|
||||
$this->_column_list = array();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query parameters to use with the query string generated above.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueryParams()
|
||||
{
|
||||
return $this->_params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this query requires pagination.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function requiresPagination(): bool
|
||||
{
|
||||
return $this->requires_pagination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a SELECT query string.
|
||||
*
|
||||
* @param bool $count_only
|
||||
* @return string
|
||||
*/
|
||||
protected function _getSelectQueryString(bool $count_only = false): string
|
||||
{
|
||||
// Initialize the query string.
|
||||
$result = 'SELECT ';
|
||||
if ($this->select_distinct)
|
||||
{
|
||||
$result .= 'DISTINCT ';
|
||||
}
|
||||
|
||||
// Compose the column list.
|
||||
$columns = array();
|
||||
if ($count_only)
|
||||
{
|
||||
$result .= 'COUNT(*) AS `count`';
|
||||
}
|
||||
elseif ($this->_column_list)
|
||||
{
|
||||
$result .= implode(', ', array_map(function($str) {
|
||||
return self::quoteName($str);
|
||||
}, $this->_column_list));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($this->columns as $column)
|
||||
{
|
||||
if ($column instanceof self)
|
||||
{
|
||||
$subquery = $column->getQueryString($this->_prefix, $this->_args);
|
||||
foreach ($column->getQueryParams() as $param)
|
||||
{
|
||||
$this->_params[] = $param;
|
||||
}
|
||||
$columns[] = sprintf('(%s) AS %s', $subquery, self::quoteName($column->alias));
|
||||
}
|
||||
elseif ($column->is_expression && !$column->is_wildcard)
|
||||
{
|
||||
$columns[] = $column->name . ($column->alias ? (' AS ' . self::quoteName($column->alias)) : '');
|
||||
}
|
||||
else
|
||||
{
|
||||
$columns[] = self::quoteName($column->name) . ($column->alias ? (' AS ' . self::quoteName($column->alias)) : '');
|
||||
}
|
||||
}
|
||||
$result .= implode(', ', $columns);
|
||||
}
|
||||
|
||||
// Compose the FROM clause.
|
||||
if (count($this->tables))
|
||||
{
|
||||
$tables = $this->_arrangeTables($this->tables);
|
||||
if ($tables !== '')
|
||||
{
|
||||
$result .= ' FROM ' . $tables;
|
||||
}
|
||||
}
|
||||
|
||||
// Compose the WHERE clause.
|
||||
if (count($this->conditions))
|
||||
{
|
||||
$where = $this->_arrangeConditions($this->conditions);
|
||||
if ($where !== '')
|
||||
{
|
||||
$result .= ' WHERE ' . $where;
|
||||
}
|
||||
}
|
||||
|
||||
// Compose the GROUP BY clause.
|
||||
if ($this->groupby && count($this->groupby->columns))
|
||||
{
|
||||
$columns = array();
|
||||
foreach ($this->groupby->columns as $column_name)
|
||||
{
|
||||
if (self::isValidColumnName($column_name))
|
||||
{
|
||||
$columns[] = self::quoteName($column_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
$columns[] = $column_name;
|
||||
}
|
||||
}
|
||||
$result .= ' GROUP BY ' . implode(', ', $columns);
|
||||
}
|
||||
if ($this->groupby && count($this->groupby->having))
|
||||
{
|
||||
$having = $this->_arrangeConditions($this->groupby->having);
|
||||
if ($having !== '')
|
||||
{
|
||||
$result .= ' HAVING ' . $having;
|
||||
}
|
||||
}
|
||||
|
||||
// Compose the ORDER BY clause.
|
||||
if ($this->navigation && count($this->navigation->orderby) && !$count_only)
|
||||
{
|
||||
$result .= ' ORDER BY ' . $this->_arrangeOrderBy($this->navigation);
|
||||
}
|
||||
|
||||
// Compose the LIMIT/OFFSET clause.
|
||||
if ($this->navigation && $this->navigation->list_count && !$count_only)
|
||||
{
|
||||
$result .= ' LIMIT ' . $this->_arrangeLimitOffset($this->navigation);
|
||||
}
|
||||
|
||||
// Return the final query string.
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a INSERT query string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getInsertQueryString(): string
|
||||
{
|
||||
// Initialize the query string.
|
||||
$result = 'INSERT';
|
||||
|
||||
// Compose the INTO clause.
|
||||
if (count($this->tables))
|
||||
{
|
||||
$tables = $this->_arrangeTables($this->tables, false);
|
||||
if ($tables !== '')
|
||||
{
|
||||
$result .= ' INTO ' . $tables;
|
||||
}
|
||||
}
|
||||
|
||||
// Process the SET clause with new values.
|
||||
$columns = array();
|
||||
foreach ($this->columns as $column)
|
||||
{
|
||||
$setval_string = $this->_parseCondition($column);
|
||||
if ($setval_string !== '')
|
||||
{
|
||||
$columns[] = $setval_string;
|
||||
}
|
||||
}
|
||||
$result .= ' SET ' . implode(', ', $columns);
|
||||
|
||||
// Process the ON DUPLICATE KEY UPDATE (upsert) clause.
|
||||
if ($this->update_duplicate && count($columns))
|
||||
{
|
||||
$result .= ' ON DUPLICATE KEY UPDATE ' . implode(', ', $columns);
|
||||
$duplicate_params = $this->_params;
|
||||
foreach ($duplicate_params as $param)
|
||||
{
|
||||
$this->_params[] = $param;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the final query string.
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a UPDATE query string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getUpdateQueryString(): string
|
||||
{
|
||||
// Initialize the query string.
|
||||
$result = 'UPDATE ';
|
||||
|
||||
// Compose the INTO clause.
|
||||
if (count($this->tables))
|
||||
{
|
||||
$tables = $this->_arrangeTables($this->tables, false);
|
||||
if ($tables !== '')
|
||||
{
|
||||
$result .= $tables;
|
||||
}
|
||||
}
|
||||
|
||||
// Compose the SET clause with updated values.
|
||||
$columns = array();
|
||||
foreach ($this->columns as $column)
|
||||
{
|
||||
$setval_string = $this->_parseCondition($column);
|
||||
if ($setval_string !== '')
|
||||
{
|
||||
$columns[] = $setval_string;
|
||||
}
|
||||
}
|
||||
$result .= ' SET ' . implode(', ', $columns);
|
||||
|
||||
// Compose the WHERE clause.
|
||||
if (count($this->conditions))
|
||||
{
|
||||
$where = $this->_arrangeConditions($this->conditions);
|
||||
if ($where !== '')
|
||||
{
|
||||
$result .= ' WHERE ' . $where;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the final query string.
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a DELETE query string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getDeleteQueryString(): string
|
||||
{
|
||||
// Initialize the query string.
|
||||
$result = 'DELETE';
|
||||
|
||||
// Compose the FROM clause.
|
||||
if (count($this->tables))
|
||||
{
|
||||
$tables = $this->_arrangeTables($this->tables, false);
|
||||
if ($tables !== '')
|
||||
{
|
||||
$result .= ' FROM ' . $tables;
|
||||
}
|
||||
}
|
||||
|
||||
// Compose the WHERE clause.
|
||||
if (count($this->conditions))
|
||||
{
|
||||
$where = $this->_arrangeConditions($this->conditions);
|
||||
if ($where !== '')
|
||||
{
|
||||
$result .= ' WHERE ' . $where;
|
||||
}
|
||||
}
|
||||
|
||||
// Compose the ORDER BY clause.
|
||||
if ($this->navigation && count($this->navigation->orderby))
|
||||
{
|
||||
$result .= ' ORDER BY ' . $this->_arrangeOrderBy($this->navigation);
|
||||
}
|
||||
|
||||
// Compose the LIMIT/OFFSET clause.
|
||||
if ($this->navigation && $this->navigation->list_count)
|
||||
{
|
||||
$result .= ' LIMIT ' . $this->_arrangeLimitOffset($this->navigation);
|
||||
}
|
||||
|
||||
// Return the final query string.
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a FROM clause from a list of tables.
|
||||
*
|
||||
* @param array $tables
|
||||
* @param bool $use_aliases
|
||||
* @return string
|
||||
*/
|
||||
protected function _arrangeTables(array $tables, bool $use_aliases = true): string
|
||||
{
|
||||
// Initialize the result.
|
||||
$result = array();
|
||||
|
||||
// Process each table definition.
|
||||
foreach ($tables as $table)
|
||||
{
|
||||
// Subquery
|
||||
if ($table instanceof self)
|
||||
{
|
||||
$tabledef = '(' . $table->getQueryString($this->_prefix, $this->_args) . ')';
|
||||
if ($table->alias)
|
||||
{
|
||||
$tabledef .= ' AS `' . $table->alias . '`';
|
||||
}
|
||||
foreach ($table->getQueryParams() as $param)
|
||||
{
|
||||
$this->_params[] = $param;
|
||||
}
|
||||
}
|
||||
|
||||
// Regular table
|
||||
else
|
||||
{
|
||||
$tabledef = self::quoteName($this->_prefix . $table->name);
|
||||
if ($use_aliases && $table->alias && $table->alias !== ($this->_prefix . $table->name))
|
||||
{
|
||||
$tabledef .= ' AS `' . $table->alias . '`';
|
||||
}
|
||||
}
|
||||
|
||||
// Add join conditions
|
||||
if ($table->join_type)
|
||||
{
|
||||
$join_where = $this->_arrangeConditions($table->join_conditions);
|
||||
if ($join_where !== '')
|
||||
{
|
||||
$tabledef = $tabledef . ' ON ' . $join_where;
|
||||
}
|
||||
$result[] = ' ' . $table->join_type . ' ' . $tabledef;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result[] = (count($result) ? ', ' : '') . $tabledef;
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the result and return as a string.
|
||||
return implode('', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a WHERE clause from a list of conditions.
|
||||
*
|
||||
* @param array $conditions
|
||||
* @return string
|
||||
*/
|
||||
protected function _arrangeConditions(array $conditions): string
|
||||
{
|
||||
// Initialize the result.
|
||||
$result = '';
|
||||
|
||||
// Process each condition.
|
||||
foreach ($conditions as $condition)
|
||||
{
|
||||
// Subquery
|
||||
if ($condition instanceof self)
|
||||
{
|
||||
$condition_string = $this->_parseCondition($condition);
|
||||
if ($condition_string !== '')
|
||||
{
|
||||
$result .= ($result === '' ? '' : (' ' . $condition->pipe . ' ')) . $condition_string;
|
||||
}
|
||||
}
|
||||
|
||||
// Condition group
|
||||
elseif ($condition instanceof ConditionGroup)
|
||||
{
|
||||
$condition_string = $this->_arrangeConditions($condition->conditions);
|
||||
if ($condition_string !== '')
|
||||
{
|
||||
$result .= ($result === '' ? '' : (' ' . $condition->pipe . ' ')) . '(' . $condition_string . ')';
|
||||
}
|
||||
}
|
||||
|
||||
// Simple condition
|
||||
else
|
||||
{
|
||||
$condition_string = $this->_parseCondition($condition);
|
||||
if ($condition_string !== '')
|
||||
{
|
||||
$result .= ($result === '' ? '' : (' ' . $condition->pipe . ' ')) . $condition_string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the WHERE clause.
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a ORDER BY clause from navigation settings.
|
||||
*
|
||||
* @param object $navigation
|
||||
* @return string
|
||||
*/
|
||||
protected function _arrangeOrderBy(Navigation $navigation): string
|
||||
{
|
||||
// Initialize the result.
|
||||
$result = array();
|
||||
|
||||
// Process each column definition.
|
||||
foreach ($navigation->orderby as $orderby)
|
||||
{
|
||||
// Get the name of the column or expression to order by.
|
||||
$column_name = '';
|
||||
list($is_expression, $column_name) = $orderby->getValue($this->_args);
|
||||
if (!$column_name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!$is_expression && self::isValidColumnName($column_name))
|
||||
{
|
||||
$column_name = self::quoteName($column_name);
|
||||
}
|
||||
|
||||
// Get the ordering (ASC or DESC).
|
||||
if (preg_match('/^(ASC|DESC)$/i', $orderby->order_var, $matches))
|
||||
{
|
||||
$column_order = strtoupper($matches[1]);
|
||||
}
|
||||
elseif (isset($this->_args[$orderby->order_var]))
|
||||
{
|
||||
$column_order = preg_replace('/[^A-Z]/', '', strtoupper($this->_args[$orderby->order_var]));
|
||||
}
|
||||
else
|
||||
{
|
||||
$column_order = preg_replace('/[^A-Z]/', '', strtoupper($orderby->order_default));
|
||||
}
|
||||
|
||||
$result[] = $column_name . ' ' . $column_order;
|
||||
}
|
||||
|
||||
// Return the ORDER BY clause.
|
||||
return implode(', ', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a LIMIT/OFFSET clause from navigation settings.
|
||||
*
|
||||
* @param object $navigation
|
||||
* @return string
|
||||
*/
|
||||
protected function _arrangeLimitOffset(Navigation $navigation): string
|
||||
{
|
||||
// Get the list count.
|
||||
list($is_expression, $list_count) = $navigation->list_count->getValue($this->_args);
|
||||
if ($list_count <= 0)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
// Get the offset from the page or offset variable.
|
||||
if ($navigation->page)
|
||||
{
|
||||
list($is_expression, $page) = $navigation->page->getValue($this->_args);
|
||||
}
|
||||
if ($navigation->offset)
|
||||
{
|
||||
list($is_expression, $offset) = $navigation->offset->getValue($this->_args);
|
||||
}
|
||||
|
||||
// If page is available, set the offset and require pagination for this query.
|
||||
if ($page > 0)
|
||||
{
|
||||
$offset = $list_count * ($page - 1);
|
||||
if ($this->type === 'SELECT')
|
||||
{
|
||||
$this->requires_pagination = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page = 1;
|
||||
}
|
||||
|
||||
// Return the LIMIT/OFFSET clause.
|
||||
return ($offset > 0 ? (intval($offset) . ', ') : '') . intval($list_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate each condition in a WHERE clause.
|
||||
*
|
||||
* @param object $condition
|
||||
* @return string
|
||||
*/
|
||||
protected function _parseCondition(VariableBase $condition): string
|
||||
{
|
||||
list($where, $params) = $condition->getQueryStringAndParams($this->_args, $this->_prefix);
|
||||
foreach ($params as $param)
|
||||
{
|
||||
$this->_params[] = $param;
|
||||
}
|
||||
return $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote a column name.
|
||||
*
|
||||
* @param string $column_name
|
||||
* @return string
|
||||
*/
|
||||
public static function quoteName(string $column_name): string
|
||||
{
|
||||
$columns = explode('.', $column_name);
|
||||
$columns = array_map(function($str) {
|
||||
return $str === '*' ? $str : ('`' . $str . '`');
|
||||
}, $columns);
|
||||
return implode('.', $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column name is valid.
|
||||
*
|
||||
* @param string $column_name
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidColumnName(string $column_name): bool
|
||||
{
|
||||
return preg_match('/^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)*$/i', $column_name) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a variable is considered valid for XE compatibility.
|
||||
*
|
||||
* @param mixed $var
|
||||
* @param bool $allow_empty_string
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidVariable($var, $allow_empty_string = true): bool
|
||||
{
|
||||
if ($var === null || ($var === '' && !$allow_empty_string))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($var))
|
||||
{
|
||||
$count = count($var);
|
||||
if ($count === 0 || ($count === 1 && reset($var) === ''))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
14
common/framework/parsers/dbquery/table.php
Normal file
14
common/framework/parsers/dbquery/table.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* Table class.
|
||||
*/
|
||||
class Table
|
||||
{
|
||||
public $name;
|
||||
public $alias;
|
||||
public $join_type;
|
||||
public $join_conditions = array();
|
||||
}
|
||||
447
common/framework/parsers/dbquery/variablebase.php
Normal file
447
common/framework/parsers/dbquery/variablebase.php
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* VariableBase class.
|
||||
*/
|
||||
class VariableBase
|
||||
{
|
||||
/**
|
||||
* Instance properties.
|
||||
*/
|
||||
public $var;
|
||||
public $default;
|
||||
|
||||
/**
|
||||
* Convert an operator into real SQL.
|
||||
*
|
||||
* @param array $args
|
||||
* @param string $prefix
|
||||
* @return array
|
||||
*/
|
||||
public function getQueryStringAndParams(array $args, string $prefix = ''): array
|
||||
{
|
||||
// Return if this method is called on an invalid child class.
|
||||
if ((!isset($this->column) && !isset($this->name)) || !isset($this->operation))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Invalid invocation of getQueryStringAndParams()');
|
||||
}
|
||||
|
||||
// Initialze the return values.
|
||||
$where = '';
|
||||
$params = array();
|
||||
|
||||
// Process the variable or default value.
|
||||
if ($this instanceof Query)
|
||||
{
|
||||
$is_expression = true;
|
||||
$value = '(' . $this->getQueryString($prefix, $args) . ')';
|
||||
$params = $this->getQueryParams();
|
||||
}
|
||||
elseif ($this->var && Query::isValidVariable($args[$this->var], $this instanceof ColumnWrite))
|
||||
{
|
||||
if ($args[$this->var] instanceof EmptyString || $args[$this->var] instanceof NullValue)
|
||||
{
|
||||
$this->filterValue('');
|
||||
$value = strval($args[$this->var]);
|
||||
$is_expression = true;
|
||||
}
|
||||
elseif ($args[$this->var] === '')
|
||||
{
|
||||
$this->filterValue($args[$this->var]);
|
||||
if ($this instanceof ColumnWrite)
|
||||
{
|
||||
$value = $args[$this->var];
|
||||
$is_expression = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
list($is_expression, $value) = $this->getDefaultValue();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->filterValue($args[$this->var]);
|
||||
$value = $args[$this->var];
|
||||
$is_expression = false;
|
||||
}
|
||||
}
|
||||
elseif ($this->default !== null)
|
||||
{
|
||||
list($is_expression, $value) = $this->getDefaultValue();
|
||||
}
|
||||
elseif ($this->not_null)
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' is not set');
|
||||
}
|
||||
elseif (!in_array($this->operation, ['null', 'notnull', 'not_null']))
|
||||
{
|
||||
return [$where, $params];
|
||||
}
|
||||
|
||||
// Quote the column name.
|
||||
$column = Query::quoteName(isset($this->column) ? $this->column : $this->name);
|
||||
|
||||
// Prepare the target value.
|
||||
$list_ops = array('in' => true, 'notin' => true, 'not_in' => true, 'between' => true);
|
||||
if (isset($list_ops[$this->operation]) && !$is_expression && !is_array($value) && $value !== '')
|
||||
{
|
||||
$value = explode(',', preg_replace('/[\s\']/', '', $value));
|
||||
}
|
||||
|
||||
// Restrict operators for write queries.
|
||||
if ($this instanceof ColumnWrite && $this->operation && !in_array($this->operation, ['equal', 'plus', 'minus', 'multiply']))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Operation ' . $this->operation . ' is not valid for column in an INSERT or UPDATE query');
|
||||
}
|
||||
|
||||
// Apply the operator.
|
||||
switch ($this->operation)
|
||||
{
|
||||
case 'equal':
|
||||
$where = sprintf('%s = %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'notequal':
|
||||
case 'not_equal':
|
||||
$where = sprintf('%s != %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'more':
|
||||
case 'gte':
|
||||
$where = sprintf('%s >= %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'excess':
|
||||
case 'gt';
|
||||
$where = sprintf('%s > %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'less':
|
||||
case 'lte':
|
||||
$where = sprintf('%s <= %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'below':
|
||||
case 'lt';
|
||||
$where = sprintf('%s < %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'regexp';
|
||||
$where = sprintf('%s REGEXP %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'notregexp';
|
||||
case 'not_regexp';
|
||||
$where = sprintf('%s NOT REGEXP %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'like':
|
||||
$where = sprintf('%s LIKE %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = '%' . $value . '%';
|
||||
break;
|
||||
case 'like_prefix':
|
||||
case 'like_head':
|
||||
$where = sprintf('%s LIKE %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value . '%';
|
||||
break;
|
||||
case 'like_suffix':
|
||||
case 'like_tail':
|
||||
$where = sprintf('%s LIKE %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = '%' . $value;
|
||||
break;
|
||||
case 'notlike':
|
||||
$where = sprintf('%s NOT LIKE %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = '%' . $value . '%';
|
||||
break;
|
||||
case 'notlike_prefix':
|
||||
case 'notlike_head':
|
||||
$where = sprintf('%s NOT LIKE %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value . '%';
|
||||
break;
|
||||
case 'notlike_suffix':
|
||||
case 'notlike_tail':
|
||||
$where = sprintf('%s NOT LIKE %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = '%' . $value;
|
||||
break;
|
||||
case 'and':
|
||||
$where = sprintf('%s & %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = '%' . $value;
|
||||
break;
|
||||
case 'or':
|
||||
$where = sprintf('%s | %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = '%' . $value;
|
||||
break;
|
||||
case 'xor':
|
||||
$where = sprintf('%s ^ %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = '%' . $value;
|
||||
break;
|
||||
case 'not':
|
||||
$where = sprintf('%s ~ %s', $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = '%' . $value;
|
||||
break;
|
||||
case 'null':
|
||||
$where = sprintf('%s IS NULL', $column);
|
||||
break;
|
||||
case 'notnull':
|
||||
case 'not_null':
|
||||
$where = sprintf('%s IS NOT NULL', $column);
|
||||
break;
|
||||
case 'in':
|
||||
if ($is_expression)
|
||||
{
|
||||
$where = sprintf('%s IN %s', $column, $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$count = count($value);
|
||||
$placeholders = implode(', ', array_fill(0, $count, '?'));
|
||||
$where = sprintf('%s IN (%s)', $column, $placeholders);
|
||||
foreach ($value as $item)
|
||||
{
|
||||
$params[] = $item;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'notin':
|
||||
case 'not_in':
|
||||
if ($is_expression)
|
||||
{
|
||||
$where = sprintf('%s IN %s', $column, $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$count = count($value);
|
||||
$placeholders = implode(', ', array_fill(0, $count, '?'));
|
||||
$where = sprintf('%s NOT IN (%s)', $column, $placeholders);
|
||||
foreach ($value as $item)
|
||||
{
|
||||
$params[] = $item;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'between':
|
||||
$where = sprintf('%s BETWEEN ? AND ?', $column);
|
||||
foreach ($value as $item)
|
||||
{
|
||||
$params[] = $item;
|
||||
}
|
||||
break;
|
||||
case 'notbetween':
|
||||
case 'not_between':
|
||||
$where = sprintf('%s NOT BETWEEN ? AND ?', $column);
|
||||
foreach ($value as $item)
|
||||
{
|
||||
$params[] = $item;
|
||||
}
|
||||
break;
|
||||
case 'search':
|
||||
$keywords = preg_split('/[\s,]+/', $value, 10, \PREG_SPLIT_NO_EMPTY);
|
||||
$conditions = array();
|
||||
$placeholders = implode(', ', array_fill(0, count($keywords), '?'));
|
||||
foreach ($keywords as $item)
|
||||
{
|
||||
if (substr($item, 0, 1) === '-')
|
||||
{
|
||||
$conditions[] = sprintf('%s NOT LIKE ?', $column);
|
||||
$item = substr($item, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$conditions[] = sprintf('%s LIKE ?', $column);
|
||||
}
|
||||
$params[] = '%' . str_replace(['\\', '_', '%'], ['\\\\', '\_', '\%'], $item) . '%';
|
||||
}
|
||||
$conditions = implode(' AND ', $conditions);
|
||||
$where = count($keywords) === 1 ? $conditions : "($conditions)";
|
||||
break;
|
||||
case 'plus':
|
||||
$where = sprintf('%s = %s + %s', $column, $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'minus':
|
||||
$where = sprintf('%s = %s - %s', $column, $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
case 'multiply':
|
||||
$where = sprintf('%s = %s * %s', $column, $column, $is_expression ? $value : '?');
|
||||
if (!$is_expression) $params[] = $value;
|
||||
break;
|
||||
default:
|
||||
$where = sprintf('%s = ?', $column);
|
||||
$params[] = $value;
|
||||
}
|
||||
|
||||
// Return the complete condition and parameters.
|
||||
return [$where, $params];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value, falling back to the default value if necessary.
|
||||
*
|
||||
* @param array $args
|
||||
* @return array
|
||||
*/
|
||||
public function getValue(array $args)
|
||||
{
|
||||
if ($this->var && Query::isValidVariable($args[$this->var], $this instanceof ColumnWrite))
|
||||
{
|
||||
if ($args[$this->var] === '')
|
||||
{
|
||||
if ($this instanceof ColumnWrite)
|
||||
{
|
||||
$value = $args[$this->var];
|
||||
$is_expression = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
list($is_expression, $value) = $this->getDefaultValue();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$is_expression = false;
|
||||
$value = $args[$this->var];
|
||||
}
|
||||
}
|
||||
elseif ($this->default !== null)
|
||||
{
|
||||
list($is_expression, $value) = $this->getDefaultValue();
|
||||
}
|
||||
|
||||
return [$is_expression, $value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value of this variable.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaultValue()
|
||||
{
|
||||
// Get the current column name.
|
||||
$column = $this instanceof ColumnWrite ? $this->name : $this->column;
|
||||
|
||||
// If the default value is a column name, escape it.
|
||||
if (strpos($this->default, '.') !== false && Query::isValidColumnName($this->default))
|
||||
{
|
||||
return [true, Query::quoteName($this->default)];
|
||||
}
|
||||
elseif (isset($column) && preg_match('/_srl$/', $column) && !is_numeric($this->default))
|
||||
{
|
||||
return [true, Query::quoteName($this->default)];
|
||||
}
|
||||
|
||||
// If the default value is a function shortcut, return an appropriate value.
|
||||
switch ($this->default)
|
||||
{
|
||||
case 'ipaddress()':
|
||||
return [false, \RX_CLIENT_IP];
|
||||
case 'unixtime()':
|
||||
return [false, time()];
|
||||
case 'curdate()':
|
||||
case 'datetime()':
|
||||
return [false, date('YmdHis')];
|
||||
case 'date()':
|
||||
return [false, date('Ymd')];
|
||||
case 'time()':
|
||||
return [false, date('His')];
|
||||
case 'member_srl()':
|
||||
return [false, intval(\Rhymix\Framework\Session::getMemberSrl())];
|
||||
case 'sequence()':
|
||||
return [false, getNextSequence()];
|
||||
}
|
||||
|
||||
// If the default value is a calculation based on the current value, return a query string.
|
||||
if (isset($column) && preg_match('/^(plus|minus|multiply)\(([0-9]+)\)$/', $this->default, $matches))
|
||||
{
|
||||
switch ($matches[1])
|
||||
{
|
||||
case 'plus':
|
||||
return [true, sprintf('%s + %d', Query::quoteName($column), $matches[2])];
|
||||
case 'minus':
|
||||
return [true, sprintf('%s - %d', Query::quoteName($column), $matches[2])];
|
||||
case 'multiply':
|
||||
return [true, sprintf('%s * %d', Query::quoteName($column), $matches[2])];
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, just return the literal value.
|
||||
return [false, $this->default];
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter a value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function filterValue($value)
|
||||
{
|
||||
// Don't apply a filter if there is no variable.
|
||||
$column = $this instanceof ColumnWrite ? $this->name : $this->column;
|
||||
$filter = isset($this->filter) ? $this->filter : '';
|
||||
if (strval($value) === '')
|
||||
{
|
||||
$filter = '';
|
||||
}
|
||||
|
||||
// Apply filters.
|
||||
switch ($filter)
|
||||
{
|
||||
case 'email':
|
||||
case 'email_address':
|
||||
if (!preg_match('/^[\w-]+((?:\.|\+|\~)[\w-]+)*@[\w-]+(\.[\w-]+)+$/', $value))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $column . ' must contain a valid e-mail address');
|
||||
}
|
||||
break;
|
||||
case 'homepage':
|
||||
case 'url':
|
||||
if (!preg_match('/^(http|https)+(:\/\/)+[0-9a-z_-]+\.[^ ]+$/i', $value))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $column . ' must contain a valid URL');
|
||||
}
|
||||
break;
|
||||
case 'userid':
|
||||
case 'user_id':
|
||||
if (!preg_match('/^[a-zA-Z]+([_0-9a-zA-Z]+)*$/', $value))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $column . ' must contain a valid user ID');
|
||||
}
|
||||
break;
|
||||
case 'number':
|
||||
case 'numbers':
|
||||
if (!preg_match('/^(-?)[0-9]+(,\-?[0-9]+)*$/', is_array($value) ? implode(',', $value) : $value))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $column . ' must contain a valid number');
|
||||
}
|
||||
break;
|
||||
case 'alpha':
|
||||
if (!ctype_alpha($value))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $column . ' must contain only alphabets');
|
||||
}
|
||||
break;
|
||||
case 'alnum':
|
||||
case 'alpha_number':
|
||||
if (!ctype_alnum($value))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $column . ' must contain only alphanumeric characters');
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Check minimum and maximum lengths.
|
||||
$length = is_scalar($value) ? iconv_strlen($value, 'UTF-8') : (is_countable($value) ? count($value) : 1);
|
||||
if (isset($this->minlength) && $this->minlength > 0 && $length < $this->minlength)
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $column . ' must contain no less than ' . $this->minlength . ' characters');
|
||||
}
|
||||
if (isset($this->maxlength) && $this->maxlength > 0 && $length > $this->maxlength)
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $column . ' must contain no more than ' . $this->minlength . ' characters');
|
||||
}
|
||||
}
|
||||
}
|
||||
251
common/framework/parsers/dbqueryparser.php
Normal file
251
common/framework/parsers/dbqueryparser.php
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers;
|
||||
|
||||
/**
|
||||
* DB query parser class for XE compatibility.
|
||||
*/
|
||||
class DBQueryParser extends BaseParser
|
||||
{
|
||||
/**
|
||||
* Load a query XML file.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return object|false
|
||||
*/
|
||||
public static function loadXML(string $filename)
|
||||
{
|
||||
// Load the XML file.
|
||||
$xml = simplexml_load_string(file_get_contents($filename));
|
||||
if ($xml === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the query.
|
||||
$query_name = preg_replace('/\.xml$/', '', basename($filename));
|
||||
$query = self::_parseQuery($xml, $query_name);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a query.
|
||||
*
|
||||
* @param SimpleXMLElement $xml
|
||||
* @param string $name
|
||||
* @return object
|
||||
*/
|
||||
protected static function _parseQuery(\SimpleXMLElement $xml, string $name = ''): DBQuery\Query
|
||||
{
|
||||
// Load basic information about this query.
|
||||
$attribs = self::_getAttributes($xml);
|
||||
$query = new DBQuery\Query;
|
||||
$query->name = $name ?: null;
|
||||
$query->type = strtoupper($attribs['action']) ?: 'SELECT';
|
||||
$query->alias = $attribs['alias'] ?? null;
|
||||
if ($query->alias && !$query->name)
|
||||
{
|
||||
$query->name = $query->alias;
|
||||
}
|
||||
|
||||
// Load attributes that only apply to subqueries in the <conditions> block.
|
||||
$query->operation = $attribs['operation'] ?? null;
|
||||
$query->column = preg_replace('/[^a-z0-9_\.]/i', '', $attribs['column']) ?: null;
|
||||
$query->pipe = strtoupper($attribs['pipe']) ?: 'AND';
|
||||
|
||||
// Load tables.
|
||||
foreach ($xml->tables ? $xml->tables->children() : [] as $tag)
|
||||
{
|
||||
if (trim($tag['query']) === 'true')
|
||||
{
|
||||
$table = self::_parseQuery($tag);
|
||||
$query->tables[$table->alias] = $table;
|
||||
}
|
||||
else
|
||||
{
|
||||
$table = new DBQuery\Table;
|
||||
$table->name = trim($tag['name']);
|
||||
$table->alias = trim($tag['alias']) ?: $table->name;
|
||||
}
|
||||
|
||||
$table_type = trim($tag['type']);
|
||||
if (stripos($table_type, 'join') !== false)
|
||||
{
|
||||
$table->join_type = strtoupper($table_type);
|
||||
if ($tag->conditions)
|
||||
{
|
||||
$table->join_conditions = self::_parseConditions($tag->conditions);
|
||||
}
|
||||
}
|
||||
$query->tables[$table->alias] = $table;
|
||||
}
|
||||
|
||||
// Load columns.
|
||||
foreach ($xml->columns ? $xml->columns->children() : [] as $tag)
|
||||
{
|
||||
if ($tag->getName() === 'query')
|
||||
{
|
||||
$subquery = self::_parseQuery($tag, trim($tag['id']));
|
||||
$query->columns[] = $subquery;
|
||||
}
|
||||
elseif ($query->type === 'SELECT')
|
||||
{
|
||||
$column = new DBQuery\ColumnRead;
|
||||
$column->name = trim($tag['name']);
|
||||
$column->alias = trim($tag['alias']) ?: null;
|
||||
if ($column->name === '*' || preg_match('/\.\*$/', $column->name))
|
||||
{
|
||||
$column->is_wildcard = true;
|
||||
}
|
||||
if (!DBQuery\Query::isValidColumnName($column->name))
|
||||
{
|
||||
$column->is_expression = true;
|
||||
}
|
||||
$query->columns[] = $column;
|
||||
}
|
||||
else
|
||||
{
|
||||
$attribs = self::_getAttributes($tag);
|
||||
$column = new DBQuery\ColumnWrite;
|
||||
$column->name = $attribs['name'];
|
||||
$column->operation = $attribs['operation'] ?: 'equal';
|
||||
$column->var = $attribs['var'] ?? null;
|
||||
$column->default = $attribs['default'] ?? null;
|
||||
$column->not_null = $attribs['notnull'] ? true : false;
|
||||
$column->filter = $attribs['filter'] ?? null;
|
||||
$column->minlength = intval($attribs['minlength'], 10);
|
||||
$column->maxlength = intval($attribs['maxlength'], 10);
|
||||
$query->columns[] = $column;
|
||||
}
|
||||
}
|
||||
|
||||
// Load conditions.
|
||||
if ($xml->conditions)
|
||||
{
|
||||
$query->conditions = self::_parseConditions($xml->conditions);
|
||||
}
|
||||
|
||||
// Load groups.
|
||||
if ($xml->groups)
|
||||
{
|
||||
$query->groupby = new DBQuery\GroupBy;
|
||||
foreach ($xml->groups->children() as $tag)
|
||||
{
|
||||
$name = $tag->getName();
|
||||
if ($name === 'group')
|
||||
{
|
||||
$query->groupby->columns[] = trim($tag['column']);
|
||||
}
|
||||
elseif ($name === 'having')
|
||||
{
|
||||
$query->groupby->having = self::_parseConditions($tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load navigation settings.
|
||||
if ($xml->navigation)
|
||||
{
|
||||
$query->navigation = new DBQuery\Navigation;
|
||||
foreach ($xml->navigation->index ?: [] as $tag)
|
||||
{
|
||||
$orderby = new DBQuery\OrderBy;
|
||||
$orderby->var = trim($tag['var']) ?: null;
|
||||
$orderby->default = trim($tag['default']) ?: null;
|
||||
$orderby->order_var = trim($tag['order']) ?: null;
|
||||
$query->navigation->orderby[] = $orderby;
|
||||
}
|
||||
foreach (['list_count', 'page_count', 'page', 'offset'] as $key)
|
||||
{
|
||||
if ($tag = $xml->navigation->{$key})
|
||||
{
|
||||
$query->navigation->{$key} = new DBQuery\VariableBase;
|
||||
$query->navigation->{$key}->var = trim($tag['var']) ?: null;
|
||||
$query->navigation->{$key}->default = trim($tag['default']) ?: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If a SELECT query has no columns, use * by default.
|
||||
if ($query->type === 'SELECT' && !count($query->columns))
|
||||
{
|
||||
$column = new DBQuery\ColumnRead;
|
||||
$column->name = '*';
|
||||
$column->is_wildcard = true;
|
||||
$column->is_expression = true;
|
||||
$query->columns[] = $column;
|
||||
}
|
||||
|
||||
// Check the SELECT DISTINCT flag.
|
||||
if ($xml->columns && $select_distinct = trim($xml->columns['distinct']))
|
||||
{
|
||||
if ($select_distinct === 'distinct' || toBool($select_distinct))
|
||||
{
|
||||
$query->select_distinct = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the ON DUPLICATE KEY UPDATE (upsert) flag.
|
||||
if ($query->type === 'INSERT' && $update_duplicate = self::_getAttributes($xml)['updateduplicate'])
|
||||
{
|
||||
if (toBool($update_duplicate))
|
||||
{
|
||||
$query->update_duplicate = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the complete query definition.
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse conditions.
|
||||
*
|
||||
* @param SimpleXMLElement $parent
|
||||
* @return array
|
||||
*/
|
||||
protected static function _parseConditions(\SimpleXMLElement $parent): array
|
||||
{
|
||||
$result = array();
|
||||
foreach ($parent->children() as $tag)
|
||||
{
|
||||
$attribs = self::_getAttributes($tag);
|
||||
$name = $tag->getName();
|
||||
if ($name === 'condition')
|
||||
{
|
||||
$cond = new DBQuery\Condition;
|
||||
$cond->operation = $attribs['operation'];
|
||||
$cond->column = $attribs['column'];
|
||||
if (isset($attribs['var']) && !isset($attribs['default']) && preg_match('/^\w+\.\w+$/', $attribs['var']))
|
||||
{
|
||||
$cond->default = $attribs['var'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$cond->var = $attribs['var'] ?? null;
|
||||
$cond->default = $attribs['default'] ?? null;
|
||||
}
|
||||
$cond->not_null = $attribs['notnull'] ? true : false;
|
||||
$cond->filter = $attribs['filter'] ?? null;
|
||||
$cond->minlength = intval($attribs['minlength'], 10);
|
||||
$cond->maxlength = intval($attribs['maxlength'], 10);
|
||||
$cond->pipe = strtoupper($attribs['pipe']) ?: 'AND';
|
||||
$result[] = $cond;
|
||||
}
|
||||
elseif ($name === 'group')
|
||||
{
|
||||
$group = new DBQuery\ConditionGroup;
|
||||
$group->conditions = self::_parseConditions($tag);
|
||||
$group->pipe = strtoupper($attribs['pipe']) ?: 'AND';
|
||||
$result[] = $group;
|
||||
}
|
||||
elseif ($name === 'query')
|
||||
{
|
||||
$subquery = self::_parseQuery($tag);
|
||||
$result[] = $subquery;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue