From 16bd7ac76d01424d9b6463673cc98b7d956ec9b4 Mon Sep 17 00:00:00 2001
From: xiaomlove <353856593@qq.com>
Date: Tue, 2 Mar 2021 21:03:02 +0800
Subject: [PATCH] field basic
---
include/functions.php | 11 ++-
lang/chs/lang_fields.php | 21 +++++
nexus/Database/DB.php | 14 ++++
nexus/Field/Field.php | 160 +++++++++++++++++++++++++++++++++++++
public/fields.php | 69 ++++++++++++++++
public/pic/chrome-logo.svg | 1 +
public/pic/firefox.png | Bin 0 -> 4044 bytes
public/takeupload.php | 2 +-
8 files changed, 273 insertions(+), 5 deletions(-)
create mode 100644 lang/chs/lang_fields.php
create mode 100644 nexus/Field/Field.php
create mode 100644 public/fields.php
create mode 100644 public/pic/chrome-logo.svg
create mode 100644 public/pic/firefox.png
diff --git a/include/functions.php b/include/functions.php
index 1e535c3c..085a33d0 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -1253,11 +1253,14 @@ function allowedemails()
function redirect($url)
{
+ if (substr($url, 0, 4) != 'http') {
+ $url = getSchemeAndHttpHost() . '/' . trim($url, '/');
+ }
if(!headers_sent()){
- header("Location : $url");
- }
- else
- echo "";
+ header("Location: $url", true, 302);
+ } else {
+ echo "";
+ }
exit;
}
diff --git a/lang/chs/lang_fields.php b/lang/chs/lang_fields.php
new file mode 100644
index 00000000..6bf717fb
--- /dev/null
+++ b/lang/chs/lang_fields.php
@@ -0,0 +1,21 @@
+ '字段管理',
+ 'text_manage' => '管理',
+ 'text_add' => '添加',
+ 'text_field' => '字段',
+ 'text_delete' => '删除',
+ 'text_edit' => '编辑',
+ 'col_id' => 'ID',
+ 'col_name' => 'Name',
+ 'col_label' => '显示标签',
+ 'col_type' => '类型',
+ 'col_required' => '不能为空',
+ 'col_help' => '辅助说明',
+ 'col_options' => '选项',
+ 'col_action' => '操作',
+ 'js_sure_to_delete_this' => '你确信要删除此项目吗?',
+ 'submit_submit' => '提交'
+
+];
\ No newline at end of file
diff --git a/nexus/Database/DB.php b/nexus/Database/DB.php
index 3d59e62a..8060185d 100644
--- a/nexus/Database/DB.php
+++ b/nexus/Database/DB.php
@@ -150,4 +150,18 @@ class DB
return mysql_insert_id();
}
+ public static function update($table, $data, $whereStr)
+ {
+ if (empty($table) || empty($data) || !is_array($data) || empty($whereStr)) {
+ throw new DatabaseException("require table and data(array) and whereStr.");
+ }
+ $updateArr = [];
+ foreach ($data as $field => $value) {
+ $updateArr[] = "`$field` = " . sqlesc($value);
+ }
+ $sql = sprintf("update `%s` set %s where %s", $table, implode(', ', $updateArr), $whereStr);
+ sql_query($sql);
+ return mysql_affected_rows();
+ }
+
}
\ No newline at end of file
diff --git a/nexus/Field/Field.php b/nexus/Field/Field.php
new file mode 100644
index 00000000..2d70310f
--- /dev/null
+++ b/nexus/Field/Field.php
@@ -0,0 +1,160 @@
+ '短文本',
+ self::TYPE_TEXTAREA => '长文本',
+ self::TYPE_RADIO => '横向单选',
+ self::TYPE_CHECKBOX => '横向多选',
+ self::TYPE_SELECT => '下拉单选',
+ self::TYPE_FILE => '文件',
+ ];
+
+ public function radio($name, $options, $current = null)
+ {
+ $arr = [];
+ foreach ($options as $value => $label) {
+ $arr[] = sprintf(
+ '',
+ $name, $value, (string)$current === (string)$value ? ' checked' : '', $label
+ );
+ }
+ return implode('', $arr);
+ }
+
+ function buildFieldForm(array $row = [])
+ {
+ 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);
+ $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);
+ $id = $row['id'] ?? 0;
+ $form = <<
+
+
+
+HTML;
+ return $form;
+ }
+
+ function buildFieldTable()
+ {
+ global $lang_fields;
+ $sql = 'select * from torrents_custom_fields';
+ $res = sql_query($sql);
+ $header = [
+ 'id' => $lang_fields['col_id'],
+ 'name' => $lang_fields['col_name'],
+ 'label' => $lang_fields['col_label'],
+ 'type' => $lang_fields['col_type'],
+ 'required_text' => $lang_fields['col_required'],
+ 'action' => $lang_fields['col_action'],
+ ];
+ $rows = [];
+ while ($row = mysql_fetch_assoc($res)) {
+ $row['required_text'] = $row['required'] ? '是' : '否';
+ $row['action'] = sprintf(
+ "%s | %s",
+ $row['id'], $lang_fields['js_sure_to_delete_this'], $lang_fields['text_delete'], $row['id'], $lang_fields['text_edit']
+ );
+ $rows[] = $row;
+ }
+ $table = $this->buildTable($header, $rows);
+ return $table;
+ }
+
+ public function save($data)
+ {
+ $attributes = [];
+ if (empty($data['name'])) {
+ throw new \InvalidArgumentException("Name 必须");
+ }
+ if (!preg_match('/^\w+$/', $data['name'])) {
+ throw new \InvalidArgumentException("Name 非法");
+ }
+ $attributes['name'] = $data['name'];
+
+ if (empty($data['label'])) {
+ throw new \InvalidArgumentException("显示标签 必须");
+ }
+ $attributes['label'] = $data['label'];
+
+ if (empty($data['type'])) {
+ throw new \InvalidArgumentException("类型 必须");
+ }
+ if (!isset(self::$types[$data['type']])) {
+ throw new \InvalidArgumentException("类型 非法");
+ }
+ $attributes['type'] = $data['type'];
+
+ if (!isset($data['required'])) {
+ throw new \InvalidArgumentException("不能为空 必须");
+ }
+ if (!in_array($data['required'], ["0", "1"], true)) {
+ throw new \InvalidArgumentException("不能为空 非法");
+ }
+ $attributes['required'] = $data['required'];
+
+ $attributes['help'] = $data['help'] ?? '';
+ $attributes['options'] = trim($data['options'] ?? '');
+ $now = date('Y-m-d H:i:s');
+ $attributes['updated_at'] = $now;
+ $table = 'torrents_custom_fields';
+ if (!empty($data['id'])) {
+ $result = DB::update($table, $attributes, "id = " . sqlesc($data['id']));
+ } else {
+ $attributes['created_at'] = $now;
+ $result = DB::insert($table, $attributes);
+ }
+ return $result;
+ }
+
+ public function buildTable(array $header, array $rows)
+ {
+ $table = '';
+ foreach ($header as $key => $value) {
+ $table .= sprintf('| %s | ', $value);
+ }
+ $table .= '
';
+ foreach ($rows as $row) {
+ $table .= '';
+ foreach ($header as $headerKey => $headerValue) {
+ $table .= sprintf('| %s | ', $row[$headerKey] ?? '');
+ }
+ $table .= '
';
+ }
+ $table .= '';
+ return $table;
+ }
+}
\ No newline at end of file
diff --git a/public/fields.php b/public/fields.php
new file mode 100644
index 00000000..8c2a74bc
--- /dev/null
+++ b/public/fields.php
@@ -0,0 +1,69 @@
+{$lang_fields['field_management']} -
+
+HEAD;
+ return $head;
+}
+
+
+
+$action = $_GET['action'] ?? 'view';
+if ($action == 'view') {
+ stdhead($lang_fields['field_management']." - ".$lang_fields['text_field']);
+ begin_main_frame();
+ echo buildTableHead();
+ echo $field->buildFieldTable();
+} elseif ($action == 'add') {
+ stdhead($lang_fields['field_management']." - ".$lang_fields['text_add']);
+ begin_main_frame();
+ echo $field->buildFieldForm();
+} elseif ($action == 'submit') {
+ try {
+ $result = $field->save($_REQUEST);
+ redirect('fields.php?action=view&type=');
+ } catch (\Exception $e) {
+ stderr($lang_fields['field_management']." - ".$lang_fields['text_field'], $e->getMessage());
+ }
+} elseif ($action == 'edit') {
+ $id = intval($_GET['id'] ?? 0);
+ if ($id == 0) {
+ stderr($lang_fields['field_management'], "invalid id");
+ }
+ $sql = "select * from torrents_custom_fields where id = $id";
+ $res = sql_query($sql);
+ $row = mysql_fetch_assoc($res);
+ if (empty($row)) {
+ stderr('', 'invlaid id');
+ }
+ stdhead($lang_fields['field_management']." - ".$lang_fields['text_edit']);
+ begin_main_frame();
+ echo $field->buildFieldForm($row);
+}
+
+
+
diff --git a/public/pic/chrome-logo.svg b/public/pic/chrome-logo.svg
new file mode 100644
index 00000000..5a3fc4bb
--- /dev/null
+++ b/public/pic/chrome-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/pic/firefox.png b/public/pic/firefox.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e812a90f131c9e80eea9b043bb10d5be895af2a
GIT binary patch
literal 4044
zcmd5<`8O1P8y#kBWB0X|kX^_&7-NKKOfyU}wuCf9*|(6CFk{WG5FtX52-&HavC9^U
zvWKD=qAbPd?az46x#v0eo_o$c&pqe)wGKgSI}28Tc(+yp$<5&~g@{p0HF(0{Yt
zbVnBgVLq@RTATcnQUa*|H+*vr_{!z~Z>zsq1|UTpOyj@@{IWzCh(WLL_^t~1fnwto
z_zf^e0CYW2WdQOuR=EAZG9E1A*F-(HGSSPN0Y^pRU>XaS@Q2=pAn(Kqm;YC;0FWhe
zu$Z*(;s6#gV8x^k^{Gs4
z`Ck#Bivt%Cz*HaL41l@bB~%Tt)cLD<9-K7t`v8{Ckw
z$Grxfcu*$|^8QP<-ETlGyID_s5w+itu>;Sv0bLoiDu8fFKs_GpuvVeF;HA;DciQ5p
z1qa4VK)=BeT_1SqfHa{<`|TI!HXSYcX84^Bv(AITbD&kv%VFLf+XHF|N6xw+3IQ_t
zvq}58XTPOjmmANHC1}47#*UEnn%0D`eLHdKPprjJ5%H*u08&sOTL%oN1zRjMT6Kmi
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