diff --git a/classes/module/ModuleObject.class.php b/classes/module/ModuleObject.class.php index a736136f4..0d5b4d3d8 100644 --- a/classes/module/ModuleObject.class.php +++ b/classes/module/ModuleObject.class.php @@ -254,15 +254,15 @@ class ModuleObject extends BaseObject // Get privileges(granted) information for target module by of module.xml if(($permission = $this->xml_info->action->{$this->act}->permission) && $permission->check_var) { - // Check parameter - if(empty($check_module_srl = trim(Context::get($permission->check_var)))) + // Ensure that the list of modules to check is the right type and not empty + $check_var = Context::get($permission->check_var); + if (is_scalar($check_var)) { - return false; - } + if (empty($check_module_srl = trim($check_var))) + { + return false; + } - // If value is not array - if(!is_array($check_module_srl)) - { // Convert string to array. delimiter is ,(comma) or |@| if(preg_match('/,|\|@\|/', $check_module_srl, $delimiter) && $delimiter[0]) { @@ -273,6 +273,14 @@ class ModuleObject extends BaseObject $check_module_srl = array($check_module_srl); } } + else + { + $check_module_srl = array_map('trim', $check_var); + if (!count($check_var)) + { + return false; + } + } // Check permission by privileges(granted) information for target module foreach($check_module_srl as $target_srl) @@ -295,7 +303,15 @@ class ModuleObject extends BaseObject } // Check permission based on the grant information for the current module. - $grant = ModuleModel::getInstance()->getGrant($this->module_info, $this->user, $this->xml_info); + if (isset($check_grant)) + { + $grant = $check_grant; + } + else + { + $grant = ModuleModel::getInstance()->getGrant($this->module_info, $this->user, $this->xml_info); + } + if(!$this->checkPermission($grant, $this->user, $failed_requirement)) { $this->stop($this->_generatePermissionError($failed_requirement)); diff --git a/common/framework/parsers/template/TemplateParser_v2.php b/common/framework/parsers/template/TemplateParser_v2.php index 501845a2a..399e45d97 100644 --- a/common/framework/parsers/template/TemplateParser_v2.php +++ b/common/framework/parsers/template/TemplateParser_v2.php @@ -185,7 +185,7 @@ class TemplateParser_v2 }, $content); // Inline scripts. - $content = preg_replace_callback('#(?<=\s)(href="javascript:|on[a-z]+=")([^"]*?)"#i', function($match) { + $content = preg_replace_callback('#(?<=\s)(href="javascript:|pattern="|on[a-z]+=")([^"]*?)"#i', function($match) { return $match[1] . 'config->context = \'JS\'; ?>' . $match[2] . 'config->context = \'HTML\'; ?>"'; }, $content); diff --git a/common/js/common.js b/common/js/common.js index e2d49fbff..15e31b6e4 100644 --- a/common/js/common.js +++ b/common/js/common.js @@ -668,7 +668,7 @@ Rhymix.ajaxForm = function(form, success, error) { * @return void */ Rhymix.checkboxToggleAll = function(name) { - if (!window[name]) { + if (typeof name === 'undefined') { name='cart'; } let options = { @@ -1027,7 +1027,7 @@ $(function() { e.preventDefault(); e.stopPropagation(); - if (window[Rhymix.loadedPopupMenus[params.menu_id]]) { + if (Rhymix.loadedPopupMenus[params.menu_id]) { return Rhymix.displayPopupMenu(params, response_tags, params); } @@ -1472,12 +1472,16 @@ function popopen(url, target) { * @return void */ function doAddDocumentCart(obj) { - Rhymix.addedDocument.push(obj.value); + if (obj && obj.value) { + Rhymix.addedDocument.push(obj.value); + } setTimeout(function() { - exec_json('document.procDocumentAddCart', { - srls: Rhymix.addedDocument.join(',') - }); - Rhymix.addedDocument = []; + if (Rhymix.addedDocument.length > 0) { + exec_json('document.procDocumentAddCart', { + srls: Rhymix.addedDocument + }); + Rhymix.addedDocument = []; + } }, 100); } diff --git a/common/js/xml_js_filter.js b/common/js/xml_js_filter.js index 83459d213..414c175d8 100644 --- a/common/js/xml_js_filter.js +++ b/common/js/xml_js_filter.js @@ -467,13 +467,13 @@ function legacy_filter(filter_name, form, module, act, callback, responses, conf }; if (!hasFile) { - Rhymix.ajax(module + '.' + act, params, callback_wrapper); + exec_json(module + '.' + act, params, callback_wrapper); } else { var fd = new FormData(); for (let key in params) { fd.append(key, params[key]); } - Rhymix.ajax(null, fd, callback_wrapper); + exec_json('raw', fd, callback_wrapper); } }; diff --git a/modules/comment/comment.controller.php b/modules/comment/comment.controller.php index f57f067f6..3eb2baee8 100644 --- a/modules/comment/comment.controller.php +++ b/modules/comment/comment.controller.php @@ -2001,6 +2001,41 @@ class CommentController extends Comment $this->setMessage('success_declared_cancel'); } + /** + * Update the number of uploaded files in the comment + * + * @param int|array $comment_srl_list + * @return void + */ + public function updateUploadedCount($comment_srl_list) + { + if (!is_array($comment_srl_list)) + { + $comment_srl_list = array($comment_srl_list); + } + + if (!count($comment_srl_list)) + { + return; + } + + $comment_srl_list = array_unique($comment_srl_list); + + foreach($comment_srl_list as $comment_srl) + { + $comment_srl = (int)$comment_srl; + if ($comment_srl <= 0) + { + continue; + } + + $args = new stdClass; + $args->comment_srl = $comment_srl; + $args->uploaded_count = FileModel::getFilesCount($comment_srl); + executeQuery('comment.updateUploadedCount', $args); + } + } + /** * Method to add a pop-up menu when clicking for displaying child comments * @param string $url diff --git a/modules/comment/queries/updateUploadedCount.xml b/modules/comment/queries/updateUploadedCount.xml new file mode 100644 index 000000000..9a9bfab15 --- /dev/null +++ b/modules/comment/queries/updateUploadedCount.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 0bc2dc7c9..4c281b0d4 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -3301,16 +3301,23 @@ class DocumentController extends Document } // Get document_srl - $srls = explode(',',Context::get('srls')); - for($i = 0; $i < count($srls); $i++) + $srls = Context::get('srls'); + if (is_array($srls)) { - $srl = trim($srls[$i]); - - if(!$srl) continue; - - $document_srls[] = $srl; + $document_srls = array_map('intval', $srls); + } + else + { + $document_srls = array_map('intval', explode(',', $srls)); + } + + $document_srls = array_unique(array_filter($document_srls, function($srl) { + return $srl > 0; + })); + if (!count($document_srls)) + { + return; } - if(!count($document_srls)) return; // Get module_srl of the documents $args = new stdClass; @@ -3781,7 +3788,17 @@ Content; } } + /** + * A typo of updateUploadedCount, maintained for backward compatibility. + * + * @deprecated + */ public function updateUploaedCount($document_srl_list) + { + return $this->updateUploadedCount($document_srl_list); + } + + public function updateUploadedCount($document_srl_list) { if(!is_array($document_srl_list)) { @@ -3797,7 +3814,8 @@ Content; foreach($document_srl_list as $document_srl) { - if(!$document_srl = (int) $document_srl) + $document_srl = (int)$document_srl; + if ($document_srl <= 0) { continue; } @@ -3817,7 +3835,7 @@ Content; return; } - $this->updateUploaedCount($file->upload_target_srl); + $this->updateUploadedCount($file->upload_target_srl); } /** diff --git a/modules/document/tpl/extra_keys.html b/modules/document/tpl/extra_keys.html index 407d99a41..8bdb07b6d 100644 --- a/modules/document/tpl/extra_keys.html +++ b/modules/document/tpl/extra_keys.html @@ -61,7 +61,7 @@
- +

