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 = << +

{$lang_fields['text_field']}

+
+
+ + + {$trName} + {$trLabel} + {$trType} + {$trRequired} + {$trHelp} + {$trOptions} +
+
+
+ +
+
+ +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('', $value); + } + $table .= ''; + foreach ($rows as $row) { + $table .= ''; + foreach ($header as $headerKey => $headerValue) { + $table .= sprintf('', $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']} - +
+ + {$lang_fields['text_manage']} + + + + {$lang_fields['text_add']} + +
+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 zyaBby!t=jNaEvJIY#!pn9nBsO^wYjOnKcBz)pGmaw)We~q`m7FbJiC?9y(3=U58^; zCMt6(?p6^wbg9zkC(?=0N*aqg4{Fs9o-0ph`RxbW?wHu@SYgs#mg_=$W3?Z@35lQ+ zTz(B)$n)xcb3N*{+nsiM|8768y-Rvp(uqy~uK#9`rMVSkMBrd;f)m=uCd_m0*aa3w z!PU}Naly*Ft@B2oDm8P`eN$w%v+g)8m3dt3P>?9rrLZ5VaUHEAWRIq`N4#Z@2_BA= zr{Vsr^}RJa{ioq+W_paV*fwK&YNGe9>Bf(>zauJ+$odS6!MWJKR^A)6pe zv96mC2p61yHMVx2UCJW3|3?yyoO69tGIgJzHI>^XuR-wf_Bbz8Qdx(upe)96QvUEz z2Iz@tMg-Gpc!E7)bdqYu5oC;3WIxsHsicTmH8CkEWHb0S3I>U}N$x*NrB?LoZfWJ@ z>_%*>8QZM>n4)^-r_9h>Q6!(S8n4jMCXoq5ersIR600@6Zddj`7IR*tv)TF-2Tw*{ zfv(o?ANk5(t<9#S;vu}Qtr?n==a z>7wuWY;}pNt3mSVi=yI56SR2uxxC@sdYQW5b$er4x}&fP7hEQ|vtlX9mm~JP$3D=#oZc+T)m5EA>Ym9Qh+>Hf zWyDUBtc6VSB@Tr$F)>F3oefDD;RD-B`(J@Rx}F9RE8}lmYWAE%d^Ph=Mp8q6ghsr8 z+BlaEu984k9SQ|$`R<;U2gJACCh=N{Z~{sjF@6#TIfGMuu!b-g)tjwIQ)ofr`b)>;*L{d z7k^|=@m>j(a;A*&%}ps~jVL}tE+xT~5FJ7j6&}{ zOfY;Lb$und?~{cNV)T`TM=!0(KJVWxw5{k=!`b;Z6IIZmNQAooZL;FyVR~F^VN|H1 zprM=QRG(5cBr@8m2IkPE8jLG`Cgx#)E2ghq#W-v44B@Q_O2zyfc_E_3nn}yJ;so^P z1&=2Ws;Y$>F7bxj&||psKg>vFSZwg}W8-Fc>a#suCXGuz$usF2c@MGk`~Bmokx#@W%x2jr+VcOzS9H|}0g!nN^kyoRwSb%bUo1>0Zu?G!hSKhsM& zZi#0?&RYU=+P&p84g?iS;<9U3T&1a?N4SqwmZFQ2n;vNRdOuAk#2#NCD4q1R4EVz8 zL}6;UzME0XYUM9si={O{Mbxgm4)Yr;udX^C{Av97^2*y=+fO$`gbx;%_V$o= zksLLz%v6lkGRP1P&B+1EyZhj42m!~`({=c`Xeu%d2pI(ekJnlLZjfA#D_w-(pm-8r3oThkojDlhMnFU>I& zrgp)CbdqVn+w_?YQ&H_oyo>-dcTzupU|;*~-sR;dI!*TIzzlWev`*G4qP?8sGyY$& z$0;)J@Z9`ZS^Rgs)j`3A0KLl8-s)7=x29DRZIeTv^pa6ZVi#%72`nLT6icX~yUj04 zDpa=GuDS3IBgL#OCjI*(RwLT|o{KpBF^oY`XN^?fSzP~m z{bLn(Qc4QXEGhuJSCJY)iN+~d)jofIEmIay@ zou^_7^a{rFFBr(U)|qXZTfwNCLQuSIMuL1r$mIS3!eOT2gYEAyp1p22%>RwnOa znAqsCyNv#2`^v_~i*$7a0`d3vckM`vN?SIyyw^MWu%WU6ProR>Q9q&mj9jEYnv?#W zk7jg^x6@?FFiDGI#FxL$H?5Rp1}N?!`uy{>Ng@~%j3D>m)a!Qb~p8Ix4!LIkalT!Q8^4>u~@1=Zs|ZGRn( zi|dJSEXYw3Oe}8no0AZqe)E$tVf+@VOdR&Ct@ZAl66Tm{z*qkvl==t7Lg3UK3-y6yws)MJ*h*2!jcOAQ4Itd5_ z5C4l+gzIs@PWU~UVUY2LlG3=V*Y(&~I}olp*G*32N=DC3usUyb%k)H2vIKNzPoRSM z70Fx|`px*gVCkRo`Em33`mZK&&2jL|Ww-d>v)KYlVtKKho=#L4ITPb5EM z`lrR1Uj*fqK$9i^>snqZK}%R_wj?vz=&!=5+|<0wVf2E?_(9f34%2myp7E9GTruDg ztb2eoID{)gSS`w<#gZc8bX703&IzvlI&iOPiOUg!c^*0{R>tdv;!=w^I>Z#hG1C3g z;wmK=`E7J%`ib09SWki~UkjzTn8XKF+!$A6`E^D~jbKUafMTJ(n2s#WX`-~!+F^Lc z4Z!0(*eBC7{H?=(4-w5wZaDtOsc&hWBp%DdW|lw zTfEvwicqa$`7)$UFJ=p9OQ&w?M^{$7+>jHD*FwYK(Pv97nb;r84?i{p?yHk_7kEYK z?Den%OS!QChLMj`Nj?@5ru|8U-^*-2NQ6)9_z*QOr|40$tc7>qk$Fl#O@L6pzcl#zcBS<_6~=G$ zF!u+8!NzXJ1XUNE>Oyo4r@Nt1Hugg?&LU#NeaVhPL%cQB$=jY6u9@}L7Gz)3NZP#_ zDpKBkqq*t%uUCQQ=DK&t=BDzd%>uX3$!>S?u4T1OsY>lD*c)Hg`0|A|$Q=1yZrrSP z*)F3iH#;jk3Mb?~;fpeh(PQI3gHuy~$aNGtKg@ft-gbc43YeqcjfeHJZ^rOShP=3b zL^7uy^1kHW8&Xhtr{eaCGxqJ3cbt@>Lxtg>2X4E43Pw>YFxjr9?1Y2_wfmC03zu1< znf{_gCbY@{`PhQd4B8<~2T!UKjCw7i|^e46H`xMM`1>rrxLS7KG8 zH!m$u-%|fH2)O#9&DCKIx)w$jBa!rPGQp0JDG^mtR z$4v2!KjXGj=irISWHMW9BusJR)s>IIE!HgKA#koXRwN&6H-45@s7z+F*2o8W;3dM%Y{QweuaMc8TVb)ZnSC
%s
%s