mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-04 17:21:39 +09:00
Merge branch 'develop' into pr/1851
This commit is contained in:
commit
4eced6daf0
71 changed files with 1045 additions and 508 deletions
|
|
@ -388,7 +388,7 @@ class Context
|
|||
else
|
||||
{
|
||||
self::set('is_logged', false);
|
||||
self::set('logged_info', Rhymix\Framework\Session::getMemberInfo());
|
||||
self::set('logged_info', false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class ModuleObject extends BaseObject
|
|||
// Populate default properties.
|
||||
$obj->setModulePath($module_path);
|
||||
$obj->setModule($module);
|
||||
$obj->user = Context::get('logged_info') ?: new Rhymix\Framework\Helpers\SessionHelper;
|
||||
$obj->user = Context::get('logged_info');
|
||||
if(!($obj->user instanceof Rhymix\Framework\Helpers\SessionHelper))
|
||||
{
|
||||
$obj->user = Rhymix\Framework\Session::getMemberInfo();
|
||||
|
|
@ -248,7 +248,7 @@ class ModuleObject extends BaseObject
|
|||
*/
|
||||
public function setPrivileges()
|
||||
{
|
||||
if(Context::get('logged_info')->is_admin !== 'Y')
|
||||
if(!$this->user->isAdmin())
|
||||
{
|
||||
// Get privileges(granted) information for target module by <permission check> of module.xml
|
||||
if(($permission = $this->xml_info->action->{$this->act}->permission) && $permission->check_var)
|
||||
|
|
@ -296,7 +296,7 @@ class ModuleObject extends BaseObject
|
|||
if(!isset($grant))
|
||||
{
|
||||
// Get privileges(granted) information of current user for current module
|
||||
$grant = ModuleModel::getInstance()->getGrant($this->module_info, Context::get('logged_info'), $this->xml_info);
|
||||
$grant = ModuleModel::getInstance()->getGrant($this->module_info, $this->user, $this->xml_info);
|
||||
|
||||
// Check permission
|
||||
if($this->checkPermission($grant) !== true)
|
||||
|
|
@ -331,7 +331,7 @@ class ModuleObject extends BaseObject
|
|||
// Get logged-in member information
|
||||
if(!$member_info)
|
||||
{
|
||||
$member_info = Context::get('logged_info');
|
||||
$member_info = $this->user;
|
||||
}
|
||||
|
||||
// Get privileges(granted) information of the member for current module
|
||||
|
|
@ -347,7 +347,7 @@ class ModuleObject extends BaseObject
|
|||
}
|
||||
|
||||
// Get permission types(guest, member, manager, root) of the currently requested action
|
||||
$permission = $this->xml_info->action->{$this->act}->permission->target ?: $this->xml_info->permission->{$this->act};
|
||||
$permission = $this->xml_info->action->{$this->act}->permission->target ?: ($this->xml_info->permission->{$this->act} ?? null);
|
||||
|
||||
// If admin action, set default permission
|
||||
if(empty($permission) && stripos($this->act, 'admin') !== false)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class TemplateHandler
|
|||
ini_set('pcre.jit', false);
|
||||
$this->config = new stdClass;
|
||||
$this->handler_mtime = filemtime(__FILE__);
|
||||
$this->user = Rhymix\Framework\Session::getMemberInfo() ?: new Rhymix\Framework\Helpers\SessionHelper;
|
||||
$this->user = Rhymix\Framework\Session::getMemberInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class Validator
|
|||
$this->addRule(array(
|
||||
'email' => '/^[\w-]+((?:\.|\+|\~)[\w-]+)*@[\w-]+(\.[\w-]+)+$/',
|
||||
'userid' => '/^[a-z]+[\w-]*[a-z0-9_]+$/i',
|
||||
'url' => '/^(https?|ftp|mms):\/\/[0-9a-z-]+(\.[_0-9a-z-]+)+(:\d+)?/',
|
||||
'url' => '/^https?:\/\/[^\\\\/]+!',
|
||||
'alpha' => '/^[a-z]*$/i',
|
||||
'alpha_number' => '/^[a-z][a-z0-9_]*$/i',
|
||||
'number' => '/^(?:[1-9]\\d*|0)$/',
|
||||
|
|
|
|||
|
|
@ -129,31 +129,31 @@ class XmlJsFilter extends XeXmlParser
|
|||
|
||||
// XmlJsFilter handles three data; filter_name, field, and parameter
|
||||
$filter_name = $attrs->name;
|
||||
$confirm_msg_code = $attrs->confirm_msg_code;
|
||||
$confirm_msg_code = $attrs->confirm_msg_code ?? null;
|
||||
$module = $attrs->module;
|
||||
$act = $attrs->act;
|
||||
$extend_filter = $attrs->extend_filter;
|
||||
$extend_filter = $attrs->extend_filter ?? null;
|
||||
|
||||
|
||||
$field_node = $xml_obj->filter->form->node;
|
||||
$field_node = $xml_obj->filter->form->node ?? null;
|
||||
if($field_node && !is_array($field_node))
|
||||
{
|
||||
$field_node = array($field_node);
|
||||
}
|
||||
|
||||
$parameter_param = $xml_obj->filter->parameter->param;
|
||||
$parameter_param = $xml_obj->filter->parameter->param ?? null;
|
||||
if($parameter_param && !is_array($parameter_param))
|
||||
{
|
||||
$parameter_param = array($parameter_param);
|
||||
}
|
||||
|
||||
$response_tag = $xml_obj->filter->response->tag;
|
||||
$response_tag = $xml_obj->filter->response->tag ?? null;
|
||||
if($response_tag && !is_array($response_tag))
|
||||
{
|
||||
$response_tag = array($response_tag);
|
||||
}
|
||||
|
||||
// If extend_filter exists, result returned by calling the method
|
||||
$extend_filter_count = 0;
|
||||
if($extend_filter)
|
||||
{
|
||||
// If extend_filter exists, it changes the name of cache not to use cache
|
||||
|
|
@ -261,9 +261,9 @@ class XmlJsFilter extends XeXmlParser
|
|||
{
|
||||
$target_list[] = $target;
|
||||
}
|
||||
if(!$target_type_list[$target])
|
||||
if(!isset($target_type_list[$target]))
|
||||
{
|
||||
$target_type_list[$target] = $filter;
|
||||
$target_type_list[$target] = $filter ?? null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class XeXmlParser
|
|||
/**
|
||||
* Load a xml file specified by a filename and parse it to Return the resultant data object
|
||||
* @param string $filename a file path of file
|
||||
* @return array Returns a data object containing data extracted from a xml file or NULL if a specified file does not exist
|
||||
* @return object|null Returns a data object containing data extracted from a xml file or NULL if a specified file does not exist
|
||||
*/
|
||||
function loadXmlFile($filename)
|
||||
{
|
||||
|
|
@ -84,7 +84,7 @@ class XeXmlParser
|
|||
* @param string $input a data buffer containing xml data
|
||||
* @param mixed $arg1 ???
|
||||
* @param mixed $arg2 ???
|
||||
* @return array Returns a resultant data object or NULL in case of error
|
||||
* @return object|null Returns a resultant data object or NULL in case of error
|
||||
*/
|
||||
function parse($input = '', $arg1 = NULL, $arg2 = NULL)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -224,9 +224,9 @@ class DB
|
|||
* @param array $columns
|
||||
* @param string $result_type
|
||||
* @param string $result_class
|
||||
* @return \BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function executeQuery(string $query_id, $args = [], $column_list = [], $result_type = 'auto', $result_class = ''): \BaseObject
|
||||
public function executeQuery(string $query_id, $args = [], $column_list = [], $result_type = 'auto', $result_class = ''): Helpers\DBResultHelper
|
||||
{
|
||||
// Validate the args.
|
||||
if (is_object($args))
|
||||
|
|
@ -328,7 +328,7 @@ class DB
|
|||
}
|
||||
else
|
||||
{
|
||||
$output = new \BaseObject;
|
||||
$output = new Helpers\DBResultHelper;
|
||||
}
|
||||
|
||||
// Prepare and execute the main query.
|
||||
|
|
@ -402,9 +402,9 @@ class DB
|
|||
* @param Parsers\DBQuery\Query $query
|
||||
* @param array $args
|
||||
* @param int $last_index
|
||||
* @return BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
protected function _executeCountQuery(string $query_id, Parsers\DBQuery\Query $query, array $args, int &$last_index): \BaseObject
|
||||
protected function _executeCountQuery(string $query_id, Parsers\DBQuery\Query $query, array $args, int &$last_index): Helpers\DBResultHelper
|
||||
{
|
||||
// Get the COUNT(*) query string and parameters.
|
||||
try
|
||||
|
|
@ -467,7 +467,7 @@ class DB
|
|||
$page_handler = new \PageHandler($total_count, $total_page, $page, $page_count);
|
||||
|
||||
// Compose the output object.
|
||||
$output = new \BaseObject;
|
||||
$output = new Helpers\DBResultHelper;
|
||||
$output->add('_count', $query_string);
|
||||
$output->total_count = $total_count;
|
||||
$output->total_page = $total_page;
|
||||
|
|
@ -733,9 +733,9 @@ class DB
|
|||
*
|
||||
* @param string $filename
|
||||
* @param string $content
|
||||
* @return BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function createTable(string $filename = '', string $content = ''): \BaseObject
|
||||
public function createTable(string $filename = '', string $content = ''): Helpers\DBResultHelper
|
||||
{
|
||||
// Get the table definition from DBTableParser.
|
||||
$table = Parsers\DBTableParser::loadXML($filename, $content);
|
||||
|
|
@ -745,25 +745,25 @@ class DB
|
|||
}
|
||||
if ($table->deleted)
|
||||
{
|
||||
return new \BaseObject;
|
||||
return new Helpers\DBResultHelper;
|
||||
}
|
||||
|
||||
// Generate the CREATE TABLE query and execute it.
|
||||
$query_string = $table->getCreateQuery($this->_prefix, $this->_charset, $this->_engine);
|
||||
$result = $this->_handle->exec($query_string);
|
||||
return $result ? new \BaseObject : $this->getError();
|
||||
return $result ? new Helpers\DBResultHelper : $this->getError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a table.
|
||||
*
|
||||
* @param string $table_name
|
||||
* @return BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function dropTable(string $table_name): \BaseObject
|
||||
public function dropTable(string $table_name): Helpers\DBResultHelper
|
||||
{
|
||||
$stmt = $this->_handle->exec(sprintf("DROP TABLE `%s`", $this->addQuotes($this->_prefix . $table_name)));
|
||||
return $stmt ? new \BaseObject : $this->getError();
|
||||
return $stmt ? new Helpers\DBResultHelper : $this->getError();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -790,9 +790,9 @@ class DB
|
|||
* @param mixed $default
|
||||
* @param bool $notnull
|
||||
* @param string $after_column
|
||||
* @return BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function addColumn(string $table_name, string $column_name, string $type = 'number', $size = null, $default = null, $notnull = false, $after_column = null): \BaseObject
|
||||
public function addColumn(string $table_name, string $column_name, string $type = 'number', $size = null, $default = null, $notnull = false, $after_column = null): Helpers\DBResultHelper
|
||||
{
|
||||
// Normalize the type and size.
|
||||
list($type, $xetype, $size) = Parsers\DBTableParser::getTypeAndSize($type, strval($size));
|
||||
|
|
@ -827,7 +827,7 @@ class DB
|
|||
|
||||
// Execute the query and return the result.
|
||||
$result = $this->_handle->exec($query);
|
||||
return $result ? new \BaseObject : $this->getError();
|
||||
return $result ? new Helpers\DBResultHelper : $this->getError();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -842,9 +842,9 @@ class DB
|
|||
* @param string $after_column
|
||||
* @param string $new_name
|
||||
* @param string $new_charset
|
||||
* @return BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function modifyColumn(string $table_name, string $column_name, string $type = 'number', $size = null, $default = null, $notnull = false, $after_column = null, $new_name = null, $new_charset = null): \BaseObject
|
||||
public function modifyColumn(string $table_name, string $column_name, string $type = 'number', $size = null, $default = null, $notnull = false, $after_column = null, $new_name = null, $new_charset = null): Helpers\DBResultHelper
|
||||
{
|
||||
// Normalize the type and size.
|
||||
list($type, $xetype, $size) = Parsers\DBTableParser::getTypeAndSize($type, strval($size));
|
||||
|
|
@ -895,7 +895,7 @@ class DB
|
|||
|
||||
// Execute the query and return the result.
|
||||
$result = $this->_handle->exec($query);
|
||||
return $result ? new \BaseObject : $this->getError();
|
||||
return $result ? new Helpers\DBResultHelper : $this->getError();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -903,12 +903,12 @@ class DB
|
|||
*
|
||||
* @param string $table_name
|
||||
* @param string $column_name
|
||||
* @return BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function dropColumn(string $table_name, string $column_name): \BaseObject
|
||||
public function dropColumn(string $table_name, string $column_name): Helpers\DBResultHelper
|
||||
{
|
||||
$result = $this->_handle->exec(sprintf("ALTER TABLE `%s` DROP `%s`", $this->addQuotes($this->_prefix . $table_name), $this->addQuotes($column_name)));
|
||||
return $result ? new \BaseObject : $this->getError();
|
||||
return $result ? new Helpers\DBResultHelper : $this->getError();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -974,9 +974,9 @@ class DB
|
|||
* @param array $columns
|
||||
* @param string $type
|
||||
* @param string $options
|
||||
* @return \BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function addIndex(string $table_name, string $index_name, $columns, $type = '', $options = ''): \BaseObject
|
||||
public function addIndex(string $table_name, string $index_name, $columns, $type = '', $options = ''): Helpers\DBResultHelper
|
||||
{
|
||||
if (!is_array($columns))
|
||||
{
|
||||
|
|
@ -1006,7 +1006,7 @@ class DB
|
|||
));
|
||||
|
||||
$result = $this->_handle->exec($query);
|
||||
return $result ? new \BaseObject : $this->getError();
|
||||
return $result ? new Helpers\DBResultHelper : $this->getError();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1014,12 +1014,12 @@ class DB
|
|||
*
|
||||
* @param string $table_name
|
||||
* @param string $index_name
|
||||
* @return BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function dropIndex(string $table_name, string $index_name): \BaseObject
|
||||
public function dropIndex(string $table_name, string $index_name): Helpers\DBResultHelper
|
||||
{
|
||||
$result = $this->_handle->exec(sprintf("ALTER TABLE `%s` DROP INDEX `%s`", $this->addQuotes($this->_prefix . $table_name), $this->addQuotes($index_name)));
|
||||
return $result ? new \BaseObject : $this->getError();
|
||||
return $result ? new Helpers\DBResultHelper : $this->getError();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1046,7 +1046,7 @@ class DB
|
|||
}
|
||||
else
|
||||
{
|
||||
return sprintf('`%s%s`', $this->_prefix, $m[1]);
|
||||
return isset($m[2]) ? sprintf('`%s%s` AS `%s`', $this->_prefix, $m[1], $m[2]) : sprintf('`%s%s`', $this->_prefix, $m[1]);
|
||||
}
|
||||
}, trim($str));
|
||||
}, explode(',', $m[2]));
|
||||
|
|
@ -1100,11 +1100,11 @@ class DB
|
|||
/**
|
||||
* Get the last error information.
|
||||
*
|
||||
* @return \BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function getError(): \BaseObject
|
||||
public function getError(): Helpers\DBResultHelper
|
||||
{
|
||||
return new \BaseObject($this->_errno, $this->_errstr);
|
||||
return new Helpers\DBResultHelper($this->_errno, $this->_errstr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1112,13 +1112,13 @@ class DB
|
|||
*
|
||||
* @param int $errno
|
||||
* @param string $errstr
|
||||
* @return BaseObject
|
||||
* @return Helpers\DBResultHelper
|
||||
*/
|
||||
public function setError(int $errno = 0, string $errstr = 'success'): \BaseObject
|
||||
public function setError(int $errno = 0, string $errstr = 'success'): Helpers\DBResultHelper
|
||||
{
|
||||
$this->_errno = $errno;
|
||||
$this->_errstr = $errstr;
|
||||
$output = new \BaseObject($errno, $errstr);
|
||||
$output = new Helpers\DBResultHelper($errno, $errstr);
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -351,12 +351,17 @@ class Formatter
|
|||
$content = utf8_clean(file_get_contents($filename));
|
||||
|
||||
// Convert all paths in LESS and SCSS imports, too.
|
||||
$dirname = dirname($filename);
|
||||
$import_type = ends_with('.scss', $filename) ? 'scss' : 'normal';
|
||||
$content = preg_replace_callback('/@import\s+(?:\\([^()]+\\))?([^;]+);/', function($matches) use($filename, $target_filename, $import_type, &$imported_list) {
|
||||
$content = preg_replace_callback('/@import\s+([^\r\n]+);(?=[\r\n$])/', function($matches) use($dirname, $filename, $target_filename, $import_type, &$imported_list) {
|
||||
if (preg_match('!^url\([\'"]?((?:https?:)?//[^()\'"]+)!i', $matches[1], $urlmatches))
|
||||
{
|
||||
return '@import url("' . escape_dqstr($urlmatches[1]) . '");';
|
||||
}
|
||||
$import_content = '';
|
||||
$import_files = array_map(function($str) use($filename, $import_type) {
|
||||
$str = trim(trim(trim(preg_replace('/^url\\(([^()]+)\\)$/', '$1', trim($str))), '"\''));
|
||||
if (preg_match('!^(https?:)?//!i', $str))
|
||||
$import_files = array_map(function($str) use($dirname, $filename, $import_type) {
|
||||
$str = trim(trim(trim(preg_replace('!^url\([\'"]?([^()\'"]+)[\'"]?\)!i', '$1', $str)), '"\''));
|
||||
if (preg_match('!^(?:https?:)?//!i', $str))
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
|
@ -369,7 +374,7 @@ class Formatter
|
|||
{
|
||||
$basename = '_' . $basename . '.scss';
|
||||
}
|
||||
return dirname($filename) . '/' . substr($str, 0, $dirpos) . '/' . $basename;
|
||||
return $dirname . '/' . substr($str, 0, $dirpos) . '/' . $basename;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -378,7 +383,7 @@ class Formatter
|
|||
{
|
||||
$basename = '_' . $basename . '.scss';
|
||||
}
|
||||
return dirname($filename) . '/' . $basename;
|
||||
return $dirname . '/' . $basename;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -388,22 +393,19 @@ class Formatter
|
|||
}, explode(',', $matches[1]));
|
||||
foreach ($import_files as $import_filename)
|
||||
{
|
||||
if (!preg_match('!^(https?:)?//!i', $import_filename))
|
||||
if (preg_match('!^(https?:)?//!i', $import_filename))
|
||||
{
|
||||
if (file_exists($import_filename))
|
||||
{
|
||||
$imported_list[] = $import_filename;
|
||||
$import_content .= self::concatCSS($import_filename, $target_filename, false, $imported_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
$error_filename = substr($import_filename, strlen(\RX_BASEDIR));
|
||||
trigger_error('Imported file not found: ' . $error_filename, \E_USER_WARNING);
|
||||
}
|
||||
$import_content .= '@import url("' . escape_dqstr($import_filename) . '");';
|
||||
}
|
||||
elseif (file_exists($import_filename))
|
||||
{
|
||||
$imported_list[] = $import_filename;
|
||||
$import_content .= self::concatCSS($import_filename, $target_filename, false, $imported_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
$import_content .= '@import url("' . escape_dqstr($import_filename) . '");';
|
||||
$error_filename = substr($import_filename, strlen(\RX_BASEDIR));
|
||||
trigger_error('Imported file not found: ' . $error_filename, \E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
return trim($import_content);
|
||||
|
|
|
|||
15
common/framework/helpers/dbresulthelper.php
Normal file
15
common/framework/helpers/dbresulthelper.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Helpers;
|
||||
|
||||
/**
|
||||
* DB result helper class.
|
||||
*
|
||||
* Instances of this class will be returned from DB queries.
|
||||
*/
|
||||
class DBResultHelper extends \BaseObject
|
||||
{
|
||||
// Additional attributes for DB query results.
|
||||
public $page_navigation;
|
||||
public $data;
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ class SessionHelper
|
|||
* @param int $member_srl (optional)
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($member_srl = null)
|
||||
public function __construct($member_srl = 0)
|
||||
{
|
||||
// Load member information.
|
||||
$member_srl = intval($member_srl);
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ abstract class BaseParser
|
|||
$item = new \stdClass;
|
||||
$item->group = $group_name;
|
||||
$item->name = trim($var['name']);
|
||||
$item->type = trim($var['type']);
|
||||
$item->type = trim($var['type']) ?: 'text';
|
||||
$item->title = self::_getChildrenByLang($var, 'title', $lang);
|
||||
$item->description = str_replace('\\n', "\n", self::_getChildrenByLang($var, 'description', $lang));
|
||||
$item->default = trim($var['default']) ?: null;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,17 @@ class VariableBase
|
|||
$this->filterValue('');
|
||||
$value = strval($args[$this->var]);
|
||||
$is_expression = true;
|
||||
if ($args[$this->var] instanceof NullValue)
|
||||
{
|
||||
if ($this->not_null)
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must not be null');
|
||||
}
|
||||
if ($this instanceof Condition && in_array($this->operation, ['equal', 'notequal', 'not_equal']))
|
||||
{
|
||||
$this->operation = ($this->operation === 'equal') ? 'null' : 'notnull';
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($args[$this->var] === '')
|
||||
{
|
||||
|
|
|
|||
|
|
@ -281,4 +281,71 @@ class DBTableParser extends BaseParser
|
|||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Order tables according to foreign key relations.
|
||||
*
|
||||
* @param array $tables [$table_name => $filename]
|
||||
* @return array
|
||||
*/
|
||||
public static function resolveDependency(array $tables): array
|
||||
{
|
||||
// Compile the list of each table's dependency.
|
||||
$ref_list = [];
|
||||
$i = 0;
|
||||
foreach ($tables as $table_name => $filename)
|
||||
{
|
||||
$table = self::loadXML($filename);
|
||||
if ($table)
|
||||
{
|
||||
$info = (object)['name' => $table_name, 'refs' => [], 'index' => $i++];
|
||||
foreach ($table->constraints as $constraint)
|
||||
{
|
||||
if ($constraint->references)
|
||||
{
|
||||
$ref = explode('.', $constraint->references);
|
||||
$info->refs[] = $ref[0];
|
||||
}
|
||||
}
|
||||
$ref_list[$table_name] = $info;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort each table after the ones they are dependent on.
|
||||
for ($j = 0; $j < count($ref_list); $j++)
|
||||
{
|
||||
$changed = false;
|
||||
foreach ($ref_list as $table_name => $info)
|
||||
{
|
||||
if (count($info->refs))
|
||||
{
|
||||
foreach ($info->refs as $ref_name)
|
||||
{
|
||||
if (isset($ref_list[$ref_name]) && $info->index <= $ref_list[$ref_name]->index)
|
||||
{
|
||||
$info->index = $ref_list[$ref_name]->index + 1;
|
||||
$changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$k++;
|
||||
}
|
||||
if (!$changed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uasort($ref_list, function($a, $b) {
|
||||
return $a->index - $b->index;
|
||||
});
|
||||
|
||||
// Produce a result in the same format as the input.
|
||||
$result = [];
|
||||
foreach ($ref_list as $table_name => $info)
|
||||
{
|
||||
$result[$table_name] = $tables[$table_name];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -734,7 +734,7 @@ class Session
|
|||
* This method returns an object, or false if nobody is logged in.
|
||||
*
|
||||
* @param bool $refresh
|
||||
* @return object|false
|
||||
* @return Helpers\SessionHelper
|
||||
*/
|
||||
public static function getMemberInfo($refresh = false)
|
||||
{
|
||||
|
|
@ -742,7 +742,7 @@ class Session
|
|||
$member_srl = self::getMemberSrl();
|
||||
if (!$member_srl)
|
||||
{
|
||||
return false;
|
||||
return new Helpers\SessionHelper(0);
|
||||
}
|
||||
|
||||
// Create a member info object.
|
||||
|
|
@ -752,7 +752,7 @@ class Session
|
|||
}
|
||||
|
||||
// Return the member info object.
|
||||
return self::$_member_info->member_srl ? self::$_member_info : false;
|
||||
return self::$_member_info;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<block loop="Context::getMetaTag() => $no, $val">
|
||||
<meta http-equiv="{$val['name']}"|cond="$val['is_http_equiv']" name="{$val['name']}"|cond="!$val['is_http_equiv']" content="{$val['content']}" />
|
||||
</block>
|
||||
<meta name="csrf-token" content="{($is_logged || $act) ? \Rhymix\Framework\Session::getGenericToken() : ''}" />
|
||||
<meta name="csrf-token" content="{($is_logged || ($act ?? '')) ? \Rhymix\Framework\Session::getGenericToken() : ''}" />
|
||||
|
||||
<!-- TITLE -->
|
||||
<title>{Context::getBrowserTitle()}</title>
|
||||
|
|
|
|||
|
|
@ -486,6 +486,9 @@
|
|||
<p>{str_replace('\n\n', '<br />', $lang->about_keep_signed)}</p>
|
||||
<div class="edge"></div>
|
||||
</div>
|
||||
<div class="captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('login')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<button type="submit" class="btn_submit">{$lang->cmd_login}</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="mail_smtp_pass">{$lang->cmd_advanced_mailer_smtp_pass}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="mail_{$driver_name}_smtp_pass" id="mail_{$driver_name}_smtp_pass" value="{$conf_value}" />
|
||||
<input type="password" name="mail_{$driver_name}_smtp_pass" id="mail_{$driver_name}_smtp_pass" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -167,7 +167,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="mail_{$driver_name}_api_pass">{$lang->cmd_advanced_mailer_api_pass}</label>
|
||||
<div class="x_controls full-width">
|
||||
<input type="password" name="mail_{$driver_name}_api_pass" id="mail_{$driver_name}_api_pass" value="{$conf_value}" />
|
||||
<input type="password" name="mail_{$driver_name}_api_pass" id="mail_{$driver_name}_api_pass" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -194,7 +194,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="mail_{$driver_name}_api_secret">{$lang->cmd_advanced_mailer_api_secret}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="mail_{$driver_name}_api_secret" id="mail_{$driver_name}_api_secret" value="{$conf_value}" />
|
||||
<input type="password" name="mail_{$driver_name}_api_secret" id="mail_{$driver_name}_api_secret" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -258,7 +258,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="sms_{$driver_name}_api_pass">{$lang->cmd_advanced_mailer_api_pass}</label>
|
||||
<div class="x_controls full-width">
|
||||
<input type="password" name="sms_{$driver_name}_api_pass" id="sms_{$driver_name}_api_pass" value="{$conf_value}" />
|
||||
<input type="password" name="sms_{$driver_name}_api_pass" id="sms_{$driver_name}_api_pass" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -285,7 +285,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="sms_{$driver_name}_api_secret">{$lang->cmd_advanced_mailer_api_secret}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="sms_{$driver_name}_api_secret" id="sms_{$driver_name}_api_secret" value="{$conf_value}" />
|
||||
<input type="password" name="sms_{$driver_name}_api_secret" id="sms_{$driver_name}_api_secret" value="{$conf_value}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -294,7 +294,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="sms_{$driver_name}_sender_key">{$lang->cmd_advanced_mailer_sender_key}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="sms_{$driver_name}_sender_key" id="sms_{$driver_name}_sender_key" value="{$conf_value}" />
|
||||
<input type="password" name="sms_{$driver_name}_sender_key" id="sms_{$driver_name}_sender_key" value="{$conf_value}" autocomplete="new-password" />
|
||||
<p class="x_help-block">{$lang->cmd_admin_sms_sender_key_help}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -363,7 +363,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="push_{$driver_name}_api_key">{$lang->cmd_advanced_mailer_fcm_api_key}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="push_{$driver_name}_api_key" id="push_{$driver_name}_api_key" value="{$conf_value|escape}" />
|
||||
<input type="password" name="push_{$driver_name}_api_key" id="push_{$driver_name}_api_key" value="{$conf_value|escape}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
@ -381,7 +381,7 @@
|
|||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||
<label class="x_control-label" for="push_{$driver_name}_passphrase">{$lang->cmd_advanced_mailer_apns_passphrase}</label>
|
||||
<div class="x_controls">
|
||||
<input type="password" name="push_{$driver_name}_passphrase" id="push_{$driver_name}_passphrase" value="{$conf_value|escape}" />
|
||||
<input type="password" name="push_{$driver_name}_passphrase" id="push_{$driver_name}_passphrase" value="{$conf_value|escape}" autocomplete="new-password" />
|
||||
</div>
|
||||
</div>
|
||||
<!--@end-->
|
||||
|
|
|
|||
|
|
@ -45,11 +45,11 @@ class boardView extends board
|
|||
$count_category = count(DocumentModel::getCategoryList($this->module_info->module_srl));
|
||||
if($count_category)
|
||||
{
|
||||
if($this->module_info->hide_category)
|
||||
if(isset($this->module_info->hide_category))
|
||||
{
|
||||
$this->module_info->use_category = ($this->module_info->hide_category == 'Y') ? 'N' : 'Y';
|
||||
}
|
||||
else if($this->module_info->use_category)
|
||||
elseif(isset($this->module_info->use_category))
|
||||
{
|
||||
$this->module_info->hide_category = ($this->module_info->use_category == 'Y') ? 'N' : 'Y';
|
||||
}
|
||||
|
|
@ -655,7 +655,7 @@ class boardView extends board
|
|||
// List of columns that should always be selected
|
||||
$defaultColumnList = array(
|
||||
'document_srl', 'module_srl', 'category_srl', 'lang_code', 'is_notice',
|
||||
'title', 'title_bold', 'title_color', 'member_srl', 'nick_name', 'extra_vars',
|
||||
'title', 'title_bold', 'title_color', 'member_srl', 'nick_name', 'tags', 'extra_vars',
|
||||
'comment_count', 'trackback_count', 'uploaded_count', 'status', 'regdate', 'last_update',
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
<load target="css/mboard.css" />
|
||||
|
||||
<div class="bd">
|
||||
<!--@if(isset($module_info->mobile_header_text) && $module_info->mobile_header_text)-->
|
||||
<div class="bd_header_text">{$module_info->mobile_header_text}</div>
|
||||
<!--@endif-->
|
||||
<!--@if($oDocument->isExists())-->
|
||||
<include target="read.html" />
|
||||
<!--@else-->
|
||||
<include target="_list.html" />
|
||||
<!--@end-->
|
||||
<!--@if(isset($module_info->mobile_footer_text) && $module_info->mobile_footer_text)-->
|
||||
<div class="bd_footer_text">{$module_info->mobile_footer_text}</div>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
<load target="css/mboard.css" />
|
||||
|
||||
<div class="bd">
|
||||
<!--@if(isset($module_info->mobile_header_text) && $module_info->mobile_header_text)-->
|
||||
<div class="bd_header_text">{$module_info->mobile_header_text}</div>
|
||||
<!--@endif-->
|
||||
<div class="hx h2">
|
||||
<h2><a href="{getUrl('','vid',$vid,'mid',$mid)}">{$module_info->browser_title}</a></h2>
|
||||
</div>
|
||||
|
|
@ -86,5 +89,8 @@
|
|||
<div class="bna">
|
||||
<button type="submit" class="bn dark">{$lang->cmd_registration}</button>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
<!--@if(isset($module_info->mobile_footer_text) && $module_info->mobile_footer_text)-->
|
||||
<div class="bd_footer_text">{$module_info->mobile_footer_text}</div>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
<load target="css/mboard.css" />
|
||||
|
||||
<div class="bd">
|
||||
<!--@if(isset($module_info->mobile_header_text) && $module_info->mobile_header_text)-->
|
||||
<div class="bd_header_text">{$module_info->mobile_header_text}</div>
|
||||
<!--@endif-->
|
||||
<!--@if($oDocument->isExists())-->
|
||||
<!--#include("read.html")-->
|
||||
<include target="read.html" />
|
||||
<!--@else-->
|
||||
<!--#include("_list.html")-->
|
||||
<include target="_list.html" />
|
||||
<!--@end-->
|
||||
<!--@if(isset($module_info->mobile_footer_text) && $module_info->mobile_footer_text)-->
|
||||
<div class="bd_footer_text">{$module_info->mobile_footer_text}</div>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
<load target="css/mboard.css" />
|
||||
|
||||
<div class="bd">
|
||||
<h2 class="h2"><a href="{getUrl('','vid',$vid,'mid',$mid)}">{$module_info->browser_title}</a> › {$lang->cmd_write}</h2>
|
||||
<!--@if(isset($module_info->mobile_header_text) && $module_info->mobile_header_text)-->
|
||||
<div class="bd_header_text">{$module_info->mobile_header_text}</div>
|
||||
<!--@endif-->
|
||||
<h2 class="h2"><a href="{getUrl('','vid',$vid,'mid',$mid)}">{$module_info->browser_title}</a> › {$lang->cmd_write}</h2>
|
||||
<form action="./" method="POST" onsubmit="return procFilter(this, insert)">
|
||||
<input type="hidden" name="mid" value="{$mid}" />
|
||||
<input type="hidden" name="document_srl" value="{$document_srl}" />
|
||||
|
|
@ -81,4 +84,7 @@
|
|||
<button type="submit" class="bn">{$lang->cmd_registration}</button>
|
||||
</div>
|
||||
</form>
|
||||
<!--@if(isset($module_info->mobile_footer_text) && $module_info->mobile_footer_text)-->
|
||||
<div class="bd_footer_text">{$module_info->mobile_footer_text}</div>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@
|
|||
<input cond="$module_info->secret=='Y'" type="checkbox" name="is_secret" value="Y" id="is_secret" class="iCheck" />
|
||||
<label cond="$module_info->secret=='Y'" for="is_secret">{$lang->secret}</label>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('comment')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="btnArea">
|
||||
<button type="submit" class="btn">{$lang->cmd_comment_registration}</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
<input cond="$module_info->secret=='Y'" type="checkbox" name="is_secret" value="Y" id="is_secret" checked="checked"|cond="$oComment->get('is_secret')=='Y'" class="iCheck" />
|
||||
<label cond="$module_info->secret=='Y'" for="is_secret">{$lang->secret}</label>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('comment')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="btnArea">
|
||||
<button type="submit" class="btn">{$lang->cmd_comment_registration}</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@
|
|||
<input type="text" name="tags" id="tags" value="{htmlspecialchars($oDocument->get('tags'))}" class="iText" style="width:300px" title="Tag" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('document')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="btnArea">
|
||||
<input type="submit" value="{$lang->cmd_registration}" class="btn" />
|
||||
<block cond="!$oDocument->isExists() || $oDocument->get('status') == 'TEMP'">
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@
|
|||
<input cond="$module_info->secret=='Y'" type="checkbox" name="is_secret" value="Y" id="is_secret" class="iCheck" />
|
||||
<label cond="$module_info->secret=='Y'" for="is_secret">{$lang->secret}</label>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('comment')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div style="float:right">
|
||||
<button type="submit" class="btn_insert"><i class="xi-message"></i> {$lang->cmd_comment_registration}</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<input cond="$module_info->secret=='Y'" type="checkbox" name="is_secret" value="Y" id="is_secret" checked="checked"|cond="$oComment->get('is_secret')=='Y'" class="iCheck" />
|
||||
<label cond="$module_info->secret=='Y'" for="is_secret">{$lang->secret}</label>
|
||||
</div>
|
||||
<div class="write_captcha" cond="$captcha">
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('comment')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div style="float:right">
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
<input type="text" name="reason_update" id="reason_update" value="" class="iText" style="width:300px" title="reason update" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha">
|
||||
<div class="write_captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('document')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div style="float:right">
|
||||
|
|
|
|||
|
|
@ -1334,7 +1334,7 @@ class documentController extends document
|
|||
);
|
||||
|
||||
$config = DocumentModel::getDocumentConfig();
|
||||
if (!$config->view_count_option || !isset($valid_options[$config->view_count_option]))
|
||||
if (!isset($config->view_count_option) || !isset($valid_options[$config->view_count_option]))
|
||||
{
|
||||
$config->view_count_option = 'once';
|
||||
}
|
||||
|
|
@ -1351,7 +1351,7 @@ class documentController extends document
|
|||
$logged_info = Context::get('logged_info');
|
||||
|
||||
// Option 'some': only count once per session.
|
||||
if ($config->view_count_option != 'all' && $_SESSION['readed_document'][$document_srl])
|
||||
if ($config->view_count_option != 'all' && isset($_SESSION['readed_document'][$document_srl]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1370,7 +1370,7 @@ class documentController extends document
|
|||
}
|
||||
|
||||
// Pass if the author's member_srl is the same as the visitor's.
|
||||
if($member_srl && $logged_info->member_srl && $logged_info->member_srl == $member_srl)
|
||||
if($member_srl && $logged_info && $logged_info->member_srl && $logged_info->member_srl == $member_srl)
|
||||
{
|
||||
$_SESSION['readed_document'][$document_srl] = true;
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ class documentItem extends BaseObject
|
|||
}
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
if (!$logged_info->member_srl)
|
||||
if (!$logged_info || !$logged_info->member_srl)
|
||||
{
|
||||
return $this->grant_cache = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -530,7 +530,7 @@ class installController extends install
|
|||
// Create a table if the schema xml exists in the "schemas" directory of the module
|
||||
$schema_dir = sprintf('%s/schemas/', $module_path);
|
||||
$schema_files = FileHandler::readDir($schema_dir, NULL, false, true);
|
||||
|
||||
$schema_sorted = [];
|
||||
foreach ($schema_files as $filename)
|
||||
{
|
||||
if (!preg_match('/\/([a-zA-Z0-9_]+)\.xml$/', $filename, $matches))
|
||||
|
|
@ -543,16 +543,24 @@ class installController extends install
|
|||
}
|
||||
|
||||
$table_name = $matches[1];
|
||||
if($oDB->isTableExists($table_name))
|
||||
if(isset($schema_sorted[$table_name]) || $oDB->isTableExists($table_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$schema_sorted[$table_name] = $filename;
|
||||
}
|
||||
|
||||
$schema_sorted = Rhymix\Framework\Parsers\DBTableParser::resolveDependency($schema_sorted);
|
||||
foreach ($schema_sorted as $table_name => $filename)
|
||||
{
|
||||
$output = $oDB->createTable($filename);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
throw new Exception(lang('msg_create_table_failed') . ': ' . $table_name . ': ' . $oDB->getError()->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Create a table and module instance and then execute install() method
|
||||
unset($oModule);
|
||||
$oModule = ModuleModel::getModuleInstallClass($module);
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ class layoutModel extends layout
|
|||
$cache_file = $this->getUserLayoutCache($layout_srl, Context::getLangType());
|
||||
}
|
||||
|
||||
if(file_exists($cache_file)&&filemtime($cache_file)>filemtime($xml_file))
|
||||
if(file_exists($cache_file) && filemtime($cache_file) > filemtime($xml_file))
|
||||
{
|
||||
include($cache_file);
|
||||
|
||||
|
|
@ -513,7 +513,7 @@ class layoutModel extends layout
|
|||
{
|
||||
foreach($vars as $key => $value)
|
||||
{
|
||||
if(!$layout_info->extra_var->{$key} && !$layout_info->{$key})
|
||||
if(!isset($layout_info->extra_var->{$key}) && !isset($layout_info->{$key}))
|
||||
{
|
||||
$layout_info->{$key} = $value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@
|
|||
<action name="procMemberInsert" type="controller" route="signup" />
|
||||
<action name="procMemberCheckValue" type="controller" />
|
||||
<action name="procMemberLogin" type="controller" route="login" />
|
||||
<action name="procMemberRegisterDevice" type="controller" route="device/register" />
|
||||
<action name="procMemberLoginWithDevice" type="controller" route="device/login" />
|
||||
<action name="procMemberFindAccount" type="controller" method="GET|POST" ruleset="findAccount" />
|
||||
<action name="procMemberFindAccountByQuestion" type="controller" method="GET|POST" />
|
||||
<action name="procMemberAuthAccount" type="controller" method="GET|POST" />
|
||||
|
|
@ -51,7 +49,6 @@
|
|||
<action name="procMemberModifyInfo" type="controller" permission="member" />
|
||||
<action name="procMemberModifyPassword" type="controller" permission="member" ruleset="modifyPassword" />
|
||||
<action name="procMemberModifyEmailAddress" type="controller" permission="member" ruleset="modifyEmailAddress" />
|
||||
<action name="procMemberDeleteDevice" type="controller" permission="member" />
|
||||
<action name="procMemberLeave" type="controller" permission="member" ruleset="leaveMember" />
|
||||
<action name="procMemberInsertProfileImage" type="controller" permission="member" ruleset="insertProfileImage" />
|
||||
<action name="procMemberDeleteProfileImage" type="controller" permission="member" />
|
||||
|
|
@ -73,6 +70,11 @@
|
|||
<action name="procMemberLogout" type="controller" permission="member" />
|
||||
<action name="procMemberSpammerManage" type="controller" permission="manager" check_var="module_srl" />
|
||||
|
||||
<action name="procMemberRegisterDevice" class="Controllers\Device" route="device/register" />
|
||||
<action name="procMemberLoginWithDevice" class="Controllers\Device" route="device/login" />
|
||||
<action name="procMemberUnregisterDevice" class="Controllers\Device" route="device/unregister" />
|
||||
<action name="procMemberDeleteDevice" class="Controllers\Device" permission="member" />
|
||||
|
||||
<action name="dispMemberAdminList" type="view" admin_index="true" menu_name="userList" menu_index="true"/>
|
||||
<action name="dispMemberAdminInfo" type="view" menu_name="userList" />
|
||||
<action name="dispMemberAdminInsert" type="view" menu_name="userList" />
|
||||
|
|
|
|||
376
modules/member/controllers/device.php
Normal file
376
modules/member/controllers/device.php
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Modules\Member\Controllers;
|
||||
|
||||
class Device extends \member
|
||||
{
|
||||
/**
|
||||
* Automatically recognize device token from header or cookie and register it.
|
||||
*
|
||||
* If the device is already registered, just update its last active date.
|
||||
*
|
||||
* @return \BaseObject
|
||||
*/
|
||||
public function autoRegisterDevice(int $member_srl): \BaseObject
|
||||
{
|
||||
$device_token = $this->_getDeviceToken();
|
||||
if ($device_token)
|
||||
{
|
||||
$output = executeQuery('member.getMemberDevice', ['device_token' => $device_token]);
|
||||
if (!$output->data || $output->data->member_srl != $member_srl)
|
||||
{
|
||||
$output = $this->procMemberRegisterDevice($member_srl, $device_token);
|
||||
if ($output instanceof \BaseObject && !$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
$this->_setDeviceKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
executeQuery('member.updateMemberDeviceLastActiveDate', ['device_token' => $device_token]);
|
||||
}
|
||||
}
|
||||
return new \BaseObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register device
|
||||
*/
|
||||
public function procMemberRegisterDevice($member_srl = null, $device_token = null)
|
||||
{
|
||||
// Set the response method to JSON, but only if this method was called directly.
|
||||
// The response method will remain unchanged, for example, when this method was called by autoRegisterDevice()
|
||||
if (\Context::get('act') === 'procMemberRegisterDevice')
|
||||
{
|
||||
\Context::setResponseMethod('JSON');
|
||||
}
|
||||
|
||||
// Check user_id, password, device_token
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$user_id = \Context::get('user_id');
|
||||
$password = \Context::get('password');
|
||||
$device_token = $device_token ?? \Context::get('device_token');
|
||||
$device_model = escape(\Context::get('device_model'));
|
||||
|
||||
// Return an error when id and password doesn't exist
|
||||
if (!$member_srl && $this->user->member_srl)
|
||||
{
|
||||
$member_srl = $this->user->member_srl;
|
||||
}
|
||||
if (!$member_srl && !$user_id && !$allow_guest_device)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_USER_ID');
|
||||
}
|
||||
if (!$member_srl && !$password && !$allow_guest_device)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_PASSWORD');
|
||||
}
|
||||
if (!$device_token)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
}
|
||||
|
||||
// Get device information
|
||||
$browserInfo = \Rhymix\Framework\UA::getBrowserInfo();
|
||||
$device_type = escape(strtolower($browserInfo->os));
|
||||
$device_version = $browserInfo->os_version;
|
||||
if (!$device_model)
|
||||
{
|
||||
$device_model = escape($browserInfo->device);
|
||||
}
|
||||
|
||||
// Detect device token type
|
||||
if (preg_match('/^[0-9a-z]{64}$/', $device_token))
|
||||
{
|
||||
$device_token_type = 'apns';
|
||||
}
|
||||
elseif (preg_match('/^[0-9a-zA-Z:_-]+$/', $device_token) && strlen($device_token) > 64)
|
||||
{
|
||||
$device_token_type = 'fcm';
|
||||
}
|
||||
else
|
||||
{
|
||||
return new \BaseObject(-1, 'INVALID_DEVICE_TOKEN');
|
||||
}
|
||||
|
||||
if ($member_srl)
|
||||
{
|
||||
$member_srl = intval($member_srl);
|
||||
}
|
||||
elseif ($user_id && $password)
|
||||
{
|
||||
$output = \memberController::getInstance()->procMemberLogin($user_id, $password);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'LOGIN_FAILED');
|
||||
}
|
||||
$logged_info = \Context::get('logged_info');
|
||||
$member_srl = intval($logged_info->member_srl);
|
||||
}
|
||||
else
|
||||
{
|
||||
$logged_info = null;
|
||||
$member_srl = 0;
|
||||
}
|
||||
|
||||
// Generate keys
|
||||
$random_key = \Rhymix\Framework\Security::getRandom();
|
||||
$device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
|
||||
// Prepare query arguments
|
||||
$args = new \stdClass;
|
||||
$args->device_srl = getNextSequence();
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_token_type = $device_token_type;
|
||||
$args->device_key = $device_key;
|
||||
$args->device_type = $device_type;
|
||||
$args->device_version = $device_version;
|
||||
$args->device_model = $device_model;
|
||||
|
||||
// Call trigger (before)
|
||||
$trigger_output = \ModuleHandler::triggerCall('member.insertMemberDevice', 'before', $args);
|
||||
if(!$trigger_output->toBool()) return $trigger_output;
|
||||
|
||||
// Start transaction
|
||||
$oDB = \DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
||||
// Remove duplicated token key
|
||||
executeQuery('member.deleteMemberDevice', ['device_token' => $device_token]);
|
||||
|
||||
// Create member_device
|
||||
$output = executeQuery('member.insertMemberDevice', $args);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
$oDB->rollback();
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Call trigger (after)
|
||||
\ModuleHandler::triggerCall('member.insertMemberDevice', 'after', $args);
|
||||
|
||||
$oDB->commit();
|
||||
|
||||
// Set parameters
|
||||
$this->add('member_srl', $member_srl);
|
||||
$this->add('user_id', $logged_info ? $logged_info->user_id : null);
|
||||
$this->add('user_name', $logged_info ? $logged_info->user_name : null);
|
||||
$this->add('nick_name', $logged_info ? $logged_info->nick_name : null);
|
||||
$this->add('device_key', $random_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically log-in to registered device
|
||||
*/
|
||||
public function procMemberLoginWithDevice()
|
||||
{
|
||||
\Context::setResponseMethod('JSON');
|
||||
|
||||
// Check member_srl, device_token, device_key
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$member_srl = abs(\Context::get('member_srl'));
|
||||
$device_token = strval(\Context::get('device_token'));
|
||||
$random_key = strval(\Context::get('device_key'));
|
||||
|
||||
// Return an error when id, password and device_key doesn't exist
|
||||
if (!$member_srl && !$allow_guest_device)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_MEMBER_SRL');
|
||||
}
|
||||
if (!$device_token)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
}
|
||||
if (!$random_key)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_KEY');
|
||||
}
|
||||
|
||||
// Check the device token and key.
|
||||
$args = new \stdClass;
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
$output = executeQuery('member.getMemberDevice', $args);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'DEVICE_RETRIEVE_FAILED');
|
||||
}
|
||||
if (!$output->data || !is_object($output->data))
|
||||
{
|
||||
return new \BaseObject(-1, 'UNREGISTERED_DEVICE');
|
||||
}
|
||||
|
||||
// Log-in
|
||||
if($member_srl)
|
||||
{
|
||||
$member_info = \MemberModel::getMemberInfoByMemberSrl($member_srl);
|
||||
$output = \memberController::getInstance()->doLogin($member_info->user_id);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'LOGIN_FAILED');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$member_info = null;
|
||||
}
|
||||
|
||||
// Update last active date
|
||||
executeQuery('member.updateMemberDeviceLastActiveDate', ['device_token' => $device_token]);
|
||||
|
||||
$this->add('member_srl', $member_srl);
|
||||
$this->add('user_id', $member_info ? $member_info->user_id : null);
|
||||
$this->add('user_name', $member_info ? $member_info->user_name : null);
|
||||
$this->add('nick_name', $member_info ? $member_info->nick_name : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a registered device.
|
||||
*
|
||||
* This action requires a device token and matching device key.
|
||||
* It is intended to be called by mobile applications.
|
||||
*/
|
||||
public function procMemberUnregisterDevice()
|
||||
{
|
||||
\Context::setResponseMethod('JSON');
|
||||
|
||||
// Check member_srl, device_token, device_key
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$member_srl = abs(\Context::get('member_srl'));
|
||||
$device_token = strval(\Context::get('device_token'));
|
||||
$random_key = strval(\Context::get('device_key'));
|
||||
|
||||
// Return an error when id, password and device_key doesn't exist
|
||||
if (!$member_srl && !$allow_guest_device)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_MEMBER_SRL');
|
||||
}
|
||||
if (!$device_token)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
}
|
||||
if (!$random_key)
|
||||
{
|
||||
return new \BaseObject(-1, 'NULL_DEVICE_KEY');
|
||||
}
|
||||
|
||||
// Check the device token and key.
|
||||
$args = new \stdClass;
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
$output = executeQuery('member.getMemberDevice', $args);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'DEVICE_RETRIEVE_FAILED');
|
||||
}
|
||||
if (!$output->data || !is_object($output->data))
|
||||
{
|
||||
return new \BaseObject(-1, 'UNREGISTERED_DEVICE');
|
||||
}
|
||||
|
||||
// Delete the device.
|
||||
$args = new \stdClass;
|
||||
$args->device_token = $device_token;
|
||||
$output = executeQuery('member.deleteMemberDevice', $args);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return new \BaseObject(-1, 'DELETE_FAILED');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a registered device.
|
||||
*
|
||||
* This action requires only the device_srl, but it must belong to the currently logged in member.
|
||||
* It is intended to be called from the web frontend.
|
||||
*/
|
||||
public function procMemberDeleteDevice()
|
||||
{
|
||||
// Check the device_srl and member_srl of the currently logged in member.
|
||||
$device_srl = intval(\Context::get('device_srl'));
|
||||
if (!$device_srl)
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\InvalidRequest;
|
||||
}
|
||||
|
||||
$member_srl = $this->user->member_srl;
|
||||
if (!$member_srl)
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\NotPermitted;
|
||||
}
|
||||
|
||||
// Check that the device_srl matches the member.
|
||||
$args = new \stdClass;
|
||||
$args->device_srl = $device_srl;
|
||||
$args->member_srl = $member_srl;
|
||||
$output = executeQuery('member.getMemberDevice', $args);
|
||||
if (!$output->data || !is_object($output->data))
|
||||
{
|
||||
throw new \Rhymix\Framework\Exceptions\TargetNotFound;
|
||||
}
|
||||
|
||||
// Delete the device.
|
||||
$args = new \stdClass;
|
||||
$args->device_token = $output->data->device_token;
|
||||
$output = executeQuery('member.deleteMemberDevice', $args);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get device token from POST parameter, HTTP header or cookie
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function _getDeviceToken()
|
||||
{
|
||||
// POST parameter named device_token
|
||||
$device_token = $_POST['device_token'] ?? null;
|
||||
if ($device_token && is_string($device_token) && $device_token !== '')
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
|
||||
// HTTP header named X-Device-Token
|
||||
$device_token = $_SERVER['HTTP_X_DEVICE_TOKEN'] ?? null;
|
||||
if ($device_token)
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
|
||||
// Cookie named device_token
|
||||
$device_token = $_COOKIE['device_token'] ?? null;
|
||||
if ($device_token)
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set device key via header or cookie
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _setDeviceKey()
|
||||
{
|
||||
$member_srl = $this->get('member_srl');
|
||||
$device_key = $this->get('device_key');
|
||||
if (!$member_srl || !$device_key)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set header if header was given, or cookie otherwise
|
||||
if (isset($_SERVER['HTTP_X_DEVICE_TOKEN']))
|
||||
{
|
||||
header('X-Device-Key: ' . urlencode($member_srl . ':' . $device_key));
|
||||
}
|
||||
else
|
||||
{
|
||||
setcookie('device_key', $member_srl . ':' . $device_key, time() + 60, \RX_BASEURL, null, !!config('session.use_ssl_cookies'), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -303,6 +303,7 @@ $lang->cmd_optional = 'Optional';
|
|||
$lang->cmd_disabled = 'Disabled';
|
||||
$lang->cmd_image_max_width = 'Max Width';
|
||||
$lang->cmd_image_max_height = 'Max Height';
|
||||
$lang->cmd_image_force_ratio = 'Fixed Aspect Ratio';
|
||||
$lang->cmd_input_extend_form = 'Add Signup Form Field';
|
||||
$lang->about_multi_type = 'Enter the value of multi-or single-item selection.(separated by line breaks)';
|
||||
$lang->msg_delete_extend_form = 'Delete the selected item.';
|
||||
|
|
|
|||
|
|
@ -317,6 +317,7 @@ $lang->cmd_optional = '선택';
|
|||
$lang->cmd_disabled = '사용 안 함';
|
||||
$lang->cmd_image_max_width = '너비 제한';
|
||||
$lang->cmd_image_max_height = '높이 제한';
|
||||
$lang->cmd_image_force_ratio = '가로세로 비율 고정';
|
||||
$lang->cmd_input_extend_form = '회원가입 추가 항목 생성';
|
||||
$lang->about_multi_type = '다중 또는 단일 항목의 선택 값을 입력하세요.(줄 바꿈으로 구분)';
|
||||
$lang->msg_delete_extend_form = '선택한 항목을 삭제합니다.';
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@
|
|||
<input id="email_address1" type="email" name="email_address" />
|
||||
</li>
|
||||
</ul>
|
||||
<div class="captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('recovery')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="bna">
|
||||
<input type="submit" class="bn dark" value="{$lang->cmd_send_mail}" />
|
||||
<input type="submit" class="bn dark" value="{$lang->cmd_send_mail}" />
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<li><label for="id"><!--@if($identifier == 'user_id')-->{$lang->user_id}<!--@else-->{$lang->email_address}<!--@end--></label><input name="user_id" type="<!--@if($identifier == 'user_id')-->text<!--@else-->email<!--@end-->" id="id" value="" /></li>
|
||||
<li><label for="pw">{$lang->password}</label><input name="password" type="password" id="pw" value="" /></li>
|
||||
</ul>
|
||||
<div class="captcha" cond="$captcha">
|
||||
<div class="captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('login')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="hp" id="keep_msg" style="display:none;">
|
||||
|
|
|
|||
|
|
@ -60,9 +60,12 @@
|
|||
</block>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="bna">
|
||||
<input type="submit" class="bn dark" value="{$lang->cmd_registration}" />
|
||||
</div>
|
||||
<div class="captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('signup')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="bna">
|
||||
<input type="submit" class="bn dark" value="{$lang->cmd_registration}" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
|
|
@ -95,4 +98,4 @@
|
|||
return false;});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -156,7 +156,13 @@ class memberAdminController extends member
|
|||
$validity_info = Rhymix\Framework\Session::getValidityInfo($args->member_srl);
|
||||
$validity_info->invalid_before = time();
|
||||
Rhymix\Framework\Session::setValidityInfo($args->member_srl, $validity_info);
|
||||
executeQuery('member.deleteAutologin', (object)array('member_srl' => $args->member_srl));
|
||||
executeQuery('member.deleteAutologin', ['member_srl' => $args->member_srl]);
|
||||
}
|
||||
|
||||
// Invalidate auth mail if denied or limited
|
||||
if ($args->denied === 'Y' || $args->limited >= date('Ymd'))
|
||||
{
|
||||
executeQuery('member.deleteAuthMail', ['member_srl' => $args->member_srl]);
|
||||
}
|
||||
|
||||
// Save Signature
|
||||
|
|
@ -371,7 +377,7 @@ class memberAdminController extends member
|
|||
'emailhost_check',
|
||||
'special_phone_number', 'special_phone_code', 'max_auth_sms_count', 'max_auth_sms_count_time', 'redirect_url',
|
||||
'phone_number_default_country', 'phone_number_hide_country', 'phone_number_allow_duplicate', 'phone_number_verify_by_sms',
|
||||
'profile_image_max_width', 'profile_image_max_height', 'profile_image_max_filesize',
|
||||
'profile_image_max_width', 'profile_image_max_height', 'profile_image_max_filesize', 'profile_image_force_ratio',
|
||||
'image_name_max_width', 'image_name_max_height', 'image_name_max_filesize',
|
||||
'image_mark_max_width', 'image_mark_max_height', 'image_mark_max_filesize',
|
||||
'signature_editor_skin', 'sel_editor_colorset', 'signature_html', 'signature_html_retroact', 'member_allow_fileupload'
|
||||
|
|
@ -469,6 +475,7 @@ class memberAdminController extends member
|
|||
$signupItem->max_width = $all_args->{$key.'_max_width'};
|
||||
$signupItem->max_height = $all_args->{$key.'_max_height'};
|
||||
$signupItem->max_filesize = $all_args->{$key.'_max_filesize'};
|
||||
$signupItem->force_ratio = $all_args->{$key.'_force_ratio'} === 'N' ? 'N' : 'Y';
|
||||
}
|
||||
|
||||
// set extends form
|
||||
|
|
|
|||
|
|
@ -33,22 +33,50 @@ class memberController extends member
|
|||
throw new Rhymix\Framework\Exception('null_user_id');
|
||||
}
|
||||
|
||||
// Variables
|
||||
if(!$user_id) $user_id = Context::get('user_id');
|
||||
$user_id = trim($user_id);
|
||||
$config = MemberModel::getMemberConfig();
|
||||
|
||||
if(!$password) $password = Context::get('password');
|
||||
$password = trim($password);
|
||||
// User ID, email address or phone number
|
||||
if (!$user_id)
|
||||
{
|
||||
$user_id = trim(Context::get('user_id'));
|
||||
}
|
||||
if (!$user_id && $config->identifiers && in_array('email_address', $config->identifiers))
|
||||
{
|
||||
$user_id = trim(Context::get('email_address'));
|
||||
}
|
||||
if (!$user_id && $config->identifiers && in_array('phone_number', $config->identifiers))
|
||||
{
|
||||
$user_id = trim(Context::get('phone_number'));
|
||||
}
|
||||
if (!$user_id)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('null_user_id');
|
||||
}
|
||||
|
||||
if(!$keep_signed) $keep_signed = Context::get('keep_signed');
|
||||
// Return an error when id and password doesn't exist
|
||||
if(!$user_id) throw new Rhymix\Framework\Exception('null_user_id');
|
||||
if(!$password) throw new Rhymix\Framework\Exception('null_password');
|
||||
// Password
|
||||
if (!$password)
|
||||
{
|
||||
$password = trim(Context::get('password'));
|
||||
}
|
||||
if (!$password)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('null_password');
|
||||
}
|
||||
|
||||
$output = $this->doLogin($user_id, $password, $keep_signed=='Y'?true:false);
|
||||
if (!$output->toBool()) return $output;
|
||||
// Autologin option
|
||||
if (!$keep_signed)
|
||||
{
|
||||
$keep_signed = Context::get('keep_signed');
|
||||
}
|
||||
|
||||
$config = ModuleModel::getModuleConfig('member');
|
||||
// Attempt login
|
||||
$output = $this->doLogin($user_id, $password, $keep_signed === 'Y' ? true : false);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Get info of member who just logged in
|
||||
$member_info = Context::get('logged_info');
|
||||
|
||||
// Check change_password_date
|
||||
|
|
@ -71,24 +99,7 @@ class memberController extends member
|
|||
executeQuery('member.deleteAuthMail', $args);
|
||||
|
||||
// If a device token is supplied, attempt to register it.
|
||||
$device_token = $this->_getDeviceToken();
|
||||
if ($device_token)
|
||||
{
|
||||
$output = executeQuery('member.getMemberDevice', ['device_token' => $device_token]);
|
||||
if (!$output->data || $output->data->member_srl != $member_info->member_srl)
|
||||
{
|
||||
$output = $this->procMemberRegisterDevice($member_info->member_srl, $device_token);
|
||||
if ($output instanceof BaseObject && !$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
$this->_setDeviceKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
executeQuery('member.updateMemberDeviceLastActiveDate', ['device_token' => $device_token]);
|
||||
}
|
||||
}
|
||||
Rhymix\Modules\Member\Controllers\Device::getInstance()->autoRegisterDevice($member_info->member_srl);
|
||||
|
||||
if(!$config->after_login_url)
|
||||
{
|
||||
|
|
@ -101,242 +112,6 @@ class memberController extends member
|
|||
return $this->setRedirectUrl($returnUrl, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register device
|
||||
*/
|
||||
function procMemberRegisterDevice($member_srl = null, $device_token = null)
|
||||
{
|
||||
if (Context::get('act') === 'procMemberRegisterDevice')
|
||||
{
|
||||
Context::setResponseMethod('JSON');
|
||||
}
|
||||
|
||||
// Check user_id, password, device_token
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$user_id = Context::get('user_id');
|
||||
$password = Context::get('password');
|
||||
$device_token = $device_token ?? Context::get('device_token');
|
||||
$device_model = escape(Context::get('device_model'));
|
||||
|
||||
// Return an error when id and password doesn't exist
|
||||
if(!$member_srl && $this->user->member_srl)
|
||||
{
|
||||
$member_srl = $this->user->member_srl;
|
||||
}
|
||||
if(!$member_srl && !$user_id && !$allow_guest_device)
|
||||
{
|
||||
return new BaseObject(-1, 'NULL_USER_ID');
|
||||
}
|
||||
if(!$member_srl && !$password && !$allow_guest_device)
|
||||
{
|
||||
return new BaseObject(-1, 'NULL_PASSWORD');
|
||||
}
|
||||
if(!$device_token)
|
||||
{
|
||||
return new BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
}
|
||||
|
||||
// Get device information
|
||||
$browserInfo = Rhymix\Framework\UA::getBrowserInfo();
|
||||
$device_type = escape(strtolower($browserInfo->os));
|
||||
$device_version = $browserInfo->os_version;
|
||||
if(!$device_model)
|
||||
{
|
||||
$device_model = escape($browserInfo->device);
|
||||
}
|
||||
|
||||
// Detect device token type
|
||||
if (preg_match('/^[0-9a-z]{64}$/', $device_token))
|
||||
{
|
||||
$device_token_type = 'apns';
|
||||
}
|
||||
elseif (preg_match('/^[0-9a-zA-Z:_-]+$/', $device_token) && strlen($device_token) > 64)
|
||||
{
|
||||
$device_token_type = 'fcm';
|
||||
}
|
||||
else
|
||||
{
|
||||
return new BaseObject(-1, 'INVALID_DEVICE_TOKEN');
|
||||
}
|
||||
|
||||
if ($member_srl)
|
||||
{
|
||||
$member_srl = intval($member_srl);
|
||||
}
|
||||
elseif ($user_id && $password)
|
||||
{
|
||||
$output = $this->procMemberLogin($user_id, $password);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new BaseObject(-1, 'LOGIN_FAILED');
|
||||
}
|
||||
$logged_info = Context::get('logged_info');
|
||||
$member_srl = intval($logged_info->member_srl);
|
||||
}
|
||||
else
|
||||
{
|
||||
$logged_info = null;
|
||||
$member_srl = 0;
|
||||
}
|
||||
|
||||
// Generate keys
|
||||
$random_key = Rhymix\Framework\Security::getRandom();
|
||||
$device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
|
||||
// Prepare query arguments
|
||||
$args = new stdClass;
|
||||
$args->device_srl = getNextSequence();
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_token_type = $device_token_type;
|
||||
$args->device_key = $device_key;
|
||||
$args->device_type = $device_type;
|
||||
$args->device_version = $device_version;
|
||||
$args->device_model = $device_model;
|
||||
|
||||
// Call trigger (before)
|
||||
$trigger_output = ModuleHandler::triggerCall('member.insertMemberDevice', 'before', $args);
|
||||
if(!$trigger_output->toBool()) return $trigger_output;
|
||||
|
||||
// Start transaction
|
||||
$oDB = DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
||||
// Remove duplicated token key
|
||||
executeQuery('member.deleteMemberDevice', ['device_token' => $device_token]);
|
||||
|
||||
// Create member_device
|
||||
$output = executeQuery('member.insertMemberDevice', $args);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
$oDB->rollback();
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Call trigger (after)
|
||||
ModuleHandler::triggerCall('member.insertMemberDevice', 'after', $args);
|
||||
|
||||
$oDB->commit();
|
||||
|
||||
// Set parameters
|
||||
$this->add('member_srl', $member_srl);
|
||||
$this->add('user_id', $logged_info ? $logged_info->user_id : null);
|
||||
$this->add('user_name', $logged_info ? $logged_info->user_name : null);
|
||||
$this->add('nick_name', $logged_info ? $logged_info->nick_name : null);
|
||||
$this->add('device_key', $random_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically log-in to registered device
|
||||
*/
|
||||
function procMemberLoginWithDevice()
|
||||
{
|
||||
Context::setResponseMethod('JSON');
|
||||
|
||||
// Check member_srl, device_token, device_key
|
||||
$allow_guest_device = config('push.allow_guest_device');
|
||||
$member_srl = intval(Context::get('member_srl'));
|
||||
$device_token = Context::get('device_token');
|
||||
$random_key = Context::get('device_key');
|
||||
|
||||
// Return an error when id, password and device_key doesn't exist
|
||||
if(!$member_srl && !$allow_guest_device) return new BaseObject(-1, 'NULL_MEMBER_SRL');
|
||||
if(!$device_token) return new BaseObject(-1, 'NULL_DEVICE_TOKEN');
|
||||
if(!$random_key) return new BaseObject(-1, 'NULL_DEVICE_KEY');
|
||||
|
||||
$args = new stdClass;
|
||||
$args->member_srl = $member_srl;
|
||||
$args->device_token = $device_token;
|
||||
$args->device_key = hash_hmac('sha256', $random_key, $member_srl . ':' . config('crypto.authentication_key'));
|
||||
$output = executeQueryArray('member.getMemberDevice', $args);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new BaseObject(-1, 'DEVICE_RETRIEVE_FAILED');
|
||||
}
|
||||
|
||||
if(!$output->data)
|
||||
{
|
||||
return new BaseObject(-1, 'UNREGISTERED_DEVICE');
|
||||
}
|
||||
|
||||
// Log-in
|
||||
if($member_srl)
|
||||
{
|
||||
$member_info = MemberModel::getMemberInfoByMemberSrl($member_srl);
|
||||
$output = $this->doLogin($member_info->user_id);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
return new BaseObject(-1, 'LOGIN_FAILED');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$member_info = null;
|
||||
}
|
||||
|
||||
// Update last active date
|
||||
executeQuery('member.updateMemberDeviceLastActiveDate', ['device_token' => $device_token]);
|
||||
|
||||
$this->add('member_srl', $member_srl);
|
||||
$this->add('user_id', $member_info ? $member_info->user_id : null);
|
||||
$this->add('user_name', $member_info ? $member_info->user_name : null);
|
||||
$this->add('nick_name', $member_info ? $member_info->nick_name : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get device token from POST parameter, HTTP header or cookie
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function _getDeviceToken()
|
||||
{
|
||||
// POST parameter named device_token
|
||||
$device_token = Context::get('device_token');
|
||||
if ($device_token && $_SERVER['REQUEST_METHOD'] === 'POST')
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
|
||||
// HTTP header named X-Device-Token
|
||||
$device_token = $_SERVER['HTTP_X_DEVICE_TOKEN'] ?? null;
|
||||
if ($device_token)
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
|
||||
// Cookie named device_token
|
||||
$device_token = $_COOKIE['device_token'] ?? null;
|
||||
if ($device_token)
|
||||
{
|
||||
return $device_token;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set device key via header or cookie
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _setDeviceKey()
|
||||
{
|
||||
$member_srl = $this->get('member_srl');
|
||||
$device_key = $this->get('device_key');
|
||||
if (!$member_srl || !$device_key)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set header if header was given, or cookie otherwise
|
||||
if (isset($_SERVER['HTTP_X_DEVICE_TOKEN']))
|
||||
{
|
||||
header('X-Device-Key: ' . urlencode($member_srl . ':' . $device_key));
|
||||
}
|
||||
else
|
||||
{
|
||||
setcookie('device_key', $member_srl . ':' . $device_key, time() + 60, \RX_BASEURL, null, !!config('session.use_ssl_cookies'), true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log-out
|
||||
*
|
||||
|
|
@ -1050,16 +825,7 @@ class memberController extends member
|
|||
}
|
||||
|
||||
// Register device
|
||||
$device_token = $this->_getDeviceToken();
|
||||
if ($device_token)
|
||||
{
|
||||
$output = $this->procMemberRegisterDevice($args->member_srl, $device_token);
|
||||
if ($output instanceof BaseObject && !$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
$this->_setDeviceKey();
|
||||
}
|
||||
Rhymix\Modules\Member\Controllers\Device::getInstance()->autoRegisterDevice($args->member_srl, false);
|
||||
|
||||
// Results
|
||||
$this->add('member_srl', $args->member_srl);
|
||||
|
|
@ -1431,7 +1197,7 @@ class memberController extends member
|
|||
* Insert a profile image
|
||||
*
|
||||
* @param int $member_srl
|
||||
* @param object $target_file
|
||||
* @param string $target_file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
|
@ -1458,14 +1224,27 @@ class memberController extends member
|
|||
}
|
||||
|
||||
$target_path = sprintf('files/member_extra_info/profile_image/%s', getNumberingPath($member_srl));
|
||||
$target_filename = sprintf('%s%d.%s', $target_path, $member_srl, $ext);
|
||||
FileHandler::makeDir($target_path);
|
||||
|
||||
$target_filename = sprintf('%s%d.%s', $target_path, $member_srl, $ext);
|
||||
// Convert if the image size is larger than a given size
|
||||
if($width > $max_width || $height > $max_height)
|
||||
if ($width > $max_width || $height > $max_height)
|
||||
{
|
||||
$resize = true;
|
||||
}
|
||||
elseif ($config->profile_image_force_ratio !== 'N' && ($width / $height !== $max_width / $max_height))
|
||||
{
|
||||
$resize = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$resize = false;
|
||||
}
|
||||
|
||||
if ($resize)
|
||||
{
|
||||
$temp_filename = sprintf('files/cache/tmp/profile_image_%d.%s', $member_srl, $ext);
|
||||
FileHandler::createImageFile($target_file, $temp_filename, $max_width, $max_height, $ext);
|
||||
FileHandler::createImageFile($target_file, $temp_filename, $max_width, $max_height, $ext, 'fill', 75);
|
||||
|
||||
// 파일 용량 제한
|
||||
FileHandler::clearStatCache($temp_filename);
|
||||
|
|
@ -3686,35 +3465,6 @@ class memberController extends member
|
|||
$_SESSION['verify_by_sms']['status'] = true;
|
||||
return new BaseObject(0, 'verify_by_sms_code_confirmed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a registered device.
|
||||
*/
|
||||
public function procMemberDeleteDevice()
|
||||
{
|
||||
$device_srl = intval(Context::get('device_srl'));
|
||||
$logged_info = Context::get('logged_info');
|
||||
|
||||
$args = new stdClass;
|
||||
$args->device_srl = $device_srl;
|
||||
$output = executeQuery('member.getMemberDevice', $args);
|
||||
if (!$output->data || !is_object($output->data))
|
||||
{
|
||||
throw new Rhymix\Framework\Exceptions\TargetNotFound;
|
||||
}
|
||||
if (!$output->data->member_srl || $output->data->member_srl != $logged_info->member_srl)
|
||||
{
|
||||
throw new Rhymix\Framework\Exceptions\TargetNotFound;
|
||||
}
|
||||
|
||||
$args = new stdClass;
|
||||
$args->device_token = $output->data->device_token;
|
||||
$output = executeQuery('member.deleteMemberDevice', $args);
|
||||
if (!$output->toBool())
|
||||
{
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* trigger for document.getDocumentMenu. Append to popup menu a button for procMemberSpammerManage()
|
||||
|
|
|
|||
|
|
@ -481,8 +481,17 @@ class memberModel extends member
|
|||
$oSecurity = new Security($info);
|
||||
$oSecurity->encodeHTML('user_id', 'user_name', 'nick_name', 'find_account_answer', 'description', 'address.', 'group_list..');
|
||||
|
||||
$info->homepage = strip_tags($info->homepage);
|
||||
$info->blog = strip_tags($info->blog);
|
||||
// Validate URLs
|
||||
$info->homepage = escape(strip_tags($info->homepage));
|
||||
if ($info->homepage !== '' && !preg_match('!^https?://[^\\\\/]+!', $info->homepage))
|
||||
{
|
||||
$info->homepage = '';
|
||||
}
|
||||
$info->blog = escape(strip_tags($info->blog));
|
||||
if ($info->blog !== '' && !preg_match('!^https?://[^\\\\/]+!', $info->blog))
|
||||
{
|
||||
$info->blog = '';
|
||||
}
|
||||
|
||||
if($extra_vars)
|
||||
{
|
||||
|
|
@ -499,18 +508,6 @@ class memberModel extends member
|
|||
}
|
||||
}
|
||||
|
||||
// Check format.
|
||||
$oValidator = new Validator();
|
||||
if(!$oValidator->applyRule('url', $info->homepage))
|
||||
{
|
||||
$info->homepage = '';
|
||||
}
|
||||
|
||||
if(!$oValidator->applyRule('url', $info->blog))
|
||||
{
|
||||
$info->blog = '';
|
||||
}
|
||||
|
||||
$GLOBALS['__member_info__'][$info->member_srl] = $info;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -607,9 +607,18 @@ class memberView extends member
|
|||
*/
|
||||
function dispMemberLoginForm()
|
||||
{
|
||||
// Get referer URL
|
||||
$referer_url = Context::get('referer_url') ?: ($_SERVER['HTTP_REFERER'] ?? '');
|
||||
if (!$referer_url || !Rhymix\Framework\URL::isInternalURL($referer_url) || contains('procMember', $referer_url))
|
||||
{
|
||||
$referer_url = getNotEncodedUrl('act', '');
|
||||
}
|
||||
Context::set('referer_url', $referer_url);
|
||||
|
||||
// Return to previous screen if already logged in.
|
||||
if(Context::get('is_logged'))
|
||||
{
|
||||
$this->setRedirectUrl(getNotEncodedUrl('act',''));
|
||||
$this->setRedirectUrl($referer_url);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -617,6 +626,7 @@ class memberView extends member
|
|||
$config = $this->member_config;
|
||||
Context::set('identifier', $config->identifier);
|
||||
|
||||
// Get validator status
|
||||
$XE_VALIDATOR_MESSAGE = Context::get('XE_VALIDATOR_MESSAGE');
|
||||
$XE_VALIDATOR_ERROR = Context::get('XE_VALIDATOR_ERROR');
|
||||
if($XE_VALIDATOR_ERROR == -11)
|
||||
|
|
@ -624,15 +634,6 @@ class memberView extends member
|
|||
Context::set('XE_VALIDATOR_MESSAGE', $XE_VALIDATOR_MESSAGE . $config->limit_day_description);
|
||||
}
|
||||
|
||||
if(strpos(Context::get('referer_url'), 'procMember') !== false || ($XE_VALIDATOR_ERROR < -10 && $XE_VALIDATOR_ERROR > -21))
|
||||
{
|
||||
Context::set('referer_url', getUrl(''));
|
||||
}
|
||||
else
|
||||
{
|
||||
Context::set('referer_url', escape($_SERVER['HTTP_REFERER']));
|
||||
}
|
||||
|
||||
// Set a template file
|
||||
$this->setTemplateFile('login_form');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@
|
|||
<input type="hidden" name="xe_validator_id" value="modules/member/skin/default/find_member_account/1" />
|
||||
<div>
|
||||
<input type="email" name="email_address" required placeholder="{$lang->email_address}" title="{$lang->email_address}" /><br />
|
||||
<block cond="$captcha">{$captcha}<br /></block>
|
||||
<block cond="isset($captcha) && $captcha && $captcha->isTargetAction('recovery')">
|
||||
{$captcha}<br />
|
||||
</block>
|
||||
<input type="submit" class="btn btn-inverse" value="{$lang->cmd_find_member_account}" />
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -33,7 +35,9 @@
|
|||
<input type="hidden" name="xe_validator_id" value="modules/member/skin/default/find_member_account/3" />
|
||||
<div>
|
||||
<input type="email" id="email_address" name="email_address" value="" required placeholder="{$lang->email_address}" title="{$lang->email_address}" /><br />
|
||||
<block cond="$captcha">{$captcha}<br /></block>
|
||||
<block cond="isset($captcha) && $captcha && $captcha->isTargetAction('recovery')">
|
||||
{$captcha}<br />
|
||||
</block>
|
||||
<input type="submit" value="{$lang->cmd_resend_auth_mail}" class="btn btn-inverse" />
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<input type="email" cond="$identifier != 'user_id'" name="user_id" id="uid" required placeholder="{$lang->email_address}" title="{$lang->email_address}" />
|
||||
<input type="password" name="password" id="upw" required placeholder="{$lang->password}" title="{$lang->password}" />
|
||||
</div>
|
||||
<div class="control-group captcha" cond="$captcha">
|
||||
<div class="control-group captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('login')">
|
||||
{$captcha}
|
||||
</div>
|
||||
<div class="control-group">
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@
|
|||
<label for="allow_{$key}" loop="$lang->allow_message_type=>$key,$val"><input type="radio" name="allow_message" value="{$key}" checked="checked"|cond="$member_info->allow_message == $key || (!$member_info && $key == 'Y')" id="allow_{$key}" /> {$val}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" cond="$captcha">
|
||||
<div class="control-group captcha" cond="isset($captcha) && $captcha && $captcha->isTargetAction('signup')">
|
||||
<div class="control-label">{$lang->captcha}</div>
|
||||
<div class="controls">{$captcha}</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -152,6 +152,13 @@
|
|||
<p class="x_help-block">
|
||||
<label class="x_inline" for="{$item->name}_max_filesize">{$lang->allowed_filesize}</label> <input type="number" min="1" name="{$item->name}_max_filesize" id="{$item->name}_max_filesize" value="{$item->max_filesize}" /> KB
|
||||
</p>
|
||||
<!--@if($item->name === 'profile_image')-->
|
||||
<p class="x_help-block">
|
||||
<label class="x_inline">{$lang->cmd_image_force_ratio}</label>
|
||||
<label class="x_inline"><input type="radio" name="profile_image_force_ratio" value="Y" checked="checked"|cond="$config->profile_image_force_ratio !== 'N'" /> {$lang->cmd_yes}</label>
|
||||
<label class="x_inline"><input type="radio" name="profile_image_force_ratio" value="N" checked="checked"|cond="$config->profile_image_force_ratio === 'N'" /> {$lang->cmd_no}</label>
|
||||
</p>
|
||||
<!--@endif-->
|
||||
</div>
|
||||
|
||||
<div cond="$item->name == 'phone_number'" class="_subItem" style="display:none"|cond="!$item->isUse">
|
||||
|
|
|
|||
|
|
@ -1939,9 +1939,9 @@ class moduleModel extends module
|
|||
$module_info->module = $module_info->module_srl = 0;
|
||||
}
|
||||
|
||||
if (isset($GLOBALS['__MODULE_GRANT__'][$module_info->module][intval($module_info->module_srl ?? 0)][intval($member_info->member_srl)]))
|
||||
if (isset($GLOBALS['__MODULE_GRANT__'][$module_info->module][intval($module_info->module_srl ?? 0)][intval($member_info->member_srl ?? 0)]))
|
||||
{
|
||||
$__cache = &$GLOBALS['__MODULE_GRANT__'][$module_info->module][intval($module_info->module_srl ?? 0)][intval($member_info->member_srl)];
|
||||
$__cache = &$GLOBALS['__MODULE_GRANT__'][$module_info->module][intval($module_info->module_srl ?? 0)][intval($member_info->member_srl ?? 0)];
|
||||
if (is_object($__cache) && !$xml_info)
|
||||
{
|
||||
return $__cache;
|
||||
|
|
@ -1975,7 +1975,7 @@ class moduleModel extends module
|
|||
foreach($privilege_list as $val)
|
||||
{
|
||||
// If an administrator, grant all
|
||||
if($member_info->is_admin == 'Y')
|
||||
if($member_info && $member_info->is_admin == 'Y')
|
||||
{
|
||||
$grant->{$val} = true;
|
||||
}
|
||||
|
|
@ -2018,7 +2018,7 @@ class moduleModel extends module
|
|||
}
|
||||
|
||||
// Log-in member only
|
||||
if($member_info->member_srl)
|
||||
if($member_info && $member_info->member_srl)
|
||||
{
|
||||
if($val->group_srl == -1 || $val->group_srl == -2)
|
||||
{
|
||||
|
|
@ -2063,7 +2063,7 @@ class moduleModel extends module
|
|||
}
|
||||
|
||||
// Log-in member only
|
||||
if($member_info->member_srl)
|
||||
if($member_info && $member_info->member_srl)
|
||||
{
|
||||
if($item->default == 'member' || $item->default == 'site')
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_url = $url;
|
||||
$args->target_browser = '';
|
||||
$args->target_summary = '';
|
||||
$args->target_content = null;
|
||||
|
||||
if (is_object($message))
|
||||
{
|
||||
|
|
@ -388,6 +389,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_ADMIN_DOCUMENT;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $obj->document_srl);
|
||||
$args->target_summary = cut_str(strip_tags($obj->title), 50);
|
||||
$args->target_content = mb_substr(trim(utf8_normalize_spaces(strip_tags($obj->content))), 0, 200, 'UTF-8') ?: (strpos($obj->content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->target_browser = $module_info->browser_title;
|
||||
$args->module_srl = $obj->module_srl;
|
||||
|
|
@ -446,6 +448,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_COMMENT_ALL;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $document_srl, 'comment_srl', $comment_srl) . '#comment_' . $comment_srl;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50) ?: (strpos($content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->target_content = null;
|
||||
$args->target_nick_name = $obj->nick_name;
|
||||
$args->target_email_address = $obj->email_address;
|
||||
$args->regdate = date('YmdHis');
|
||||
|
|
@ -482,6 +485,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_ADMIN_COMMENT;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $document_srl, 'comment_srl', $comment_srl) . '#comment_' . $comment_srl;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50) ?: (strpos($content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->target_content = null;
|
||||
$args->target_nick_name = $obj->nick_name;
|
||||
$args->target_email_address = $obj->email_address;
|
||||
$args->regdate = date('YmdHis');
|
||||
|
|
@ -560,6 +564,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_COMMENT;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $document_srl, 'comment_srl', $comment_srl) . '#comment_' . $comment_srl;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50) ?: (strpos($content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->target_content = null;
|
||||
$args->target_nick_name = $obj->nick_name;
|
||||
$args->target_email_address = $obj->email_address;
|
||||
$args->regdate = $regdate;
|
||||
|
|
@ -609,6 +614,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->target_type = $this->_TYPE_COMMENT;
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $document_srl, 'comment_srl', $comment_srl) . '#comment_' . $comment_srl;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50) ?: (strpos($content, '<img') !== false ? lang('ncenterlite_content_image') : lang('ncenterlite_content_empty'));
|
||||
$args->target_content = null;
|
||||
$args->target_nick_name = $obj->nick_name;
|
||||
$args->target_email_address = $obj->email_address;
|
||||
$args->regdate = $regdate;
|
||||
|
|
@ -658,6 +664,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->type = $this->_TYPE_MESSAGE;
|
||||
$args->target_type = $this->_TYPE_MESSAGE;
|
||||
$args->target_summary = $obj->title;
|
||||
$args->target_content = mb_substr(trim(utf8_normalize_spaces(strip_tags($obj->content))), 0, 200, 'UTF-8');
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->notify = $this->_getNotifyId($args);
|
||||
$args->target_url = getNotEncodedUrl('', 'act', 'dispCommunicationMessages', 'message_srl', $obj->related_srl);
|
||||
|
|
@ -698,6 +705,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->type = $this->_TYPE_DOCUMENT;
|
||||
$args->target_type = $this->_TYPE_SCRAPPED;
|
||||
$args->target_summary = $obj->title;
|
||||
$args->target_content = null;
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->notify = $this->_getNotifyId($args);
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $obj->document_srl);
|
||||
|
|
@ -741,6 +749,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->type = $this->_TYPE_DOCUMENT;
|
||||
$args->target_type = $this->_TYPE_VOTED;
|
||||
$args->target_summary = $oDocument->get('title');
|
||||
$args->target_content = null;
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->notify = $this->_getNotifyId($args);
|
||||
$args->target_url = getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $obj->document_srl);
|
||||
|
|
@ -821,6 +830,7 @@ class ncenterliteController extends ncenterlite
|
|||
$args->type = $this->_TYPE_COMMENT;
|
||||
$args->target_type = $this->_TYPE_VOTED;
|
||||
$args->target_summary = cut_str(trim(utf8_normalize_spaces(strip_tags($content))), 50);
|
||||
$args->target_content = null;
|
||||
$args->regdate = date('YmdHis');
|
||||
$args->module_srl = $obj->module_srl;
|
||||
$args->notify = $this->_getNotifyId($args);
|
||||
|
|
@ -958,7 +968,7 @@ class ncenterliteController extends ncenterlite
|
|||
{
|
||||
$comment_srl = Context::get('comment_srl');
|
||||
$logged_info = Context::get('logged_info');
|
||||
if($comment_srl && $logged_info)
|
||||
if($comment_srl && $logged_info && $logged_info->member_srl)
|
||||
{
|
||||
$args->target_srl = $comment_srl;
|
||||
$args->member_srl = $logged_info->member_srl;
|
||||
|
|
@ -975,7 +985,7 @@ class ncenterliteController extends ncenterlite
|
|||
$document_srl = Context::get('document_srl');
|
||||
$logged_info = Context::get('logged_info');
|
||||
|
||||
if($document_srl && $config->document_read == 'Y' && $logged_info->member_srl)
|
||||
if($document_srl && $config->document_read == 'Y' && $logged_info && $logged_info->member_srl)
|
||||
{
|
||||
$args->srl = $document_srl;
|
||||
$args->member_srl = $logged_info->member_srl;
|
||||
|
|
@ -1562,10 +1572,28 @@ class ncenterliteController extends ncenterlite
|
|||
$target_url = Rhymix\Framework\URL::getCurrentDomainUrl($target_url);
|
||||
}
|
||||
|
||||
if (!isset($args->extra_data) || !$args->extra_data)
|
||||
{
|
||||
$args->extra_data = [];
|
||||
$args->extra_data['sender'] = strval($args->target_nick_name);
|
||||
$args->extra_data['profile_image'] = '';
|
||||
if ($args->target_member_srl > 0)
|
||||
{
|
||||
$profile_image = MemberModel::getProfileImage($args->target_member_srl);
|
||||
if ($profile_image && $profile_image->src)
|
||||
{
|
||||
$args->extra_data['profile_image'] = Rhymix\Framework\URL::getCurrentDomainUrl($profile_image->src);
|
||||
}
|
||||
}
|
||||
$args->extra_data['type'] = strval($args->target_type);
|
||||
$args->extra_data['subject'] = strval($args->target_summary);
|
||||
$args->extra_data['content'] = isset($args->target_content) ? mb_substr($args->target_content, 0, 200, 'UTF-8') : '';
|
||||
}
|
||||
|
||||
$oPush = new \Rhymix\Framework\Push();
|
||||
$oPush->setSubject($content);
|
||||
$oPush->setContent(strval($args->extra_content));
|
||||
$oPush->setData($args->extra_data ?: []);
|
||||
$oPush->setData($args->extra_data);
|
||||
$oPush->setURL(strval($target_url));
|
||||
$oPush->addTo(intval($args->member_srl));
|
||||
$oPush->send();
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ $lang->point_recal_finished = 'Point recalculation is finished.';
|
|||
$lang->point_update_desc = 'Insert + in front of the number to increase the point or - to decrease, and update the point. If you don\'t insert + or -, the point will be set as the value you entered.';
|
||||
$lang->give_point = 'Give or Take Points';
|
||||
$lang->point_given_prefix = '';
|
||||
$lang->point_given_suffix = 'points';
|
||||
$lang->point_given_suffix = '$point';
|
||||
$lang->point_time_limit_prefix = 'until';
|
||||
$lang->point_time_limit_suffix = 'days after submission';
|
||||
$lang->search_target_list['nick_name'] = 'Nick Name';
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ $lang->point_recal_finished = '포인트 재계산이 완료되었습니다.';
|
|||
$lang->point_update_desc = '포인트를 증가시키려면 +를 감소시키려면 -를 숫자앞에 표기한 후 업데이트해 주세요. + 또는 - 표시가 없으면 입력한 값으로 설정됩니다.';
|
||||
$lang->give_point = '포인트 부여/차감';
|
||||
$lang->point_given_prefix = '';
|
||||
$lang->point_given_suffix = '포인트';
|
||||
$lang->point_given_suffix = '$point';
|
||||
$lang->point_time_limit_prefix = '작성 후';
|
||||
$lang->point_time_limit_suffix = '일까지';
|
||||
$lang->search_target_list['nick_name'] = '닉네임';
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ class pointController extends point
|
|||
public function triggerBeforeDownloadFile($obj)
|
||||
{
|
||||
$logged_info = Context::get('logged_info');
|
||||
$logged_member_srl = $logged_info->member_srl;
|
||||
$logged_member_srl = $logged_info ? $logged_info->member_srl : 0;
|
||||
$author_member_srl = abs($obj->member_srl);
|
||||
$module_srl = $obj->module_srl;
|
||||
if ($logged_member_srl && $logged_member_srl == $author_member_srl)
|
||||
|
|
@ -443,7 +443,7 @@ class pointController extends point
|
|||
public function triggerDownloadFile($obj)
|
||||
{
|
||||
$logged_info = Context::get('logged_info');
|
||||
$logged_member_srl = $logged_info->member_srl;
|
||||
$logged_member_srl = $logged_info ? $logged_info->member_srl : 0;
|
||||
$author_member_srl = abs($obj->member_srl);
|
||||
$module_srl = $obj->module_srl;
|
||||
if ($logged_member_srl && $logged_member_srl == $author_member_srl)
|
||||
|
|
@ -481,7 +481,7 @@ class pointController extends point
|
|||
public function triggerUpdateReadedCount($obj)
|
||||
{
|
||||
$logged_info = Context::get('logged_info');
|
||||
$logged_member_srl = $logged_info->member_srl;
|
||||
$logged_member_srl = $logged_info ? $logged_info->member_srl : 0;
|
||||
$author_member_srl = abs($obj->get('member_srl'));
|
||||
$module_srl = $obj->get('module_srl');
|
||||
if ($logged_member_srl && $logged_member_srl == $author_member_srl)
|
||||
|
|
@ -587,7 +587,7 @@ class pointController extends point
|
|||
public function triggerUpdateVotedCount($obj)
|
||||
{
|
||||
$logged_info = Context::get('logged_info');
|
||||
$logged_member_srl = $logged_info->member_srl;
|
||||
$logged_member_srl = $logged_info ? $logged_info->member_srl : 0;
|
||||
$target_member_srl = abs($obj->member_srl);
|
||||
if ($logged_member_srl && $logged_member_srl == $target_member_srl)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -89,18 +89,18 @@
|
|||
<tr>
|
||||
<th class="nowr">{$lang->cmd_signup}</td>
|
||||
<td class="nowr">
|
||||
{$lang->point_given_prefix}
|
||||
{strtr($lang->point_given_prefix, ['$'.'point' => $config->point_name])}
|
||||
<input type="number" value="{$config->signup_point ?: '0'}" name="signup_point" id="signup_point" />
|
||||
{$lang->point_given_suffix}
|
||||
{strtr($lang->point_given_suffix, ['$'.'point' => $config->point_name])}
|
||||
</td>
|
||||
<td class="nowr"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="nowr">{$lang->cmd_login}</td>
|
||||
<td class="nowr">
|
||||
{$lang->point_given_prefix}
|
||||
{strtr($lang->point_given_prefix, ['$'.'point' => $config->point_name])}
|
||||
<input type="number" value="{$config->login_point ?: '0'}" name="login_point" id="login_point" />
|
||||
{$lang->point_given_suffix}
|
||||
{strtr($lang->point_given_suffix, ['$'.'point' => $config->point_name])}
|
||||
</td>
|
||||
<td class="nowr"></td>
|
||||
</tr>
|
||||
|
|
@ -108,9 +108,9 @@
|
|||
<tr>
|
||||
<th class="nowr">{lang('point_' . $action_type)}</td>
|
||||
<td class="nowr">
|
||||
{$lang->point_given_prefix}
|
||||
{strtr($lang->point_given_prefix, ['$'.'point' => $config->point_name])}
|
||||
<input type="number" value="{$config_array[$action_type] ?: '0'}" name="{$action_type}" id="{$action_type}" />
|
||||
{$lang->point_given_suffix}
|
||||
{strtr($lang->point_given_suffix, ['$'.'point' => $config->point_name])}
|
||||
<block cond="$action_config['except_notice']">
|
||||
<label class="x_inline" for="{$action_type}_except_notice" style="margin-left:10px">
|
||||
<input type="checkbox" value="Y" name="{$action_type}_except_notice" id="{$action_type}_except_notice" checked="checked"|cond="$config_array[$action_type . '_except_notice']" />
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ class pollController extends poll
|
|||
$stop_date = date('YmdHis', $_SERVER['REQUEST_TIME']+60*60*24*30);
|
||||
}
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
$vars = Context::getRequestVars();
|
||||
|
||||
$args = new stdClass;
|
||||
$tmp_args = array();
|
||||
|
||||
|
|
@ -70,9 +68,9 @@ class pollController extends poll
|
|||
$tmp_args[$poll_index]->item = array();
|
||||
}
|
||||
|
||||
if($logged_info->is_admin != 'Y')
|
||||
if(!$this->user->isAdmin())
|
||||
{
|
||||
$val = htmlspecialchars($val, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
|
||||
$val = escape($val, false);
|
||||
}
|
||||
|
||||
switch($tmp_arr[0])
|
||||
|
|
@ -108,15 +106,14 @@ class pollController extends poll
|
|||
|
||||
// Configure the variables
|
||||
$poll_srl = getNextSequence();
|
||||
$member_srl = $logged_info->member_srl?$logged_info->member_srl:0;
|
||||
|
||||
$oDB = &DB::getInstance();
|
||||
$oDB = DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
||||
// Register the poll
|
||||
$poll_args = new stdClass;
|
||||
$poll_args->poll_srl = $poll_srl;
|
||||
$poll_args->member_srl = $member_srl;
|
||||
$poll_args->member_srl = $this->user->member_srl;
|
||||
$poll_args->list_order = $poll_srl*-1;
|
||||
$poll_args->stop_date = $args->stop_date;
|
||||
$poll_args->poll_count = 0;
|
||||
|
|
@ -180,8 +177,10 @@ class pollController extends poll
|
|||
|
||||
if($poll_item_title=='') throw new Rhymix\Framework\Exception('msg_item_title_cannot_empty');
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
if(!$logged_info) throw new Rhymix\Framework\Exception('msg_cannot_add_item');
|
||||
if(!$this->user->member_srl)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('msg_cannot_add_item');
|
||||
}
|
||||
|
||||
if(!$poll_srl || !$poll_index_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||
|
||||
|
|
@ -196,12 +195,12 @@ class pollController extends poll
|
|||
|
||||
if(!$this->isAbletoAddItem($type)) throw new Rhymix\Framework\Exception('msg_cannot_add_item');
|
||||
|
||||
if($logged_info->is_admin != 'Y')
|
||||
if(!$this->user->isAdmin())
|
||||
{
|
||||
$poll_item_title = htmlspecialchars($poll_item_title, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
|
||||
$poll_item_title = escape($poll_item_title, false);
|
||||
}
|
||||
|
||||
$oDB = &DB::getInstance();
|
||||
$oDB = DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
||||
$item_args = new stdClass;
|
||||
|
|
@ -210,7 +209,7 @@ class pollController extends poll
|
|||
$item_args->title = $poll_item_title;
|
||||
$item_args->poll_count = 0;
|
||||
$item_args->upload_target_srl = 0;
|
||||
$item_args->add_user_srl = $logged_info->member_srl;
|
||||
$item_args->add_user_srl = $this->user->member_srl;
|
||||
$output = executeQuery('poll.insertPollItem', $item_args);
|
||||
if(!$output->toBool())
|
||||
{
|
||||
|
|
@ -226,8 +225,10 @@ class pollController extends poll
|
|||
$poll_index_srl = (int) Context::get('index_srl');
|
||||
$poll_item_srl = Context::get('item_srl');
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
if(!$logged_info) throw new Rhymix\Framework\Exception('msg_cannot_delete_item');
|
||||
if(!$this->user->member_srl)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('msg_cannot_delete_item');
|
||||
}
|
||||
|
||||
if(!$poll_srl || !$poll_index_srl || !$poll_item_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||
|
||||
|
|
@ -248,8 +249,14 @@ class pollController extends poll
|
|||
if(!$output->data) throw new Rhymix\Framework\Exception('poll_no_poll_or_deleted_poll');
|
||||
$poll_member_srl = $output->data->member_srl;
|
||||
|
||||
if($add_user_srl!=$logged_info->member_srl && $poll_member_srl!=$logged_info->member_srl) throw new Rhymix\Framework\Exception('msg_cannot_delete_item');
|
||||
if($poll_count>0) throw new Rhymix\Framework\Exception('msg_cannot_delete_item_poll_exist');
|
||||
if($add_user_srl != $this->user->member_srl && $poll_member_srl != $this->user->member_srl)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('msg_cannot_delete_item');
|
||||
}
|
||||
if($poll_count > 0)
|
||||
{
|
||||
throw new Rhymix\Framework\Exception('msg_cannot_delete_item_poll_exist');
|
||||
}
|
||||
|
||||
$oDB = &DB::getInstance();
|
||||
$oDB->begin();
|
||||
|
|
@ -330,11 +337,7 @@ class pollController extends poll
|
|||
$log_args = new stdClass;
|
||||
$log_args->poll_srl = $poll_srl;
|
||||
$log_args->poll_item = $args->poll_item_srl;
|
||||
|
||||
$logged_info = Context::get('logged_info');
|
||||
$member_srl = $logged_info->member_srl?$logged_info->member_srl:0;
|
||||
|
||||
$log_args->member_srl = $member_srl;
|
||||
$log_args->member_srl = $this->user->member_srl;
|
||||
$log_args->ipaddress = \RX_CLIENT_IP;
|
||||
$output = executeQuery('poll.insertPollLog', $log_args);
|
||||
|
||||
|
|
|
|||
|
|
@ -239,19 +239,19 @@ class spamfilterController extends spamfilter
|
|||
return;
|
||||
}
|
||||
|
||||
$enable = false;
|
||||
$target_actions = [];
|
||||
foreach (['signup', 'login', 'recovery', 'document', 'comment'] as $action)
|
||||
{
|
||||
if ($config->captcha->target_actions[$action])
|
||||
{
|
||||
if (preg_match(self::$_captcha_actions[$action], $obj->act) || ($action === 'comment' && !$obj->act && Context::get('document_srl')))
|
||||
if (preg_match(self::$_captcha_actions[$action], $obj->act) || ($action === 'comment' && (!$obj->act || $obj->act === 'dispBoardContent') && Context::get('document_srl')))
|
||||
{
|
||||
$enable = true;
|
||||
$target_actions[$action] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($enable)
|
||||
if (count($target_actions))
|
||||
{
|
||||
include_once __DIR__ . '/spamfilter.lib.php';
|
||||
spamfilter_reCAPTCHA::init($config->captcha);
|
||||
|
|
@ -262,7 +262,10 @@ class spamfilterController extends spamfilter
|
|||
}
|
||||
else
|
||||
{
|
||||
Context::set('captcha', new spamfilter_reCAPTCHA());
|
||||
$captcha = new spamfilter_reCAPTCHA();
|
||||
$captcha->setTargetActions($target_actions);
|
||||
$captcha->addScripts();
|
||||
Context::set('captcha', $captcha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ class spamfilter_reCAPTCHA
|
|||
protected static $scripts_added = false;
|
||||
protected static $instances_inserted = 0;
|
||||
protected static $sequence = 1;
|
||||
protected $_target_actions = [];
|
||||
|
||||
public static function init($config)
|
||||
{
|
||||
|
|
@ -47,19 +48,29 @@ class spamfilter_reCAPTCHA
|
|||
$_SESSION['recaptcha_authenticated'] = true;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
public function addScripts()
|
||||
{
|
||||
if (!self::$scripts_added)
|
||||
{
|
||||
self::$scripts_added = true;
|
||||
Context::loadFile(array('./modules/spamfilter/tpl/js/recaptcha.js', 'body'));
|
||||
Context::addHtmlFooter('<script src="https://www.google.com/recaptcha/api.js?render=explicit&onload=reCaptchaCallback" async defer></script>');
|
||||
$html = '<div id="recaptcha-config" data-sitekey="%s" data-theme="%s" data-size="%s"></div>';
|
||||
$html = sprintf($html, escape(self::$config->site_key), self::$config->theme ?: 'light', self::$config->size ?: 'normal');
|
||||
$html = '<div id="recaptcha-config" data-sitekey="%s" data-theme="%s" data-size="%s" data-targets="%s"></div>';
|
||||
$html = sprintf($html, escape(self::$config->site_key), self::$config->theme ?: 'light', self::$config->size ?: 'normal', implode(',', array_keys($this->_target_actions)));
|
||||
Context::addHtmlFooter($html);
|
||||
}
|
||||
}
|
||||
|
||||
public function setTargetActions(array $target_actions)
|
||||
{
|
||||
$this->_target_actions = $target_actions;
|
||||
}
|
||||
|
||||
public function isTargetAction(string $action): bool
|
||||
{
|
||||
return isset($this->_target_actions[$action]);
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('<div id="recaptcha-instance-%d" class="g-recaptcha"></div>', self::$instances_inserted++);
|
||||
|
|
|
|||
|
|
@ -3,15 +3,31 @@ function reCaptchaCallback() {
|
|||
var recaptcha_config = $("#recaptcha-config");
|
||||
var recaptcha_instances = $(".g-recaptcha");
|
||||
var recaptcha_instance_id = 1;
|
||||
var recaptcha_targets = String(recaptcha_config.data("targets")).split(",");
|
||||
|
||||
if (recaptcha_instances.size() === 0) {
|
||||
if (recaptcha_instances.length === 0) {
|
||||
var autoinsert_candidates = $("form").filter(function() {
|
||||
var actinput = $("input[name='act']", this);
|
||||
if (actinput.size() && actinput.val() && actinput.val().match(/^proc.+(Insert(Document|Comment|)|Login|FindAccount|ResendAuthMail)/i)) {
|
||||
return true;
|
||||
if (actinput.length && actinput.val()) {
|
||||
var act = String(actinput.val());
|
||||
if (act.match(/^procMemberInsert$/i) && recaptcha_targets.indexOf("signup") > -1) {
|
||||
return true;
|
||||
}
|
||||
if (act.match(/^procMemberLogin$/i) && recaptcha_targets.indexOf("login") > -1) {
|
||||
return true;
|
||||
}
|
||||
if (act.match(/^procMember(FindAccount|ResendAuthMail)$/i) && recaptcha_targets.indexOf("recovery") > -1) {
|
||||
return true;
|
||||
}
|
||||
if (act.match(/^proc[A-Z][a-zA-Z0-9_]+InsertDocument$/i) && recaptcha_targets.indexOf("document") > -1) {
|
||||
return true;
|
||||
}
|
||||
if (act.match(/^proc[A-Z][a-zA-Z0-9_]+InsertComment$/i) && recaptcha_targets.indexOf("comment") > -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var procfilter = $(this).attr("onsubmit");
|
||||
if (procfilter && procfilter.match(/procFilter\b.+\binsert/i)) {
|
||||
if (procfilter && procfilter.match(/procFilter\b.+\binsert/i) && (recaptcha_targets.indexOf("document") > -1 || recaptcha_targets.indexOf("comment") > -1)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
11
tests/_data/dbquery/emptyStringTest1.xml
Normal file
11
tests/_data/dbquery/emptyStringTest1.xml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<query id="emptyStringTest1" action="update">
|
||||
<tables>
|
||||
<table name="documents" />
|
||||
</tables>
|
||||
<columns>
|
||||
<column name="nick_name" var="nick_name" />
|
||||
</columns>
|
||||
<conditions>
|
||||
<condition operation="equal" column="document_srl" var="document_srl" />
|
||||
</conditions>
|
||||
</query>
|
||||
12
tests/_data/dbquery/emptyStringTest2.xml
Normal file
12
tests/_data/dbquery/emptyStringTest2.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<query id="emptyStringTest2" action="select">
|
||||
<tables>
|
||||
<table name="documents" />
|
||||
</tables>
|
||||
<columns>
|
||||
<column name="*" />
|
||||
</columns>
|
||||
<conditions>
|
||||
<condition operation="equal" column="category_srl" var="category_srl" notnull="notnull" />
|
||||
<condition operation="equal" column="nick_name" var="nick_name" />
|
||||
</conditions>
|
||||
</query>
|
||||
12
tests/_data/dbquery/nullValueTest1.xml
Normal file
12
tests/_data/dbquery/nullValueTest1.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<query id="nullValueTest1" action="update">
|
||||
<tables>
|
||||
<table name="documents" />
|
||||
</tables>
|
||||
<columns>
|
||||
<column name="user_name" var="user_name" />
|
||||
<column name="nick_name" var="nick_name" notnull="notnull" />
|
||||
</columns>
|
||||
<conditions>
|
||||
<condition operation="equal" column="document_srl" var="document_srl" />
|
||||
</conditions>
|
||||
</query>
|
||||
12
tests/_data/dbquery/nullValueTest2.xml
Normal file
12
tests/_data/dbquery/nullValueTest2.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<query id="nullValueTest2" action="select">
|
||||
<tables>
|
||||
<table name="documents" />
|
||||
</tables>
|
||||
<columns>
|
||||
<column name="*" />
|
||||
</columns>
|
||||
<conditions>
|
||||
<condition operation="equal" column="module_srl" var="module_srl" />
|
||||
<condition operation="notequal" column="member_srl" var="member_srl" />
|
||||
</conditions>
|
||||
</query>
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
$setting: 5px;
|
||||
|
||||
@import url('//fonts.googleapis.com/css?family=Raleway:700,400');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700&display=swap');
|
||||
|
||||
@mixin mymixin($size) {
|
||||
margin: $size;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
@import 'scss/include1.scss';
|
||||
@import url('scss/include2.scss');
|
||||
@import 'scss/partial1', 'scss/partial2';
|
||||
|
||||
.rhymix {
|
||||
color: $foo;
|
||||
background: url('foo/bar.jpg');
|
||||
|
|
|
|||
|
|
@ -1,6 +1,20 @@
|
|||
@charset "UTF-8";
|
||||
/* Original file: tests/_data/formatter/scss.source1.scss */
|
||||
@import url("//fonts.googleapis.com/css?family=Raleway:700,400");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700&display=swap");
|
||||
/* Original file: tests/_data/formatter/scss.source2.scss */
|
||||
.inc1 {
|
||||
margin: 5px;
|
||||
}
|
||||
.inc2 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.partial1 {
|
||||
display: flex;
|
||||
}
|
||||
.partial2 {
|
||||
display: none;
|
||||
}
|
||||
.rhymix {
|
||||
color: #123456;
|
||||
background: url("../_data/formatter/foo/bar.jpg");
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
@charset "UTF-8";
|
||||
.rhymix{color:#123456;background:url("../_data/formatter/foo/bar.jpg")}.rhymix span{margin:320px}
|
||||
@import url("//fonts.googleapis.com/css?family=Raleway:700,400");@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700&display=swap");.inc1{margin:5px}.inc2{padding-left:10px}.partial1{display:flex}.partial2{display:none}.rhymix{color:#123456;background:url("../_data/formatter/foo/bar.jpg")}.rhymix span{margin:320px}
|
||||
|
|
|
|||
3
tests/_data/formatter/scss/_partial1.scss
Normal file
3
tests/_data/formatter/scss/_partial1.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.partial1 {
|
||||
display: flex;
|
||||
}
|
||||
3
tests/_data/formatter/scss/_partial2.scss
Normal file
3
tests/_data/formatter/scss/_partial2.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.partial2 {
|
||||
display: none;
|
||||
}
|
||||
3
tests/_data/formatter/scss/include1.scss
Normal file
3
tests/_data/formatter/scss/include1.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.inc1 {
|
||||
margin: $setting;
|
||||
}
|
||||
3
tests/_data/formatter/scss/include2.scss
Normal file
3
tests/_data/formatter/scss/include2.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.inc2 {
|
||||
padding-left: $setting * 2;
|
||||
}
|
||||
|
|
@ -282,16 +282,16 @@ class SessionTest extends \Codeception\TestCase\Test
|
|||
public function testGetMemberInfo()
|
||||
{
|
||||
@Rhymix\Framework\Session::start();
|
||||
$this->assertEquals(false, Rhymix\Framework\Session::getMemberInfo());
|
||||
$this->assertEquals(new Rhymix\Framework\Helpers\SessionHelper(), Rhymix\Framework\Session::getMemberInfo());
|
||||
|
||||
Rhymix\Framework\Session::login(42);
|
||||
$this->assertEquals(false, Rhymix\Framework\Session::getMemberInfo());
|
||||
$this->assertEquals(new Rhymix\Framework\Helpers\SessionHelper(), Rhymix\Framework\Session::getMemberInfo());
|
||||
|
||||
Rhymix\Framework\Session::setMemberInfo((object)array('member_srl' => 42));
|
||||
$this->assertEquals((object)array('member_srl' => 42), Rhymix\Framework\Session::getMemberInfo());
|
||||
|
||||
Rhymix\Framework\Session::setMemberInfo((object)array('member_srl' => 99, 'is_admin' => 'Y'));
|
||||
$this->assertEquals(false, Rhymix\Framework\Session::getMemberInfo());
|
||||
$this->assertEquals(new Rhymix\Framework\Helpers\SessionHelper(), Rhymix\Framework\Session::getMemberInfo());
|
||||
|
||||
Rhymix\Framework\Session::close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -446,4 +446,104 @@ class DBQueryParserTest extends \Codeception\TestCase\Test
|
|||
$this->assertEquals('DELETE FROM `rx_documents` WHERE `document_srl` IN (?, ?, ?)', $sql);
|
||||
$this->assertEquals(['12', '34', '56'], $params);
|
||||
}
|
||||
|
||||
public function testEmptyString()
|
||||
{
|
||||
$query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/emptyStringTest1.xml');
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'nick_name' => '',
|
||||
'document_srl' => 1234,
|
||||
));
|
||||
$this->assertEquals('UPDATE `rx_documents` SET `nick_name` = ? WHERE `document_srl` = ?', $sql);
|
||||
$this->assertEquals(['', 1234], $query->getQueryParams());
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString,
|
||||
'document_srl' => 1234,
|
||||
));
|
||||
$this->assertEquals('UPDATE `rx_documents` SET `nick_name` = \'\' WHERE `document_srl` = ?', $sql);
|
||||
$this->assertEquals([1234], $query->getQueryParams());
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString,
|
||||
'document_srl' => '',
|
||||
));
|
||||
$this->assertEquals('UPDATE `rx_documents` SET `nick_name` = \'\'', $sql);
|
||||
$this->assertEquals([], $query->getQueryParams());
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString,
|
||||
'document_srl' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString,
|
||||
));
|
||||
$this->assertEquals('UPDATE `rx_documents` SET `nick_name` = \'\' WHERE `document_srl` = \'\'', $sql);
|
||||
$this->assertEquals([], $query->getQueryParams());
|
||||
|
||||
$query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/emptyStringTest2.xml');
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'category_srl' => 77,
|
||||
'nick_name' => '',
|
||||
));
|
||||
$this->assertEquals('SELECT * FROM `rx_documents` AS `documents` WHERE `category_srl` = ?', $sql);
|
||||
$this->assertEquals([77], $query->getQueryParams());
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'category_srl' => 88,
|
||||
'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString,
|
||||
));
|
||||
$this->assertEquals('SELECT * FROM `rx_documents` AS `documents` WHERE `category_srl` = ? AND `nick_name` = \'\'', $sql);
|
||||
$this->assertEquals([88], $query->getQueryParams());
|
||||
}
|
||||
|
||||
public function testNullValue()
|
||||
{
|
||||
$query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/nullValueTest1.xml');
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'user_name' => null,
|
||||
'nick_name' => 'TEST',
|
||||
'document_srl' => 1234,
|
||||
));
|
||||
$this->assertEquals('UPDATE `rx_documents` SET `nick_name` = ? WHERE `document_srl` = ?', $sql);
|
||||
$this->assertEquals(['TEST', 1234], $query->getQueryParams());
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'user_name' => new \Rhymix\Framework\Parsers\DBQuery\NullValue,
|
||||
'nick_name' => 'TEST',
|
||||
'document_srl' => 1234,
|
||||
));
|
||||
$this->assertEquals('UPDATE `rx_documents` SET `user_name` = NULL, `nick_name` = ? WHERE `document_srl` = ?', $sql);
|
||||
$this->assertEquals(['TEST', 1234], $query->getQueryParams());
|
||||
|
||||
$this->tester->expectThrowable('Exception', function() use($query) {
|
||||
$query->getQueryString('rx_', array(
|
||||
'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\NullValue,
|
||||
'document_srl' => 1234,
|
||||
));
|
||||
});
|
||||
|
||||
$this->tester->expectThrowable('Exception', function() use($query) {
|
||||
$query->getQueryString('rx_', array(
|
||||
'nick_name' => null,
|
||||
'document_srl' => 1234,
|
||||
));
|
||||
});
|
||||
|
||||
$query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/nullValueTest2.xml');
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'member_srl' => null,
|
||||
'module_srl' => 456,
|
||||
));
|
||||
$this->assertEquals('SELECT * FROM `rx_documents` AS `documents` WHERE `module_srl` = ?', $sql);
|
||||
$this->assertEquals([456], $query->getQueryParams());
|
||||
|
||||
$sql = $query->getQueryString('rx_', array(
|
||||
'member_srl' => new \Rhymix\Framework\Parsers\DBQuery\NullValue,
|
||||
'module_srl' => new \Rhymix\Framework\Parsers\DBQuery\NullValue,
|
||||
));
|
||||
$this->assertEquals('SELECT * FROM `rx_documents` AS `documents` WHERE `module_srl` IS NULL AND `member_srl` IS NOT NULL', $sql);
|
||||
$this->assertEquals([], $query->getQueryParams());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue