diff --git a/modules/tag/conf/module.xml b/modules/tag/conf/module.xml new file mode 100644 index 000000000..d01bffb60 --- /dev/null +++ b/modules/tag/conf/module.xml @@ -0,0 +1,21 @@ + + + + + + + + + + 태그 + Tag + 标签 + 標籤 + タグ + Tag + Etiqueta + Теги + Etiket + + + diff --git a/modules/tag/lang/en.php b/modules/tag/lang/en.php new file mode 100644 index 000000000..1e052b35f --- /dev/null +++ b/modules/tag/lang/en.php @@ -0,0 +1,8 @@ +tag_default_config = 'Default Config'; +$lang->tag_separators = 'Tag Separators'; +$lang->tag_separator_comma = 'comma(foo, bar)'; +$lang->tag_separator_hash = 'hash(#foo #bar)'; +$lang->tag_separator_space = 'space'; +$lang->tag_separator_help = 'If you select more than one type of separator, all of them will be recognized. For example, "#foo,bar Rhymix"'; diff --git a/modules/tag/lang/ko.php b/modules/tag/lang/ko.php new file mode 100644 index 000000000..d2a18c58c --- /dev/null +++ b/modules/tag/lang/ko.php @@ -0,0 +1,8 @@ +tag_default_config = '태그 기본 설정'; +$lang->tag_separators = '태그 구분 방법'; +$lang->tag_separator_comma = '쉼표(foo, bar)'; +$lang->tag_separator_hash = '해시(#foo #bar)'; +$lang->tag_separator_space = '공백'; +$lang->tag_separator_help = '두 가지 이상 선택할 경우 모두 인식합니다. 예: "#foo,bar Rhymix" 입력시 해시태그와 쉼표, 공백 모두 구분자로 인식할 수 있습니다.'; diff --git a/modules/tag/tag.admin.controller.php b/modules/tag/tag.admin.controller.php index 50d947ce5..c814701cf 100644 --- a/modules/tag/tag.admin.controller.php +++ b/modules/tag/tag.admin.controller.php @@ -7,6 +7,34 @@ */ class tagAdminController extends tag { + /** + * Save admin config. + */ + public function procTagAdminInsertConfig() + { + $config = new stdClass; + $vars = Context::getRequestVars(); + + $config->separators = []; + foreach ($vars->separators ?? [] as $val) + { + if (in_array($val, ['comma', 'hash', 'space'])) + { + $config->separators[] = $val; + } + } + + $oModuleController = ModuleController::getInstance(); + $output = $oModuleController->insertModuleConfig($this->module, $config); + if (!$output->toBool()) + { + return $output; + } + + $this->setMessage('success_registed'); + $this->setRedirectUrl(Context::get('success_return_url')); + } + /** * @brief Delete all tags for a particular module */ diff --git a/modules/tag/tag.admin.view.php b/modules/tag/tag.admin.view.php new file mode 100644 index 000000000..1a419e858 --- /dev/null +++ b/modules/tag/tag.admin.view.php @@ -0,0 +1,13 @@ +module) ?: new stdClass; + Context::set('tag_config', $config); + + $this->setTemplatePath($this->module_path . 'tpl'); + $this->setTemplateFile('config'); + } +} diff --git a/modules/tag/tag.controller.php b/modules/tag/tag.controller.php index ce4b35603..a59e1cd65 100644 --- a/modules/tag/tag.controller.php +++ b/modules/tag/tag.controller.php @@ -8,78 +8,78 @@ class tagController extends tag { /** - * @brief Initialization - */ - function init() - { - } - - /** - * @brief , (Comma) to clean up the tags attached to the trigger + * Parse tags. */ function triggerArrangeTag(&$obj) { - if(!$obj->tags) return; - // tags by variable - $arranged_tag_list = array(); - $tag_list = explode(',', $obj->tags); - foreach($tag_list as $tag) + if (empty($obj->tags)) { - $tag = utf8_trim(utf8_normalize_spaces($tag)); - if($tag) - { - $arranged_tag_list[$tag] = $tag; - } + return; } - if(!count($arranged_tag_list)) + + $tag_list = tagModel::splitString($obj->tags ?? ''); + if (count($tag_list)) { - $obj->tags = null; + $obj->tags = implode(', ', $tag_list); } else { - $obj->tags = implode(',', $arranged_tag_list); + $obj->tags = null; } } /** - * @brief Input trigger tag - * Enter a Tag to delete that article and then re-enter all the tags using a method + * Replace all tags belonging to a document with a new list of tags. + * + * @param object $obj + * @return BaseObject */ function triggerInsertTag(&$obj) { - $module_srl = $obj->module_srl; - $document_srl = $obj->document_srl; - $tags = $obj->tags; - if(!$document_srl) return; - // Remove all tags that article + if (!$obj->document_srl) + { + return new BaseObject; + } + + // Remove all existing tags. $output = $this->triggerDeleteTag($obj); - if(!$output->toBool()) return $output; + if(!$output->toBool()) + { + return $output; + } + // Re-enter the tag $args = new stdClass(); - $args->module_srl = $module_srl; - $args->document_srl = $document_srl; + $args->module_srl = $obj->module_srl; + $args->document_srl = $obj->document_srl; - $tag_list = explode(',', $tags); - foreach($tag_list as $tag) + $tag_list = tagModel::splitString($obj->tags ?? ''); + foreach ($tag_list as $tag) { - $args->tag = utf8_trim(utf8_normalize_spaces($tag)); - if(!$args->tag) continue; + $args->tag = $tag; $output = executeQuery('tag.insertTag', $args); - if(!$output->toBool()) return $output; + if(!$output->toBool()) + { + return $output; + } } } /** - * @brief Delete the tag trigger a specific article - * document_srl delete tag belongs to + * Delete all tags belonging to a document. + * + * @param object $obj + * @return BaseObject */ function triggerDeleteTag(&$obj) { - $document_srl = $obj->document_srl; - if(!$document_srl) return; + if (!$obj->document_srl) + { + return new BaseObject; + } $args = new stdClass(); - $args->document_srl = $document_srl; + $args->document_srl = $obj->document_srl; return executeQuery('tag.deleteTag', $args); } @@ -88,11 +88,13 @@ class tagController extends tag */ function triggerDeleteModuleTags(&$obj) { - $module_srl = $obj->module_srl; - if(!$module_srl) return; + if (!$obj->module_srl) + { + return; + } $oTagController = getAdminController('tag'); - return $oTagController->deleteModuleTags($module_srl); + return $oTagController->deleteModuleTags($obj->module_srl); } function triggerMoveDocument($obj) diff --git a/modules/tag/tag.model.php b/modules/tag/tag.model.php index 682799058..5e1a9bd03 100644 --- a/modules/tag/tag.model.php +++ b/modules/tag/tag.model.php @@ -8,12 +8,77 @@ class tagModel extends tag { /** - * @brief Initialization + * Separator regexp cache */ - function init() + protected static $_separator_list = null; + protected static $_separator_regexp = null; + + /** + * Generate and cache separator list and regexp. + */ + protected static function _generateSeparatorConfig() { + $config = ModuleModel::getModuleConfig('tag'); + if (isset($config->separators) && count($config->separators)) + { + self::$_separator_list = $config->separators; + } + else + { + self::$_separator_list = ['comma', 'hash']; + } + + $regexp = '/['; + $regexp_map = [ + 'comma' => ',', + 'hash' => '#', + 'space' => '\\s', + ]; + foreach (self::$_separator_list as $separator) + { + $regexp .= $regexp_map[$separator]; + } + $regexp .= ']+/'; + + self::$_separator_regexp = $regexp; } - + + /** + * Split a string of tags into an array. + * + * @param string $str + * @return array + */ + public static function splitString(string $str): array + { + if (!isset(self::$_separator_list)) + { + self::_generateSeparatorConfig(); + } + + // Clean up the input string. + $str = trim(utf8_normalize_spaces(utf8_clean($str))); + if ($str === '') + { + return []; + } + + // Split the input string and collect non-empty fragments. + $fragments = preg_split(self::$_separator_regexp, $str, -1, PREG_SPLIT_NO_EMPTY); + $tags = []; + foreach ($fragments as $fragment) + { + $fragment = trim($fragment); + if ($fragment !== '') + { + $tags[strtolower($fragment)] = $fragment; + } + } + + // Return a list of valid fragments with no duplicates. + return array_values(array_unique($tags)); + } + /** * @brief Imported Tag List * Many of the specified module in order to extract the number of tags diff --git a/modules/tag/tpl/config.html b/modules/tag/tpl/config.html new file mode 100644 index 000000000..faffd857c --- /dev/null +++ b/modules/tag/tpl/config.html @@ -0,0 +1,50 @@ + + +
+

{$lang->tag}

+
+ + + +
+ + + + + +
+

{$XE_VALIDATOR_MESSAGE}

+
+ +
+
+ +
+ + + +

+ {$lang->tag_separator_help} +

+
+
+
+ +
+ +
+ +