diff --git a/app/Models/SearchBox.php b/app/Models/SearchBox.php
index 57aa575e..5a5ddff7 100644
--- a/app/Models/SearchBox.php
+++ b/app/Models/SearchBox.php
@@ -2,6 +2,8 @@
namespace App\Models;
+use Illuminate\Database\Eloquent\Casts\Attribute;
+
class SearchBox extends NexusModel
{
protected $table = 'searchbox';
@@ -33,6 +35,21 @@ class SearchBox extends NexusModel
return $result;
}
+ public function getCustomFieldsAttribute($value): array
+ {
+ if (!is_array($value)) {
+ return explode(',', $value);
+ }
+ }
+
+ public function setCustomFieldsAttribute($value)
+ {
+ if (is_array($value)) {
+ $this->attributes['custom_fields'] = implode(',', $value);
+ }
+ }
+
+
public function categories(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(Category::class, 'mode');
diff --git a/app/Models/TorrentCustomField.php b/app/Models/TorrentCustomField.php
new file mode 100644
index 00000000..98068da2
--- /dev/null
+++ b/app/Models/TorrentCustomField.php
@@ -0,0 +1,15 @@
+privacy == "strong" || ($torrent && $torrent->anonymous == 'yes' && $user->id == $torrent->owner)) {
//用户强私密,或者种子作者匿名而当前项作者刚好为种子作者
+ $anonymousText = nexus_trans('label.anonymous');
if($authenticator->class >= $canViewAnonymousClass || $user->id == $authenticator->id) {
//但当前用户权限可以查看匿名者,或当前用户查看自己的数据,显示个匿名,后边加真实用户名
- return sprintf('匿名(%s)', $username);
+ return sprintf('%s(%s)', $anonymousText, $username);
} else {
- return '匿名';
+ return $anonymousText;
}
} else {
return $username;
diff --git a/database/migrations/2022_09_19_043749_add_display_to_torrents_custom_fields_table.php b/database/migrations/2022_09_19_043749_add_display_to_torrents_custom_fields_table.php
new file mode 100644
index 00000000..315d4abe
--- /dev/null
+++ b/database/migrations/2022_09_19_043749_add_display_to_torrents_custom_fields_table.php
@@ -0,0 +1,33 @@
+text('display')->nullable(true)->after('help');
+ $table->integer('priority')->default(0)->after('display');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('torrents_custom_fields', function (Blueprint $table) {
+ $table->dropColumn('display', 'priority');
+ });
+ }
+};
diff --git a/include/constants.php b/include/constants.php
index 77346b6d..b83eced9 100644
--- a/include/constants.php
+++ b/include/constants.php
@@ -1,6 +1,6 @@
'横向多选',
'field_type_select' => '下拉单选',
'field_type_image' => '图片',
+ 'col_display' => '自定义展示',
-];
\ No newline at end of file
+];
diff --git a/lang/cht/lang_fields.php b/lang/cht/lang_fields.php
index 8e3eea26..096544b9 100644
--- a/lang/cht/lang_fields.php
+++ b/lang/cht/lang_fields.php
@@ -25,5 +25,6 @@ $lang_fields = [
'field_type_radio' => '橫向單選',
'field_type_checkbox' => '橫向多選',
'field_type_select' => '下拉單選',
+ 'col_display' => '自定義展示',
-];
\ No newline at end of file
+];
diff --git a/lang/en/lang_fields.php b/lang/en/lang_fields.php
index d3bddc60..f0829af1 100644
--- a/lang/en/lang_fields.php
+++ b/lang/en/lang_fields.php
@@ -26,5 +26,6 @@ $lang_fields = [
'field_type_checkbox' => 'Horizontal multiple select',
'field_type_select' => 'Vertical single select',
'field_type_image' => 'Image',
+ 'col_display' => 'Custom display',
-];
\ No newline at end of file
+];
diff --git a/nexus/Field/Field.php b/nexus/Field/Field.php
index a467dc3b..8ca7cc18 100644
--- a/nexus/Field/Field.php
+++ b/nexus/Field/Field.php
@@ -2,6 +2,10 @@
namespace Nexus\Field;
+use App\Models\SearchBox;
+use App\Models\TorrentCustomField;
+use App\Models\TorrentCustomFieldValue;
+use Elasticsearch\Endpoints\Search;
use Nexus\Database\NexusDB;
class Field
@@ -86,7 +90,7 @@ class Field
function buildFieldForm(array $row = [])
{
- global $lang_fields, $lang_functions;
+ global $lang_fields, $lang_functions, $lang_catmanage;
$trName = tr($lang_fields['col_name'] . '*', ' ' . $lang_fields['col_name_help'], 1, '', true);
$trLabel = tr($lang_fields['col_label'] . '*', '', 1, '', true);
$trType = tr($lang_fields['col_type'] . '*', $this->radio('type', $this->getTypeRadioOptions(), $row['type'] ?? null), 1, '', true);
@@ -94,6 +98,9 @@ class Field
$trHelp = tr($lang_fields['col_help'], '', 1, '', true);
$trOptions = tr($lang_fields['col_options'], '
' . $lang_fields['col_options_help'], 1, '', true);
$trIsSingleRow = tr($lang_fields['col_is_single_row'] . '*', $this->radio('is_single_row', ['0' => $lang_functions['text_no'], '1' => $lang_functions['text_yes']], $row['is_single_row'] ?? null), 1, '', true);
+ $trPriority = tr(nexus_trans('label.priority') . '*', '', 1, '', true);
+ $trDisplay = tr($lang_fields['col_display'], '
' . $lang_catmanage['row_custom_field_display_help'], 1, '', true);
+
$id = $row['id'] ?? 0;
$form = <<
@@ -109,6 +116,8 @@ class Field
{$trHelp}
{$trOptions}
{$trIsSingleRow}
+ {$trPriority}
+ {$trDisplay}
@@ -126,7 +135,7 @@ HTML;
$perPage = 10;
$total = get_row_count('torrents_custom_fields');
list($paginationTop, $paginationBottom, $limit) = pager($perPage, $total, "?");
- $sql = "select * from torrents_custom_fields order by id asc $limit";
+ $sql = "select * from torrents_custom_fields order by priority desc $limit";
$res = sql_query($sql);
$header = [
'id' => $lang_fields['col_id'],
@@ -135,6 +144,7 @@ HTML;
'type_text' => $lang_fields['col_type'],
'required_text' => $lang_fields['col_required'],
'is_single_row_text' => $lang_fields['col_is_single_row'],
+ 'priority' => nexus_trans('label.priority'),
'action' => $lang_fields['col_action'],
];
$rows = [];
@@ -203,6 +213,8 @@ HEAD;
$attributes['help'] = $data['help'] ?? '';
$attributes['options'] = trim($data['options'] ?? '');
+ $attributes['display'] = trim($data['display'] ?? '');
+ $attributes['priority'] = trim($data['priority'] ?? '0');
$now = date('Y-m-d H:i:s');
$attributes['updated_at'] = $now;
$table = 'torrents_custom_fields';
@@ -252,24 +264,29 @@ HEAD;
}
- public function renderOnUploadPage($torrentId = 0)
+ public function renderOnUploadPage($torrentId = 0, $searchBoxId)
{
- global $browsecatmode;
- $searchBox = NexusDB::getOne('searchbox', "id = $browsecatmode");
+ $searchBox = NexusDB::getOne('searchbox', "id = $searchBoxId");
if (empty($searchBox)) {
- throw new \RuntimeException("Invalid search box: $browsecatmode");
+ throw new \RuntimeException("Invalid search box: $searchBoxId");
}
- $customValues = $this->listTorrentCustomField($torrentId);
- $sql = sprintf('select * from torrents_custom_fields where id in (%s)', $searchBox['custom_fields'] ?: 0);
+ $customValues = $this->listTorrentCustomField($torrentId, $searchBoxId);
+ $sql = sprintf('select * from torrents_custom_fields where id in (%s) order by priority desc', $searchBox['custom_fields'] ?: 0);
$res = sql_query($sql);
$html = '';
while ($row = mysql_fetch_assoc($res)) {
- $name = "custom_fields[{$row['id']}]";
+ $name = "custom_fields[$searchBoxId][{$row['id']}]";
$currentValue = $customValues[$row['id']]['custom_field_value'] ?? '';
+ $requireText = '';
+ if ($row['required']) {
+ $requireText = "*";
+ }
+ $trLabel = $row['label'] . $requireText;
+ $trRelation = "mode_$searchBoxId";
if ($row['type'] == self::TYPE_TEXT) {
- $html .= tr($row['label'], sprintf('', $name, $currentValue, '99%'), 1);
+ $html .= tr($trLabel, sprintf('', $name, $currentValue, '99%'), 1, $trRelation);
} elseif ($row['type'] == self::TYPE_TEXTAREA) {
- $html .= tr($row['label'], sprintf('', $name, '99%', $currentValue), 1);
+ $html .= tr($trLabel, sprintf('', $name, '99%', $currentValue), 1, $trRelation);
} elseif ($row['type'] == self::TYPE_RADIO || $row['type'] == self::TYPE_CHECKBOX) {
if ($row['type'] == self::TYPE_CHECKBOX) {
$name .= '[]';
@@ -293,7 +310,7 @@ HEAD;
$row['type'], $name, $value, $checked, $label
);
}
- $html .= tr($row['label'], $part, 1);
+ $html .= tr($trLabel, $part, 1, $trRelation);
} elseif ($row['type'] == self::TYPE_SELECT) {
$part = '';
- $html .= tr($row['label'], $part, 1);
+ $html .= tr($trLabel, $part, 1, $trRelation);
} elseif ($row['type'] == self::TYPE_IMAGE) {
$callbackFunc = "preview_custom_field_image_" . $row['id'];
$iframeId = "iframe_$callbackFunc";
@@ -351,18 +368,14 @@ HEAD;
}
JS;
- $html .= tr($row['label'], $y, 1);
+ $html .= tr($trLabel, $y, 1, $trRelation, true);
}
}
return $html;
}
- public function listTorrentCustomField($torrentId, $searchBoxId = 0)
+ public function listTorrentCustomField($torrentId, $searchBoxId)
{
- global $browsecatmode;
- if ($searchBoxId <= 0) {
- $searchBoxId = $browsecatmode;
- }
//suppose torrentId is array
$isArray = true;
$torrentIdArr = $torrentId;
@@ -371,7 +384,7 @@ JS;
$torrentIdArr = [$torrentId];
}
$torrentIdStr = implode(',', $torrentIdArr);
- $res = sql_query("select f.*, v.custom_field_value, v.torrent_id 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 = $searchBoxId and find_in_set(f.id, box.custom_fields) where torrent_id in ($torrentIdStr)");
+ $res = sql_query("select f.*, v.custom_field_value, v.torrent_id 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 = $searchBoxId and find_in_set(f.id, box.custom_fields) where torrent_id in ($torrentIdStr) order by f.priority desc");
$values = [];
$result = [];
while ($row = mysql_fetch_assoc($res)) {
@@ -402,12 +415,11 @@ JS;
return $isArray ? $result : ($result[$torrentId] ?? []);
}
- public function renderOnTorrentDetailsPage($torrentId)
+ public function renderOnTorrentDetailsPage($torrentId, $searchBoxId)
{
- global $browsecatmode;
- $displayName = get_searchbox_value($browsecatmode, 'custom_fields_display_name');
- $customFields = $this->listTorrentCustomField($torrentId);
- $mixedRowContent = get_searchbox_value($browsecatmode, 'custom_fields_display');
+ $displayName = get_searchbox_value($searchBoxId, 'custom_fields_display_name');
+ $customFields = $this->listTorrentCustomField($torrentId, $searchBoxId);
+ $mixedRowContent = get_searchbox_value($searchBoxId, 'custom_fields_display');
$rowByRowHtml = '';
$shouldRenderMixRow = false;
foreach ($customFields as $field) {
@@ -422,8 +434,15 @@ JS;
$mixedRowContent = str_replace("<%{$field['name']}.label%>", $field['label'], $mixedRowContent);
$mixedRowContent = str_replace("<%{$field['name']}.value%>", $contentNotFormatted, $mixedRowContent);
if ($field['is_single_row']) {
- $contentFormatted = $this->formatCustomFieldValue($field, true);
- $rowByRowHtml .= tr($field['label'], $contentFormatted, 1);
+ if (!empty($field['display'])) {
+ $customFieldDisplay = $field['display'];
+ $customFieldDisplay = str_replace("<%{$field['name']}.label%>", $field['label'], $customFieldDisplay);
+ $customFieldDisplay = str_replace("<%{$field['name']}.value%>", $contentNotFormatted, $customFieldDisplay);
+ $rowByRowHtml .= tr($field['label'], format_comment($customFieldDisplay, false), 1);
+ } else {
+ $contentFormatted = $this->formatCustomFieldValue($field, true);
+ $rowByRowHtml .= tr($field['label'], $contentFormatted, 1);
+ }
}
}
@@ -443,13 +462,13 @@ JS;
switch ($customFieldWithValue['type']) {
case self::TYPE_TEXT:
case self::TYPE_TEXTAREA:
- $result .= $doFormatComment ? format_comment($fieldValue) : $fieldValue;
+ $result .= $doFormatComment ? format_comment($fieldValue, false) : $fieldValue;
break;
case self::TYPE_IMAGE:
if (substr($fieldValue, 0, 4) == 'http') {
$result .= $doFormatComment ? formatImg($fieldValue, true, 700, 0, "attach{$customFieldWithValue['id']}") : $fieldValue;
} else {
- $result .= $doFormatComment ? format_comment($fieldValue) : $fieldValue;
+ $result .= $doFormatComment ? format_comment($fieldValue, false) : $fieldValue;
}
break;
case self::TYPE_RADIO:
@@ -492,6 +511,32 @@ JS;
}
+ public function saveFieldValues($searchBoxId, $torrentId, array $data)
+ {
+ $searchBox = SearchBox::query()->findOrFail($searchBoxId);
+ $enabledFields = TorrentCustomField::query()->find($searchBox->custom_fields);
+ $insert = [];
+ $now = now();
+ foreach ($enabledFields as $field) {
+ if (empty($data[$field->id])) {
+ if ($field->required) {
+// throw new \InvalidArgumentException(nexus_trans("nexus.require_argument", ['argument' => $field->label]));
+ do_log("Field: {$field->label} required, but empty");
+ }
+ continue;
+ }
+ $insert[] = [
+ 'torrent_id' => $torrentId,
+ 'custom_field_id' => $field->id,
+ 'custom_field_value' => $data[$field->id],
+ 'created_at' => $now,
+ 'updated_at' => $now,
+ ];
+ }
+ TorrentCustomFieldValue::query()->where('torrent_id', $torrentId)->delete();
+ TorrentCustomFieldValue::query()->insert($insert);
+ }
+
}
diff --git a/public/details.php b/public/details.php
index e1ca5a2a..5ed0672c 100644
--- a/public/details.php
+++ b/public/details.php
@@ -278,7 +278,7 @@ JS;
do_action('torrent_detail_before_desc', $row['id'], $CURUSER['id']);
/**************start custom fields****************/
- echo $customField->renderOnTorrentDetailsPage($id);
+ echo $customField->renderOnTorrentDetailsPage($id, $row['search_box_id']);
/**************end custom fields****************/
diff --git a/public/edit.php b/public/edit.php
index f490bd8a..a2a64a57 100644
--- a/public/edit.php
+++ b/public/edit.php
@@ -67,8 +67,6 @@ else {
echo $ptGen->renderUploadPageFormInput($row['pt_gen']);
}
- $customField->renderOnUploadPage($id);
-
if ($enablenfo_main=='yes')
tr($lang_edit['row_nfo_file'], "".$lang_edit['radio_keep_current'].
"".$lang_edit['radio_remove'].
@@ -81,7 +79,7 @@ else {
tr($lang_functions['text_technical_info'], '
' . $lang_functions['text_technical_info_help_text'], 1);
}
- $s = "