{$lang->about_extra_vars_default_value}

diff --git a/modules/extravar/skins/default/assets/file_upload.js b/modules/extravar/skins/default/assets/file_upload.js index 878ac15af..d280ea1e9 100644 --- a/modules/extravar/skins/default/assets/file_upload.js +++ b/modules/extravar/skins/default/assets/file_upload.js @@ -1,16 +1,16 @@ 'use strict'; -(function($) { - $(function() { - $('button.evFileRemover').on('click', function() { - const container = $(this).parents('.ev_file_upload'); +$(function() { + $('.ev_file_upload').each(function() { + const container = $(this); + container.find('button.evFileRemover').on('click', function() { container.find('span.filename').text(''); container.find('span.filesize').text(''); container.find('input[type=hidden][name^=_delete_]').val('Y'); container.find('input[type=file]').val(''); + $(this).remove(); }); - $('input.rx_ev_file').on('change', function() { - const container = $(this).parents('.ev_file_upload'); + container.find('input.rx_ev_file').on('change', function() { const max_size = parseInt($(this).data('allowedFilesize'), 10); const file_count = this.files.length; for (let i = 0; i < file_count; i++) { @@ -23,4 +23,4 @@ container.find('input[type=hidden][name^=_delete_]').val('N'); }); }); -})(jQuery); +}); diff --git a/modules/extravar/skins/default/assets/number.js b/modules/extravar/skins/default/assets/number.js new file mode 100644 index 000000000..eccbd7474 --- /dev/null +++ b/modules/extravar/skins/default/assets/number.js @@ -0,0 +1,7 @@ +'use strict'; + +$(function() { + $('input.rx_ev_number').on('input', function() { + this.value = this.value.replace(/[^0-9]/g, ''); + }); +}); diff --git a/modules/extravar/skins/default/form_types/password.blade.php b/modules/extravar/skins/default/form_types/password.blade.php index 4936c05bd..d304e691e 100644 --- a/modules/extravar/skins/default/form_types/password.blade.php +++ b/modules/extravar/skins/default/form_types/password.blade.php @@ -2,6 +2,7 @@ id="{{ $input_id }}"|if="$input_id" class="password rx_ev_password" style="{{ $definition->style }}"|if="$definition->style" value="{{ strval($value) !== '' ? $value : strval($default) }}" + autocomplete="off" autocapitalize="none" @required(toBool($definition->is_required)) @disabled(toBool($definition->is_disabled)) @readonly(toBool($definition->is_readonly)) diff --git a/modules/extravar/skins/default/form_types/text.blade.php b/modules/extravar/skins/default/form_types/text.blade.php index ca9122298..754b6f145 100644 --- a/modules/extravar/skins/default/form_types/text.blade.php +++ b/modules/extravar/skins/default/form_types/text.blade.php @@ -17,7 +17,8 @@ @readonly(toBool($definition->is_readonly)) /> @elseif ($type === 'number') - copyFiles($obj->source->document_srl, $obj->copied->module_srl, $obj->copied->document_srl, $obj->copied->content); + $this->setFilesValid($obj->copied->document_srl, 'doc'); + DocumentController::getInstance()->updateUploadedCount($obj->copied->document_srl); } function triggerAddCopyCommentByDocument(&$obj) @@ -2012,6 +2014,8 @@ class FileController extends File } $this->copyFiles($obj->source->comment_srl, $obj->copied->module_srl, $obj->copied->comment_srl, $obj->copied->content); + $this->setFilesValid($obj->copied->comment_srl, 'com'); + CommentController::getInstance()->updateUploadedCount($obj->copied->comment_srl); } function triggerCopyModule(&$obj) diff --git a/modules/member/member.admin.controller.php b/modules/member/member.admin.controller.php index bde74ac60..f9ee4c530 100644 --- a/modules/member/member.admin.controller.php +++ b/modules/member/member.admin.controller.php @@ -878,21 +878,27 @@ class MemberAdminController extends Member $args->column_type = Context::get('column_type'); $args->column_name = strtolower(Context::get('column_id')); $args->column_title = Context::get('column_title'); - $args->default_value = explode("\n", str_replace("\r", '', Context::get('default_value'))); - $args->required = Context::get('required'); - $args->is_active = (isset($args->required)); - if(!in_array(strtoupper($args->required), array('Y','N')))$args->required = 'N'; - $args->description = Context::get('description') ? Context::get('description') : ''; - // Default values - if(in_array($args->column_type, array('checkbox','select','radio')) && count($args->default_value)) + $args->default_value = trim(utf8_clean(Context::get('default_value'))); + $args->options = trim(utf8_clean(Context::get('options'))); + if ($args->options !== '') { - $args->default_value = serialize($args->default_value); + $args->options = array_map('trim', explode("\n", $args->options)); + $args->options = json_encode($args->options, \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES); } else { - $args->default_value = ''; + $args->options = null; } + $args->required = Context::get('required'); + if (!in_array(strtoupper($args->required), array('Y','N'))) + { + $args->required = 'N'; + } + + $args->is_active = (isset($args->required)); + $args->description = Context::get('description') ? Context::get('description') : ''; + // Check ID duplicated if (Context::isReservedWord($args->column_name)) { @@ -909,7 +915,7 @@ class MemberAdminController extends Member } } // Fix if member_join_form_srl exists. Add if not exists. - $isInsert; + $isInsert = false; if(!$args->member_join_form_srl) { $isInsert = true; diff --git a/modules/member/member.admin.model.php b/modules/member/member.admin.model.php index 4a3b9c23e..18f434a03 100644 --- a/modules/member/member.admin.model.php +++ b/modules/member/member.admin.model.php @@ -288,13 +288,24 @@ class MemberAdminModel extends Member if($output->toBool() && $output->data) { $formInfo = $output->data; - $default_value = $formInfo->default_value; - if($default_value) + $default_value = ''; + $options = ''; + if (isset($formInfo->options) && $formInfo->options !== '') { - $default_value = unserialize($default_value); - Context::set('default_value', $default_value); + $default_value = $formInfo->default_value; + $options = json_decode($formInfo->options, true); + } + elseif (preg_match('/^a:\d+:\{i:/', $formInfo->default_value)) + { + $options = unserialize($formInfo->default_value); + } + else + { + $default_value = $formInfo->default_value; } Context::set('formInfo', $output->data); + Context::set('default_value', $default_value); + Context::set('options', $options); } $oMemberModel = getModel('member'); @@ -314,7 +325,7 @@ class MemberAdminModel extends Member $oTemplate = TemplateHandler::getInstance(); $tpl = $oTemplate->compile($this->module_path.'tpl', 'insert_join_form'); - $this->add('tpl', str_replace("\n"," ",$tpl)); + $this->add('tpl', $tpl); } /** diff --git a/modules/member/member.admin.view.php b/modules/member/member.admin.view.php index 88b44d034..0b46709f2 100644 --- a/modules/member/member.admin.view.php +++ b/modules/member/member.admin.view.php @@ -486,7 +486,7 @@ class MemberAdminView extends Member { $extend_form_list = MemberModel::getCombineJoinForm($memberInfo); $security = new Security($extend_form_list); - $security->encodeHTML('..column_title', '..description', '..default_value.'); + $security->encodeHTML('..column_title', '..description', '..default_value', '..options.'); if ($memberInfo) { @@ -725,6 +725,7 @@ class MemberAdminView extends Member $input->input_id = $extendForm->column_name; $input->value = $extendForm->value ?? ''; $input->default = $extendForm->default_value ?? null; + $input->options = $extendForm->options ?? null; if ($extendForm->column_type === 'tel' || $extendForm->column_type === 'tel_intl') { $input->style = 'width:33.3px'; diff --git a/modules/member/member.class.php b/modules/member/member.class.php index daf61158d..32cf596b2 100644 --- a/modules/member/member.class.php +++ b/modules/member/member.class.php @@ -167,6 +167,9 @@ class Member extends ModuleObject if(!$oDB->isIndexExists('member_auth_mail', 'idx_member_srl')) return true; if($oDB->isIndexExists('member_auth_mail', 'unique_key')) return true; + // Check join form options column + if(!$oDB->isColumnExists('member_join_form', 'options')) return true; + // Update status column $output = executeQuery('member.getDeniedAndStatus'); if ($output->data->count) @@ -403,6 +406,12 @@ class Member extends ModuleObject $oDB->dropIndex('member_auth_mail', 'unique_key'); } + // Check join form options column + if(!$oDB->isColumnExists('member_join_form', 'options')) + { + $oDB->addColumn('member_join_form', 'options', 'text', null, null, null, 'default_value'); + } + // Update status column $output = executeQuery('member.getDeniedAndStatus'); if ($output->data->count) diff --git a/modules/member/member.controller.php b/modules/member/member.controller.php index 9e2a488e8..26b3ea4d4 100644 --- a/modules/member/member.controller.php +++ b/modules/member/member.controller.php @@ -2871,7 +2871,7 @@ class MemberController extends Member $extend_form_list = MemberModel::getJoinFormlist(); $security = new Security($extend_form_list); - $security->encodeHTML('..column_title', '..description', '..default_value.'); + $security->encodeHTML('..column_title', '..description', '..default_value', '..options.'); if($config->signupForm) { foreach($config->signupForm as $no => $formInfo) @@ -3167,7 +3167,7 @@ class MemberController extends Member $extend_form_list = MemberModel::getJoinFormlist(); $security = new Security($extend_form_list); - $security->encodeHTML('..column_title', '..description', '..default_value.'); + $security->encodeHTML('..column_title', '..description', '..default_value', '..options.'); if($config->signupForm) { foreach($config->signupForm as $no => $formInfo) diff --git a/modules/member/member.model.php b/modules/member/member.model.php index 03013abe2..2cdda377e 100644 --- a/modules/member/member.model.php +++ b/modules/member/member.model.php @@ -806,31 +806,38 @@ class MemberModel extends Member if(!$join_form_list) return NULL; // Need to unserialize because serialized array is inserted into DB in case of default_value if(!is_array($join_form_list)) $join_form_list = array($join_form_list); - $join_form_count = count($join_form_list); - for($i=0;$i<$join_form_count;$i++) + foreach ($join_form_list as $i => $join_form) { - $join_form_list[$i]->column_name = strtolower($join_form_list[$i]->column_name); + $join_form->column_name = strtolower($join_form->column_name); - $member_join_form_srl = $join_form_list[$i]->member_join_form_srl; - $column_type = $join_form_list[$i]->column_type; - $column_name = $join_form_list[$i]->column_name; - $column_title = $join_form_list[$i]->column_title; - $default_value = $join_form_list[$i]->default_value; // Add language variable - if(!isset($lang->extend_vars)) $lang->extend_vars = array(); - $lang->extend_vars[$column_name] = $column_title; - // unserialize if the data type if checkbox, select and so on - if(in_array($column_type, array('checkbox','select','radio'))) + $column_name = $join_form->column_name; + $column_title = $join_form->column_title; + if (!isset($lang->extend_vars)) { - $join_form_list[$i]->default_value = unserialize($default_value); - if(!$join_form_list[$i]->default_value[0]) $join_form_list[$i]->default_value = ''; + $lang->extend_vars = array(); + } + $lang->extend_vars[$column_name] = $column_title; + + // unserialize if the data type if checkbox, select and so on + if (in_array($join_form->column_type, ['checkbox','select','radio'])) + { + if (isset($join_form->options) && $join_form->options !== '') + { + $join_form->options = json_decode($join_form->options, true); + } + elseif (preg_match('/^a:\d+:\{i:/', $join_form->default_value)) + { + $join_form->options = unserialize($join_form->default_value); + $join_form->default_value = ''; + } } else { - $join_form_list[$i]->default_value = ''; + $join_form->default_value = ''; } - $list[$member_join_form_srl] = $join_form_list[$i]; + $list[$join_form->member_join_form_srl] = $join_form; } self::$_join_form_list = $list; } @@ -958,12 +965,17 @@ class MemberModel extends Member $join_form = $output->data; if(!$join_form) return NULL; - $column_type = $join_form->column_type; - $default_value = $join_form->default_value; - - if(in_array($column_type, array('checkbox','select','radio'))) + if (in_array($join_form->column_type, ['checkbox','select','radio'])) { - $join_form->default_value = unserialize($default_value); + if (isset($join_form->options) && $join_form->options !== '') + { + $join_form->options = json_decode($join_form->options, true); + } + elseif (preg_match('/^a:\d+:\{i:/', $join_form->default_value)) + { + $join_form->options = unserialize($join_form->default_value); + $join_form->default_value = ''; + } } else { diff --git a/modules/member/member.view.php b/modules/member/member.view.php index d6afba4af..9523b6cc6 100644 --- a/modules/member/member.view.php +++ b/modules/member/member.view.php @@ -280,6 +280,7 @@ class MemberView extends Member $extvalue->input_id = $formInfo->name; $extvalue->value = $extendFormInfo[$formInfo->member_join_form_srl]->value ?? null; $extvalue->default = $extendFormInfo[$formInfo->member_join_form_srl]->default_value ?? null; + $extvalue->options = $extendFormInfo[$formInfo->member_join_form_srl]->options ?? null; $item->value = $extvalue->getValueHTML(); } diff --git a/modules/member/queries/insertJoinForm.xml b/modules/member/queries/insertJoinForm.xml index 808ff4160..9b8be3c54 100644 --- a/modules/member/queries/insertJoinForm.xml +++ b/modules/member/queries/insertJoinForm.xml @@ -9,6 +9,7 @@ + diff --git a/modules/member/queries/updateJoinForm.xml b/modules/member/queries/updateJoinForm.xml index 5b6082682..3d18f78bc 100644 --- a/modules/member/queries/updateJoinForm.xml +++ b/modules/member/queries/updateJoinForm.xml @@ -8,6 +8,7 @@ + diff --git a/modules/member/schemas/member_join_form.xml b/modules/member/schemas/member_join_form.xml index e69076e8f..9c3e8f5e3 100644 --- a/modules/member/schemas/member_join_form.xml +++ b/modules/member/schemas/member_join_form.xml @@ -5,6 +5,7 @@ + diff --git a/modules/member/tpl/insert_join_form.html b/modules/member/tpl/insert_join_form.html index 18f2a4c21..d59983f12 100644 --- a/modules/member/tpl/insert_join_form.html +++ b/modules/member/tpl/insert_join_form.html @@ -26,11 +26,17 @@ -
- +
+
- -

{$lang->about_multi_type}

+ +
+
+
+ +
+ +

{$lang->about_multi_type}

@@ -51,7 +57,6 @@