From 6bfa625ef0323332aab3cf00b0ccbe04b213b9b7 Mon Sep 17 00:00:00 2001 From: xiaomlove <353856593@qq.com> Date: Thu, 4 Mar 2021 20:43:55 +0800 Subject: [PATCH] finish custom field basic --- lang/chs/lang_fields.php | 10 ++- nexus/Field/Field.php | 170 ++++++++++++++++++++++++++++++++++----- public/catmanage.php | 10 ++- public/details.php | 6 ++ 4 files changed, 175 insertions(+), 21 deletions(-) diff --git a/lang/chs/lang_fields.php b/lang/chs/lang_fields.php index 6bf717fb..7edcbcdb 100644 --- a/lang/chs/lang_fields.php +++ b/lang/chs/lang_fields.php @@ -15,7 +15,15 @@ $lang_fields = [ 'col_help' => '辅助说明', 'col_options' => '选项', 'col_action' => '操作', + 'col_is_single_row' => '展示时单独一行', 'js_sure_to_delete_this' => '你确信要删除此项目吗?', - 'submit_submit' => '提交' + 'submit_submit' => '提交', + 'field_type_text' => '短文本', + 'field_type_textara' => '长文本', + 'field_type_radio' => '横向单选', + 'field_type_checkbox' => '横向多选', + 'field_type_select' => '下拉单选', + 'field_type_image' => '图片', + 'field_type_file' => '文件', ]; \ No newline at end of file diff --git a/nexus/Field/Field.php b/nexus/Field/Field.php index 8258fb8e..4a8357ea 100644 --- a/nexus/Field/Field.php +++ b/nexus/Field/Field.php @@ -15,15 +15,67 @@ class Field const TYPE_FILE = 'file'; public static $types = [ - self::TYPE_TEXT => '短文本(text)', - self::TYPE_TEXTAREA => '长文本(textarea)', - self::TYPE_RADIO => '横向单选(radio)', - self::TYPE_CHECKBOX => '横向多选(checkbox)', - self::TYPE_SELECT => '下拉单选(select)', - self::TYPE_IMAGE => '图片(image)', - self::TYPE_FILE => '文件(file)', + self::TYPE_TEXT => [ + 'text' => 'text', + 'has_option' => false, + 'is_value_multiple' => false, + ], + self::TYPE_TEXTAREA => [ + 'text' => 'textarea', + 'has_option' => false, + 'is_value_multiple' => false, + ], + self::TYPE_RADIO => [ + 'text' => 'radio', + 'has_option' => true, + 'is_value_multiple' => false, + ], + self::TYPE_CHECKBOX => [ + 'text' => 'checkbox', + 'has_option' => true, + 'is_value_multiple' => true, + ], + self::TYPE_SELECT => [ + 'text' => 'select', + 'has_option' => true, + 'is_value_multiple' => false, + ], + self::TYPE_IMAGE => [ + 'text' => 'image', + 'has_option' => false, + 'is_value_multiple' => false, + ], + self::TYPE_FILE => [ + 'text' => 'file', + 'has_option' => false, + 'is_value_multiple' => false, + ], ]; + public function getTypeHuman($type) + { + global $lang_fields; + $map = [ + self::TYPE_TEXT => $lang_fields['field_type_text'], + self::TYPE_TEXTAREA => $lang_fields['field_type_textara'], + self::TYPE_RADIO => $lang_fields['field_type_radio'], + self::TYPE_CHECKBOX => $lang_fields['field_type_checkbox'], + self::TYPE_SELECT => $lang_fields['field_type_select'], + self::TYPE_IMAGE => $lang_fields['field_type_image'], + self::TYPE_FILE => $lang_fields['field_type_file'], + ]; + return $map[$type] ?? ''; + } + + public function getTypeRadioOptions() + { + $out = []; + foreach (self::$types as $key => $value) { + $out[$key] = sprintf('%s(%s)', $this->getTypeHuman($key), $value['text']); + } + return $out; + } + public function radio($name, $options, $current = null) { @@ -42,10 +94,11 @@ class Field global $lang_fields; $trName = tr($lang_fields['col_name'] . '*', '  仅允许数字、字母、下划线', 1, '', true); $trLabel = tr($lang_fields['col_label'] . '*', '', 1, '', true); - $trType = tr($lang_fields['col_type'] . '*', $this->radio('type', self::$types, $row['type'] ?? null), 1, '', true); + $trType = tr($lang_fields['col_type'] . '*', $this->radio('type', $this->getTypeRadioOptions(), $row['type'] ?? null), 1, '', true); $trRequired = tr($lang_fields['col_required'] . '*', $this->radio('required', ['0' => '否', '1' => '是'], $row['required'] ?? null), 1, '', true); $trHelp = tr($lang_fields['col_help'], '', 1, '', true); $trOptions = tr($lang_fields['col_options'], '
类型为单选、多选、下拉时必填,一行一个,格式:选项值|选项描述文本', 1, '', true); + $trIsSingleRow = tr($lang_fields['col_is_single_row'] . '*', $this->radio('is_single_row', ['0' => '否', '1' => '是'], $row['is_single_row'] ?? null), 1, '', true); $id = $row['id'] ?? 0; $form = << @@ -60,6 +113,7 @@ class Field {$trRequired} {$trHelp} {$trOptions} + {$trIsSingleRow}
@@ -85,12 +139,14 @@ HTML; 'label' => $lang_fields['col_label'], 'type_text' => $lang_fields['col_type'], 'required_text' => $lang_fields['col_required'], + 'is_single_row_text' => $lang_fields['col_is_single_row'], 'action' => $lang_fields['col_action'], ]; $rows = []; while ($row = mysql_fetch_assoc($res)) { $row['required_text'] = $row['required'] ? '是' : '否'; - $row['type_text'] = self::$types[$row['type']] ?? ''; + $row['is_single_row_text'] = $row['is_single_row'] ? '是' : '否'; + $row['type_text'] = sprintf('%s(%s)', $this->getTypeHuman($row['type']), $row['type']); $row['action'] = sprintf( "%s | %s", $row['id'], $lang_fields['js_sure_to_delete_this'], $lang_fields['text_delete'], $row['id'], $lang_fields['text_edit'] @@ -149,6 +205,14 @@ HEAD; } $attributes['required'] = $data['required']; + if (!isset($data['is_single_row'])) { + throw new \InvalidArgumentException("展示时单独一行 必须"); + } + if (!in_array($data['is_single_row'], ["0", "1"], true)) { + throw new \InvalidArgumentException("展示时单独一行 非法"); + } + $attributes['is_single_row'] = $data['is_single_row']; + $attributes['help'] = $data['help'] ?? ''; $attributes['options'] = trim($data['options'] ?? ''); $now = date('Y-m-d H:i:s'); @@ -185,17 +249,18 @@ HEAD; { $sql = 'select * from torrents_custom_fields'; $res = sql_query($sql); - $checkbox = []; if (!is_array($current)) { $current = explode(',', $current); } + $checkbox = ''; while ($row = mysql_fetch_assoc($res)) { - $checkbox[] = sprintf( + $checkbox .= sprintf( '', - $name, $row['id'], in_array($row['id'], $current) ? ' checked' : '', "{$row['label']}({$row['id']})" + $name, $row['id'], in_array($row['id'], $current) ? ' checked' : '', "{$row['label']}[{$row['id']}]" ); } - return implode('', $checkbox); + $checkbox .= ''; + return $checkbox; } @@ -307,16 +372,85 @@ JS; public function listTorrentCustomField($torrentId) { - $res = sql_query("select v.*, f.type as custom_field_type from torrents_custom_field_values v inner join torrents_custom_fields f on v.custom_field_id = f.id where torrent_id = $torrentId"); + global $browsecatmode; + $res = sql_query("select f.*, v.custom_field_value from torrents_custom_field_values v inner join torrents_custom_fields f on v.custom_field_id = f.id inner join searchbox box on box.id = $browsecatmode and find_in_set(f.id, box.custom_fields) where torrent_id = $torrentId"); + $values = []; $result = []; while ($row = mysql_fetch_assoc($res)) { - if ($row['custom_field_type'] == self::TYPE_CHECKBOX) { - $result[$row['custom_field_id']][] = $row['custom_field_value']; - } else { - $result[$row['custom_field_id']] = $row['custom_field_value']; + $typeInfo = self::$types[$row['type']]; + if ($typeInfo['has_option']) { + $options = preg_split('/[\r\n]+/', $row['options']); + $optionsArr = []; + foreach ($options as $option) { + $pos = strpos($option, '|'); + $value = substr($option, 0, $pos); + $label = substr($option, $pos + 1); + $optionsArr[$value] = $label; + } + $row['options'] = $optionsArr; } + $result[$row['id']] = $row; + if ($typeInfo['is_value_multiple']) { + $values[$row['id']][] = $row['custom_field_value']; + } else { + $values[$row['id']] = $row['custom_field_value']; + } + } + foreach ($result as &$value) { + $value['custom_field_value'] = $values[$value['id']]; } return $result; } + public function renderTorrentDetailPageMixed($torretnId) + { + global $browsecatmode; + $displayName = get_searchbox_value($browsecatmode, 'custom_fields_display_name'); + $displayOrder = get_searchbox_value($browsecatmode, 'custom_fields_display_order'); + $customFields = $this->listTorrentCustomField($torretnId); + $mixedRowContent = nl2br($displayOrder); + $rowByRowHtml = ''; + foreach ($customFields as $field) { + $content = ''; + $fieldValue = $field['custom_field_value']; + $typeInfo = self::$types[$field['type']]; + switch ($field['type']) { + case self::TYPE_TEXT: + case self::TYPE_TEXTAREA: + case self::TYPE_FILE: + $content .= format_comment($fieldValue); + break; + case self::TYPE_IMAGE: + if (substr($fieldValue, 0, 4) == 'http') { + $content .= formatImg($fieldValue, true, 700, 0, "attach{$field['id']}"); + } else { + $content .= format_comment($fieldValue); + } + break; + case self::TYPE_RADIO: + case self::TYPE_CHECKBOX: + case self::TYPE_SELECT; + $fieldContent = []; + foreach ((array)$fieldValue as $item) { + $fieldContent[] = $field['options'][$item] ?? ''; + } + $content .= implode(' ', $fieldContent); + break; + default: + break; + } + $mixedRowContent = str_replace("<%{$field['name']}.label%>", $field['label'], $mixedRowContent); + $mixedRowContent = str_replace("<%{$field['name']}.value%>", $content, $mixedRowContent); + if ($field['is_single_row']) { + $rowByRowHtml .= tr($field['label'], $content, 1); + } + } + $result = $rowByRowHtml; + if (!empty($mixedRowContent)) { + $result .= tr($displayName, $mixedRowContent, 1); + } + return $result; + } + + } \ No newline at end of file diff --git a/public/catmanage.php b/public/catmanage.php index 03c2f363..785f9980 100644 --- a/public/catmanage.php +++ b/public/catmanage.php @@ -233,10 +233,14 @@ function print_category_editor($type, $row='') } tr($lang_catmanage['row_searchbox_name']."*", " " . $lang_catmanage['text_searchbox_name_note'], 1); tr($lang_catmanage['row_show_sub_category'], " " . $lang_catmanage['text_sources'] . " " . $lang_catmanage['text_media'] . " " . $lang_catmanage['text_codecs'] . " " . $lang_catmanage['text_standards'] . " " . $lang_catmanage['text_processings'] . " " . $lang_catmanage['text_teams'] . " " . $lang_catmanage['text_audio_codecs']."
".$lang_catmanage['text_show_sub_category_note'], 1); - $field = new \Nexus\Field\Field(); - tr('显示自字义字段', $field->buildFieldCheckbox('custom_fields[]', $row['custom_fields']), 1); tr($lang_catmanage['row_items_per_row']."*", " " . $lang_catmanage['text_items_per_row_note'], 1); tr($lang_catmanage['row_padding_between_items']."*", " " . $lang_catmanage['text_padding_between_items_note'], 1); + $field = new \Nexus\Field\Field(); + tr('启用自字义字段', $field->buildFieldCheckbox('custom_fields[]', $row['custom_fields'] ?? ''), 1); + tr('自定义字段显示名称', '', 1); + $helpText = '
使用标签代表字段,如某字段其 Name 为 artist,则它的标签为:<%artist%>'; + $helpText .= '
仅针对非单独占一行的字段有效'; + tr('自定义字段显示顺序', '' . $helpText, 1); } elseif ($type=='caticon') { @@ -703,6 +707,8 @@ elseif($action == 'submit') $updateset[] = "showteam=".sqlesc($showteam); $updateset[] = "showaudiocodec=".sqlesc($showaudiocodec); $updateset[] = "custom_fields=" . sqlesc(implode(',', $_POST['custom_fields'] ?? [])); + $updateset[] = "custom_fields_display_name=" . sqlesc($_POST['custom_fields_display_name'] ?? ''); + $updateset[] = "custom_fields_display_order=" . sqlesc($_POST['custom_fields_display_order'] ?? ''); if ($showsource || $showmedium || $showcodec || $showstandard || $showprocessing || $showteam || $showaudiocodec) $updateset[] = "showsubcat=1"; else diff --git a/public/details.php b/public/details.php index c1b7710c..d46530c9 100644 --- a/public/details.php +++ b/public/details.php @@ -5,6 +5,7 @@ dbconn(); require_once(get_langfile_path()); loggedinorreturn(); $id = intval($_GET["id"] ?? 0); +$customField = new \Nexus\Field\Field(); int_check($id); if (!isset($id) || !$id) @@ -153,6 +154,11 @@ else { print("\n"); // ---------------- end subtitle block -------------------// + /**************start custom fields****************/ + echo $customField->renderTorrentDetailPageMixed($id); + + /**************end custom fields****************/ + if ($CURUSER['showdescription'] != 'no' && !empty($row["descr"])){ $torrentdetailad=$Advertisement->get_ad('torrentdetail'); tr("\"Show/Hide\" ".$lang_details['row_description']."", "
".($Advertisement->enable_ad() && $torrentdetailad ? "
".$torrentdetailad[0]."
" : "").format_comment($row["descr"])."
", 1);