BioTorrents.de’s version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

torrent_form.class.NEW.2020-12-10.php 41KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494
  1. <?php
  2. #declare(strict_types=1);
  3. // This class is used in upload.php to display the upload form, and the edit
  4. // section of torrents.php to display a shortened version of the same form
  5. class TorrentForm
  6. {
  7. public $UploadForm = '';
  8. public $Categories = [];
  9. /**
  10. * This kind of stuff will eventually go away.
  11. * The goal is to loop through multidimensional $ENV objects,
  12. * recursively copying parts to arrays in place as needed.
  13. */
  14. # Platforms
  15. # See classes/config.php
  16. public $SeqPlatforms = [];
  17. public $GraphPlatforms = [];
  18. public $ImgPlatforms = [];
  19. public $DocPlatforms = [];
  20. public $RawPlatforms = [];
  21. #public $Media = [];
  22. #public $MediaManga = [];
  23. # Formats
  24. # See classes/config.php
  25. public $SeqFormats = [];
  26. public $ProtFormats = [];
  27. public $GraphXmlFormats = [];
  28. public $GraphTxtFormats = [];
  29. public $ImgFormats = [];
  30. public $MapVectorFormats = [];
  31. public $MapRasterFormats = [];
  32. public $BinDocFormats = [];
  33. public $CpuGenFormats = [];
  34. public $PlainFormats = [];
  35. #public $Containers = [];
  36. #public $ContainersGames = [];
  37. #public $ContainersProt = [];
  38. #public $ContainersExtra = [];
  39. # Misc
  40. public $Codecs = [];
  41. public $Archives = [];
  42. public $Resolutions = [];
  43. # Deprecated
  44. #public $Formats = [];
  45. #public $AudioFormats = [];
  46. #public $Bitrates = [];
  47. #public $Platform = [];
  48. # Gazelle
  49. public $NewTorrent = false;
  50. public $Torrent = [];
  51. public $Error = false;
  52. public $TorrentID = false;
  53. public $Disabled = '';
  54. public $DisabledFlag = false;
  55. public function __construct($Torrent = false, $Error = false, $NewTorrent = true)
  56. {
  57. # See classes/config.php
  58. global $UploadForm, $Categories, $TorrentID, $SeqPlatforms, $GraphPlatforms, $ImgPlatforms, $DocPlatforms, $RawPlatforms, $SeqFormats, $ProtFormats, $GraphXmlFormats, $GraphTxtFormats, $ImgFormats, $MapVectorFormats, $MapRasterFormats, $BinDocFormats, $CpuGenFormats, $PlainFormats, $Codecs, $Archives, $Resolutions;
  59. #global $UploadForm, $Categories, $Formats, $Bitrates, $Media, $MediaManga, $TorrentID, $Containers, $ContainersGames, $Codecs, $Resolutions, $AudioFormats, $Platform, $Archives, $ArchivesManga;
  60. # Gazelle
  61. $this->NewTorrent = $NewTorrent;
  62. $this->Torrent = $Torrent;
  63. $this->Error = $Error;
  64. $this->UploadForm = $UploadForm;
  65. $this->Categories = $Categories;
  66. $this->TorrentID = $TorrentID;
  67. # Platforms
  68. # See classes/config.php
  69. $this->SeqPlatforms = $SeqPlatforms;
  70. $this->GraphPlatforms = $GraphPlatforms;
  71. $this->ImgPlatforms = $ImgPlatforms;
  72. $this->DocPlatforms = $DocPlatforms;
  73. $this->RawPlatforms = $RawPlatforms;
  74. #$this->Media = $Media;
  75. #$this->MediaManga = $MediaManga;
  76. # Formats
  77. # See classes/config.php
  78. $this->SeqFormats = $SeqFormats;
  79. $this->ProtFormats = $ProtFormats;
  80. $this->GraphXmlFormats = $GraphXmlFormats;
  81. $this->GraphTxtFormats = $GraphTxtFormats;
  82. $this->ImgFormats = $ImgFormats;
  83. $this->MapVectorFormats = $MapVectorFormats;
  84. $this->MapRasterFormats = $MapRasterFormats;
  85. $this->BinDocFormats = $BinDocFormats;
  86. $this->CpuGenFormats = $CpuGenFormats;
  87. $this->PlainFormats = $PlainFormats;
  88. #$this->Containers = $Containers;
  89. #$this->ContainersGames = $ContainersGames;
  90. #$this->ContainersProt = $ContainersProt;
  91. #$this->ContainersExtra = $ContainersExtra;
  92. # Misc
  93. $this->Codecs = $Codecs;
  94. $this->Archives = $Archives;
  95. $this->Resolutions = $Resolutions;
  96. # Deprecated
  97. #$this->ArchivesManga = $ArchivesManga;
  98. #$this->Formats = $Formats;
  99. #$this->AudioFormats = $AudioFormats;
  100. #$this->Bitrates = $Bitrates;
  101. #$this->Platform = $Platform;
  102. # Quick constructor test
  103. if ($this->Torrent && $this->Torrent['GroupID']) {
  104. $this->Disabled = ' readonly="readonly"';
  105. $this->DisabledFlag = true;
  106. }
  107. }
  108. /**
  109. * ========================
  110. * = New functional class =
  111. * ========================
  112. *
  113. * Contains functions that output discreet torrent form fields.
  114. * Useful for <?= echoing in skeleton tables in the sections.
  115. */
  116. /**
  117. * Upload form meta function
  118. *
  119. * Easily configure the form order and logic.
  120. * All the functions it calls emit a basic form element.
  121. */
  122. public function upload_form_v2()
  123. {
  124. $ENV = ENV::go();
  125. if ($this->NewTorrent) {
  126. echo $this->uploadNotice();
  127. echo $this->announceSource();
  128. echo $this->errorMessage();
  129. }
  130. echo $this->basicInfo();
  131. echo $this->head();
  132. # Start printing the form
  133. echo '<h2 class="header">Torrent Form</h2>';
  134. echo '<table class="torrent_form">';
  135. }
  136. /**
  137. * Upload notice
  138. *
  139. * Broken into multiple NewTorrent tests for sanity.
  140. * Each if statement should contain one discreet content block.
  141. */
  142. public function uploadNotice()
  143. {
  144. return $HTML = <<<HTML
  145. <aside class="upload_notice">
  146. <p>
  147. Please consult the
  148. <a href="/rules.php?p=upload">Upload Rules</a>
  149. and the
  150. <a href="/wiki.php?action=article&name=categories">Categories Wiki</a>
  151. to help fill out the upload form correctly.
  152. </p>
  153. <p>
  154. The site adds the Announce and Source automatically.
  155. Just download and seed the new torrent after uploading it.
  156. <!--
  157. <strong>
  158. If you never have before, be sure to read this list of
  159. <a href="wiki.php?action=article&name=uploadingpitfalls">uploading pitfalls</a>.
  160. </strong>
  161. -->
  162. </p>
  163. </aside>
  164. HTML;
  165. }
  166. /**
  167. * Announce URLs and Source
  168. *
  169. * Announce URLs displayed on the form.
  170. * They're added to torrents in torrentsdl.class.php.
  171. * Bio Gazelle supports tiered swarms, T1 private and T2 public.
  172. * The Source is randomized to ensure unique info hashes.
  173. */
  174. public function announceSource()
  175. {
  176. $Announces = ANNOUNCE_URLS[0];
  177. #$Announces = call_user_func_array('array_merge', ANNOUNCE_URLS);
  178. $TorrentPass = G::$LoggedUser['torrent_pass'];
  179. $HTML = '<aside class="announce_source">';
  180. foreach ($Announces as $Announce) {
  181. $HTML .= <<<HTML
  182. <p>
  183. <strong>Announce</strong>
  184. <input type="text"
  185. value="$Announce/$TorrentPass/announce"
  186. size="60" readonly="readonly"
  187. onclick="this.select();"/>
  188. </p>
  189. HTML;
  190. }
  191. /**
  192. * Source (randomize infohash)
  193. */
  194. $TorrentSource = Users::get_upload_sources()[0];
  195. $HTML .= <<<HTML
  196. <p>
  197. <strong>Source</strong>
  198. <input type="text"
  199. value="$TorrentSource"
  200. size="30" readonly="readonly"
  201. onclick="this.select();" />
  202. </p>
  203. HTML;
  204. $HTML .= '</aside>';
  205. return $HTML;
  206. }
  207. /**
  208. * Display torrent upload errors
  209. */
  210. public function errorMessage()
  211. {
  212. if ($this->Error) {
  213. return $HTML = <<<HTML
  214. <aside class="upload_error">
  215. <p>$this->Error</p>
  216. </aside>
  217. HTML;
  218. }
  219. }
  220. /**
  221. * head
  222. *
  223. * Everything until the catalogue number field.
  224. * Server-side torrent scrubbing admonishment.
  225. */
  226. public function head()
  227. {
  228. $ENV = ENV::go();
  229. G::$DB->query(
  230. "
  231. SELECT
  232. COUNT(`ID`)
  233. FROM
  234. `torrents`
  235. WHERE
  236. `UserID` = ".G::$LoggedUser['ID']
  237. );
  238. list($Uploads) = G::$DB->next_record();
  239. # Torrent form hidden values
  240. $AuthKey = G::$LoggedUser['AuthKey'];
  241. $HTML = <<<HTML
  242. <form class="create_form box pad" name="torrent" action="" enctype="multipart/form-data" method="post"
  243. onsubmit="$('#post').raw().disabled = 'disabled';">
  244. <input type="hidden" name="submit" value="true" />
  245. <input type="hidden" name="auth" value="$AuthKey" />
  246. HTML;
  247. if (!$this->NewTorrent) {
  248. # Edit form hidden fields
  249. $TorrentID = display_str($this->TorrentID);
  250. $CategoryID = display_str($this->Torrent['CategoryID'] - 1);
  251. $HTML .= <<<HTML
  252. <input type="hidden" name="action" value="takeedit" />
  253. <input type="hidden" name="torrentid" value="$TorrentID" />
  254. <input type="hidden" name="type" value="$CategoryID" />
  255. HTML;
  256. } # fi !NewTorrent
  257. else {
  258. # Torrent upload hidden fields
  259. if ($this->Torrent && $this->Torrent['GroupID']) {
  260. $GroupID = display_str($this->Torrent['GroupID']);
  261. $CategoryID = display_str($this->Torrent['CategoryID'] - 1);
  262. $HTML .= <<<HTML
  263. <input type="hidden" name="groupid" value="$GroupID" />
  264. <input type="hidden" name="type" value="$CategoryID" />
  265. HTML;
  266. }
  267. # Request hidden fields (new or edit?)
  268. if ($this->Torrent && ($this->Torrent['RequestID'] ?? false)) {
  269. $RequestID = display_str($this->Torrent['RequestID']);
  270. $HTML .= <<<HTML
  271. <input type="hidden" name="requestid"value="$RequestID" />
  272. HTML;
  273. }
  274. } # else
  275. /**
  276. * Start printing the torrent form
  277. */
  278. $HTML .= '<table class="torrent_form">';
  279. return $HTML;
  280. }
  281. /**
  282. * New torrent options: file
  283. */
  284. public function basicInfo()
  285. {
  286. $ENV = ENV::go();
  287. if ($this->NewTorrent) {
  288. $HTML = '<h2 class="header">Basic Info</h2>';
  289. $HTML .= <<<HTML
  290. <tr>
  291. <td>
  292. <label for="file_input" class="required">
  293. Torrent File
  294. </label>
  295. </td>
  296. <td>
  297. <input id="file" type="file" name="file_input" size="50" />
  298. <p>
  299. Set the private flag, e.g.,
  300. <code>mktorrent -p -a &lt;announce&gt; &lt;target folder&gt;</code>
  301. </p>
  302. </td>
  303. </tr>
  304. HTML;
  305. } # fi NewTorrent
  306. /**
  307. * New torrent options: category
  308. */
  309. if ($this->NewTorrent) {
  310. $DisabledFlag = ($this->DisabledFlag) ? ' disabled="disabled"' : '';
  311. $HTML .= <<<HTML
  312. <tr>
  313. <td>
  314. <label for="type" class="required">
  315. Category
  316. </label>
  317. </td>
  318. <td>
  319. <select id="categories" name="type" onchange="Categories()" $DisabledFlag>
  320. HTML;
  321. foreach ($ENV->CATS as $Cat) {
  322. $HTML .= "<option value='$Cat->ID'";
  323. if ($Cat->Name === $this->Torrent['CategoryName']) {
  324. $HTML .= ' selected="selected"';
  325. }
  326. $HTML .= ">$Cat->Name</option>";
  327. }
  328. $HTML .= <<<HTML
  329. </select>
  330. <p id="category_description" class="">
  331. <!-- $Cat->Description will live here -->
  332. Please see the
  333. <a href="https://dev.biotorrents.de/wiki.php?action=article&name=categories">Categories Wiki</a>
  334. for details
  335. </p>
  336. </td>
  337. </tr>
  338. </table>
  339. HTML;
  340. } # fi NewTorrent
  341. # Start the dynamic form
  342. $HTML .= '<div id="dynamic_form">';
  343. } # End basicInfo()
  344. /**
  345. * foot
  346. *
  347. * Make the endmatter.
  348. */
  349. public function foot()
  350. {
  351. $Torrent = $this->Torrent;
  352. echo '<table class="torrent_form>';
  353. /**
  354. * Freeleech type
  355. */
  356. if (!$this->NewTorrent) {
  357. if (check_perms('torrents_freeleech')) {
  358. echo <<<HTML
  359. <tr id="freetorrent">
  360. <td>
  361. <label for="freeleech">
  362. Freeleech
  363. </label>
  364. </td>
  365. <td>
  366. <select name="freeleech">
  367. HTML;
  368. $FL = ['Normal', 'Free', 'Neutral'];
  369. foreach ($FL as $Key => $Name) {
  370. $Selected = ($Key === $Torrent['FreeTorrent']) ? ' selected="selected"' : '';
  371. echo <<<HTML
  372. <option value="$Key" $Selected>
  373. $Name
  374. </option>
  375. HTML;
  376. }
  377. echo <<<HTML
  378. </select>
  379. because
  380. <select name="freeleechtype">
  381. HTML;
  382. /**
  383. * Freeleech reasons
  384. */
  385. $FL = array('N/A', 'Staff Pick', 'Perma-FL', 'Freeleechizer', 'Site-Wide FL');
  386. foreach ($FL as $Key => $Name) {
  387. $Selected = ($Key === $Torrent['FreeLeechType']) ? ' selected="selected"' : '';
  388. echo <<<HTML
  389. <option value="$Key?>" $Selected>
  390. $Name
  391. </option>
  392. HTML;
  393. }
  394. echo <<<HTML
  395. </select>
  396. </td>
  397. </tr>
  398. HTML;
  399. }
  400. } # fi !NewTorrent
  401. /**
  402. * Rules notice
  403. */
  404. echo <<<HTML
  405. <tr>
  406. <td>
  407. <aside class="torrent_upload">
  408. <p>
  409. Be sure that your torrent is approved by the
  410. <a href="rules.php?p=upload" target="_blank">rules</a>.
  411. Not doing this will result in a
  412. <strong class="important_text">warning</strong> or
  413. <strong class="important_text">worse</strong>.
  414. </p>
  415. HTML;
  416. # For new torrents only
  417. if ($this->NewTorrent) {
  418. echo <<<HTML
  419. <p>
  420. After uploading the torrent, you will have a one hour grace period.
  421. During this time only you can fill requests with this torrent.
  422. Make use of it wisely, and
  423. <a href="requests.php">search the list of requests</a>.
  424. </p>
  425. HTML;
  426. }
  427. echo '</aside></td></tr>';
  428. /**
  429. * Submit button
  430. */
  431. $Value = ($this->NewTorrent) ? 'Upload' : 'Edit';
  432. echo <<<HTML
  433. <tr>
  434. <td>
  435. <input id="post" type="submit" value="$Value" />
  436. </td>
  437. </tr>
  438. </table> <!-- torrent_form -->
  439. </form>
  440. </div> <!-- dynamic_form -->
  441. HTML;
  442. } # End foot()
  443. /**
  444. * upload_form
  445. *
  446. * Finally the "real" upload form.
  447. * Contains all the field you'd expect.
  448. *
  449. * This is currently one enormous function.
  450. * It has sub-functions, variables, and everything.
  451. * It continues to the end of the class.
  452. */
  453. public function upload_form()
  454. {
  455. $ENV = ENV::go();
  456. $QueryID = G::$DB->get_query_id();
  457. echo $this->head();
  458. echo $this->basicInfo();
  459. $Torrent = $this->Torrent;
  460. # Start printing the form
  461. echo '<h2 class="header">Torrent Form</h2>';
  462. echo '<table class="torrent_form">';
  463. /**
  464. * Accession Number
  465. *
  466. * The headings below refer to a new generic input schema.
  467. * The HTML labels and various user-visible text should come from $ENV.
  468. *
  469. * RecursiveArrayObject->toArray() returns arrays from, e.g., $ENV->A->B->C.
  470. * This makes it easy to get and program with any subset of config objects.
  471. */
  472. $CatalogueNumber = display_str($Torrent['CatalogueNumber']);
  473. $Disabled = $this->Disabled;
  474. # DOI
  475. echo <<<HTML
  476. <tr id="javdb_tr">
  477. <td>
  478. <label for="catalogue">
  479. Accession Number
  480. </label>
  481. </td>
  482. <td>
  483. <input type="text"
  484. id="catalogue" name="catalogue" size="30"
  485. placeholder="RefSeq and UniProt preferred"
  486. value="$CatalogueNumber" />
  487. <input type="button" autofill="jav" value="Autofill"
  488. style="pointer-events: none; opacity: 0.5;">
  489. </input>
  490. </td>
  491. </tr>
  492. HTML;
  493. # RefSeq
  494. $DisabledFlagInput = (!$this->DisabledFlag)
  495. ? '<input type="button" autofill="anime" value="Autofill" />'
  496. : null;
  497. echo <<<HTML
  498. <tr id="anidb_tr" class="hidden">
  499. <td>
  500. <label for="anidb">
  501. AniDB Autofill (optional)
  502. </label>
  503. </td>
  504. <td>
  505. <input type="text" id="anidb" size="10" $Disabled />
  506. $DisabledFlagInput
  507. </td>
  508. </tr>
  509. HTML;
  510. # UniProt
  511. $DisabledFlagInput = (!$this->DisabledFlag)
  512. ? '<input type="button" autofill="anime" value="Autofill" />'
  513. : null;
  514. echo <<<HTML
  515. <tr id="anidb_tr" class="hidden">
  516. <td>
  517. <label for="douj">
  518. e-hentai URL (optional)
  519. </label>
  520. </td>
  521. <td>
  522. <input type="text" id="douj" size="10" $Disabled />
  523. $DisabledFlagInput
  524. </td>
  525. </tr>
  526. HTML;
  527. /**
  528. * Semantic Version
  529. */
  530. $AudioFormat = display_str($Torrent['AudioFormat']);
  531. echo <<<HTML
  532. <tr id="audio_tr">
  533. <td>
  534. <label for="audioformat">
  535. Version
  536. </label>
  537. </td>
  538. <td>
  539. <input type="text"
  540. id="audioformat" name="audioformat"
  541. size="12" pattern="\d+\.*\d*\.*\d*"
  542. placeholder="Start with 0.1.0"
  543. value="$AudioFormat" />
  544. <p>
  545. Please see
  546. <a href="https://semver.org target=" _blank">Semantic Versioning</a>
  547. </p>
  548. </td>
  549. </tr>
  550. HTML;
  551. /**
  552. * Title fields
  553. *
  554. * Gazelle has three title fields available, regrettably hardcoded.
  555. * Ideally we could rank them in importance in the site ontology,
  556. * then update one config file to apply custom metadata across the board.
  557. */
  558. # New torrent upload
  559. if ($this->NewTorrent) {
  560. $Disabled = $this->Disabled;
  561. /**
  562. * Title 1
  563. */
  564. $Title1 = display_str($Torrent['Title']);
  565. echo <<<HTML
  566. <tr id="title_tr">
  567. <td>
  568. <label for="title" class="required">
  569. Torrent Title
  570. </label>
  571. </td>
  572. <td>
  573. <input type="text" id="title" name="title" size="60"
  574. placeholder="Definition line, e.g., Alcohol dehydrogenase ADH1"
  575. value="$Title1" $Disabled />
  576. </td>
  577. </tr>
  578. HTML;
  579. /**
  580. * Title 2
  581. */
  582. $Title2 = display_str($Torrent['Title2']);
  583. echo <<<HTML
  584. <tr id="title_rj_tr">
  585. <td>
  586. <label for="title_rj">
  587. Organism
  588. </label>
  589. </td>
  590. <td>
  591. <input type="text" id="title_rj" name="title_rj" size="60"
  592. placeholder="Organism line binomial, e.g., Saccharomyces cerevisiae"
  593. value="$Title2" $Disabled />
  594. </td>
  595. </tr>
  596. HTML;
  597. /**
  598. * Title 3
  599. */
  600. $Title3 = display_str($Torrent['TitleJP']);
  601. echo <<<HTML
  602. <tr id="title_jp_tr">
  603. <td>
  604. <label for="title_jp">
  605. Strain/Variety
  606. </label>
  607. </td>
  608. <td>
  609. <input type="text" id="title_jp" name="title_jp" size="60"
  610. placeholder="Organism line if any, e.g., S288C"
  611. value="$Title3" $Disabled />
  612. </td>
  613. </tr>
  614. HTML;
  615. } # fi NewTorrent
  616. /**
  617. * Creator(s)
  618. * CURRENTLY BROKEN
  619. *
  620. * Gazelle supports multiple creators per torrent.
  621. * One day I want to integrate the creator DB to join:
  622. * - DOI publication info in `torrents_screenshots`
  623. * - Attributions listed on the creator pages
  624. * - Stats about creator vs. total DOI citations
  625. */
  626. if ($this->NewTorrent) {
  627. # Useful variables
  628. $Disabled = $this->Disabled;
  629. $AutocompleteOption = Users::has_autocomplete_enabled('other');
  630. $AddRemoveBrackets = <<<HTML
  631. <a class="add_artist_button brackets" onclick="AddArtistField()">+</a>
  632. <a class="remove_artist_button brackets" onclick="RemoveArtistField()">&minus;</a>
  633. HTML;
  634. echo <<<HTML
  635. <tr id="artists_tr">
  636. <td>
  637. <label for="artistfields" class="required">
  638. Authors(s)
  639. </label>
  640. </td>
  641. <td id="artistfields">
  642. <p>
  643. One per field, e.g., Robert K. Mortimer [+] David Schild
  644. </p>
  645. HTML;
  646. # If there are already creators listed
  647. if (!empty($Torrent['Artists'])) {
  648. foreach ($Torrent['Artists'] as $Num => $Artist) {
  649. $ArtistName = display_str($Artist['name']);
  650. $AddRemoveBrackets = ($Num === 0) ?: null;
  651. echo <<<HTML
  652. <input type="text" id="artist_$Num" name="artists[]" size="45"
  653. value="$ArtistName" $AutocompleteOption $Disabled />
  654. $AddRemoveBrackets
  655. HTML;
  656. }
  657. } else {
  658. echo <<<HTML
  659. <input type="text" id="artist_0" name="artists[]" size="45"
  660. value="" $AutocompleteOption $Disabled />
  661. $AddRemoveBrackets
  662. HTML;
  663. }
  664. echo '</td></tr>';
  665. } # fi $NewTorrent
  666. /**
  667. * Affiliation
  668. *
  669. * The company, studio, lab, etc., that did the work.
  670. * todo: Add creator affiliation and pick a predetermined one
  671. * (in our case, last author's institution).
  672. */
  673. if ($this->NewTorrent) {
  674. $Affiliation = display_str($Torrent['Studio']);
  675. echo <<<HTML
  676. <tr id="studio_tr">
  677. <td>
  678. <label for="studio" class="required">
  679. Department/Lab
  680. </label>
  681. </td>
  682. <td>
  683. <input type="text" id="studio" name="studio" size="60"
  684. placeholder="Last author's institution, e.g., Lawrence Berkeley Laboratory"
  685. value="$Affiliation" $Disabled />
  686. </td>
  687. </tr>
  688. HTML;
  689. }
  690. /**
  691. * Location
  692. *
  693. * The location of the studio, lab, etc.
  694. * Currently not sanitized to a standard format.
  695. */
  696. if ($this->NewTorrent) {
  697. $TorrentLocation = display_str($Torrent['Series']);
  698. echo <<<HTML
  699. <tr id="series_tr">
  700. <td>
  701. <label for="series">
  702. Location
  703. </label>
  704. </td>
  705. <td>
  706. <input type="text" id="series" name="series" size="60"
  707. placeholder="Physical location, e.g., Berkeley, CA 94720"
  708. value="$TorrentLocation" $Disabled />
  709. </td>
  710. </tr>
  711. HTML;
  712. } # fi NewTorrent
  713. /**
  714. * ============================
  715. * = End if NewTorrent fields =
  716. * ============================
  717. */
  718. /**
  719. * Year
  720. */
  721. $TorrentYear = display_str($Torrent['Year']);
  722. echo <<<HTML
  723. <tr id="year_tr">
  724. <td>
  725. <label for="year" class="required">
  726. Year
  727. </label>
  728. </td>
  729. <td>
  730. <input type="text" id="year" name="year"
  731. maxlength="4" size="15" placeholder="Publication year"
  732. value="$TorrentYear" />
  733. </td>
  734. </tr>
  735. HTML;
  736. /**
  737. * Misc meta
  738. *
  739. * Used in OT Gazelle as Codec.
  740. * Used in Bio Gazelle as License.
  741. *
  742. * Unsure what to call the final field.
  743. * Some essential, specific one-off info.
  744. */
  745. echo <<<HTML
  746. <tr id="codec_tr">
  747. <td>
  748. <label for="codec" class="required">
  749. License
  750. </label>
  751. </td>
  752. <td>
  753. <select name="codec">
  754. <option>---</option>
  755. HTML;
  756. foreach ($this->Codecs as $Codec) {
  757. echo "<option value='$Codec'";
  758. if ($Codec === ($Torrent['Codec'] ?? false)) {
  759. echo " selected";
  760. }
  761. echo ">$Codec</option>\n";
  762. }
  763. echo <<<HTML
  764. </select>
  765. <p>
  766. Please see
  767. <a href="http://www.dcc.ac.uk/resources/how-guides/license-research-data" target="_blank">How to License Research Data</a>
  768. </p>
  769. </td>
  770. </tr>
  771. HTML;
  772. /**
  773. * ====================================
  774. * = Begin if NewTorrent fields again =
  775. * ====================================
  776. */
  777. /**
  778. * Media
  779. *
  780. * The class of technology associated with the data.
  781. * Answers the question: "Where does the data come from?"
  782. *
  783. * This could be the data genesis platform or program,
  784. * or a genre of physical media (e.g., vinyl record).
  785. */
  786. /**
  787. * Make select element
  788. *
  789. * Takes an ID, label, torrent, and media list.
  790. * Returns a media select option as on upload.php.
  791. */
  792. function mediaSelect($trID = '', $Label = '', $Torrent = [], $Media = [])
  793. {
  794. echo <<<HTML
  795. <tr id="$trID">
  796. <td>
  797. <label for="media" class="required">
  798. $Label
  799. </label>
  800. </td>
  801. <td>
  802. <select name="media">
  803. <option>---</option>
  804. HTML;
  805. foreach ($Media as $Media) {
  806. echo "<option value='$Media'";
  807. if ($Media === ($Torrent['Media'] ?? false)) {
  808. echo ' selected';
  809. }
  810. echo ">$Media</option>\n";
  811. }
  812. echo <<<HTML
  813. </select>
  814. <p>
  815. The class of technology used
  816. </p>
  817. </td>
  818. </tr>
  819. HTML;
  820. } # End mediaSelect()
  821. /**
  822. * Platform: Sequences
  823. */
  824. if ($this->NewTorrent) {
  825. mediaSelect(
  826. $trID = 'media_tr',
  827. $Label = 'Platform',
  828. $Torrent = $Torrent,
  829. $Media = $this->SeqPlatforms
  830. );
  831. /**
  832. * Platform: Graphs
  833. */
  834. mediaSelect(
  835. $trID = 'media_graphs_tr',
  836. $Label = 'Platform',
  837. $Torrent = $Torrent,
  838. $Media = array_merge($this->GraphPlatforms, $this->SeqPlatforms)
  839. );
  840. /**
  841. * Platform: Scalars/Vectors
  842. */
  843. mediaSelect(
  844. $trID = 'media_scalars_vectors_tr',
  845. $Label = 'Platform',
  846. $Torrent = $Torrent,
  847. $Media = array_merge($this->GraphPlatforms, $this->ImgPlatforms)
  848. );
  849. /**
  850. * Platform: Scalars/Vectors
  851. */
  852. mediaSelect(
  853. $trID = 'media_images_tr',
  854. $Label = 'Platform',
  855. $Torrent = $Torrent,
  856. $Media = $this->ImgPlatforms
  857. );
  858. /**
  859. * Platform: Documents
  860. */
  861. mediaSelect(
  862. $trID = 'media_documents_tr',
  863. $Label = 'Platform',
  864. $Torrent = $Torrent,
  865. $Media = $this->DocPlatforms
  866. );
  867. /**
  868. * Platform: Machine Data
  869. */
  870. mediaSelect(
  871. $trID = 'media_machine_data_tr',
  872. $Label = 'Platform',
  873. $Torrent = $Torrent,
  874. $Media = $this->RawPlatforms
  875. );
  876. } # fi NewTorrent
  877. else {
  878. $TorrentMedia = $Torrent['Media'];
  879. echo <<<HTML
  880. <input type="hidden" name="media" value="$TorrentMedia" />
  881. HTML;
  882. }
  883. /**
  884. * Format
  885. *
  886. * Simple: the data's file format.
  887. * Called Container in OT Gazelle, same diff.
  888. * In the future, $ENV will automagically set this.
  889. */
  890. function formatSelect($trID = '', $Label = '', $Torrent = [], $FileTypes = [])
  891. {
  892. echo <<<HTML
  893. <tr id="$trID">
  894. <td>
  895. <label for="container" class="required">
  896. $Label
  897. <label>
  898. </td>
  899. <td>
  900. <select id="container" name="container">
  901. <option value="Autofill">Autofill</option>
  902. HTML;
  903. foreach ($FileTypes as $Type => $Extensions) {
  904. echo "<option value='$Type'";
  905. if ($Type === ($Torrent['Container'] ?? false)) {
  906. echo ' selected';
  907. }
  908. echo ">$Type</option>\n";
  909. }
  910. echo <<<HTML
  911. </select>
  912. <p>
  913. File format, or detect from file list
  914. <!--
  915. todo: Make work with config.php metadata
  916. Data file format, or detect from file list
  917. Compression algorithm, or detect from file list
  918. -->
  919. </p>
  920. </td>
  921. </tr>
  922. HTML;
  923. } # End formatSelect()
  924. /**
  925. * Format: Sequences
  926. */
  927. formatSelect(
  928. $trID = 'container_tr',
  929. $Label = 'Format',
  930. $Torrent = $Torrent,
  931. $FileTypes = array_merge($this->SeqFormats, $this->ProtFormats, $this->PlainFormats)
  932. );
  933. /**
  934. * Format: Graphs
  935. */
  936. formatSelect(
  937. $trID = 'container_graphs_tr',
  938. $Label = 'Format',
  939. $Torrent = $Torrent,
  940. $FileTypes = array_merge($this->GraphXmlFormats, $this->GraphTxtFormats, $this->SeqFormats, $this->ProtFormats, $this->PlainFormats)
  941. );
  942. /**
  943. * Format: Scalars/Vectors
  944. */
  945. formatSelect(
  946. $trID = 'container_scalars_vectors_tr',
  947. $Label = 'Format',
  948. $Torrent = $Torrent,
  949. $FileTypes = array_merge($this->ImgFormats, $this->SeqFormats, $this->ProtFormats, $this->PlainFormats)
  950. );
  951. /**
  952. * Format: Images
  953. */
  954. formatSelect(
  955. $trID = 'container_images_tr',
  956. $Label = 'Format',
  957. $Torrent = $Torrent,
  958. $FileTypes = array_merge($this->ImgFormats, $this->PlainFormats)
  959. );
  960. /**
  961. * Format: Spatial
  962. */
  963. formatSelect(
  964. $trID = 'container_spatial_tr',
  965. $Label = 'Format',
  966. $Torrent = $Torrent,
  967. $FileTypes = array_merge($this->MapVectorFormats, $this->MapRasterFormats, $this->ImgFormats, $this->PlainFormats)
  968. );
  969. /**
  970. * Format: Documents
  971. */
  972. formatSelect(
  973. $trID = 'container_documents_tr',
  974. $Label = 'Format',
  975. $Torrent = $Torrent,
  976. $FileTypes = array_merge($this->BinDocFormats, $this->CpuGenFormats, $this->PlainFormats)
  977. );
  978. /**
  979. * Format: Compression
  980. */
  981. formatSelect(
  982. $trID = 'archive_tr',
  983. $Label = 'Archive',
  984. $Torrent = $Torrent,
  985. $FileTypes = $this->Archives
  986. );
  987. /**
  988. * Scope
  989. *
  990. * How complete the data are.
  991. * Relatively, how much information does it contain?
  992. */
  993. $TorrentResolution = ($Torrent['Resolution']) ?? '';
  994. echo <<<HTML
  995. <tr id="resolution_tr">
  996. <td>
  997. <label for="ressel" class="required">
  998. Scope
  999. </label>
  1000. </td>
  1001. <td>
  1002. <select id="ressel" name="ressel" onchange="SetResolution()">
  1003. <option>---</option>
  1004. HTML;
  1005. foreach ($this->Resolutions as $Res) {
  1006. echo "<option value='$Res'";
  1007. if ($Res === ($Torrent['Resolution'] ?? false)
  1008. || (!isset($FoundRes) && ($Torrent['Resolution'] ?? false)
  1009. && $Res === 'Other')) {
  1010. echo " selected";
  1011. $FoundRes = true;
  1012. }
  1013. echo ">$Res</option>\n";
  1014. }
  1015. echo <<<HTML
  1016. </select>
  1017. <!-- Enter your own -->
  1018. <input type="text" id="resolution" name="resolution" size="15" maxlength="20"
  1019. class="hidden" value="$TorrentResolution" readonly>
  1020. </input>
  1021. <script>
  1022. if ($('#ressel').raw().value === 'Other') {
  1023. $('#resolution').raw().readOnly = false
  1024. $('#resolution').gshow()
  1025. }
  1026. </script>
  1027. <p>
  1028. How complete the data is, specifically or conceptually
  1029. </p>
  1030. </td>
  1031. </tr>
  1032. HTML;
  1033. /**
  1034. * ====================================
  1035. * = Begin if NewTorrent fields again =
  1036. * ====================================
  1037. */
  1038. /**
  1039. * Tags
  1040. *
  1041. * Simple enough.
  1042. * I won't rehash tag management.
  1043. */
  1044. if ($this->NewTorrent) {
  1045. echo <<<HTML
  1046. <tr id="tags_tr">
  1047. <td>
  1048. <label for="tags" class="required">
  1049. Tags
  1050. </label>
  1051. </td>
  1052. <td>
  1053. HTML;
  1054. $GenreTags = G::$Cache->get_value('genre_tags');
  1055. if (!$GenreTags) {
  1056. $DB->query("
  1057. SELECT
  1058. `Name`
  1059. FROM
  1060. `tags`
  1061. WHERE
  1062. `TagType` = 'genre'
  1063. ORDER BY
  1064. `Name`
  1065. ");
  1066. $GenreTags = $DB->collect('Name');
  1067. G::$Cache->cache_value('genre_tags', $GenreTags, 3600*6);
  1068. }
  1069. # todo: Find a better place for these
  1070. $Disabled = ($this->DisabledFlag) ? ' disabled="disabled"' : null;
  1071. $TorrentTagList = display_str(implode(', ', explode(',', $Torrent['TagList'])));
  1072. $AutocompleteOption = Users::has_autocomplete_enabled('other');
  1073. echo <<<HTML
  1074. <select id="genre_tags" name="genre_tags" onchange="add_tag(); return false;" $Disabled>
  1075. <option>---</option>
  1076. HTML;
  1077. foreach (Misc::display_array($GenreTags) as $Genre) {
  1078. echo <<<HTML
  1079. <option value="$Genre">
  1080. $Genre
  1081. </option>
  1082. HTML;
  1083. }
  1084. echo <<<HTML
  1085. </select>
  1086. <input type="text" id="tags" name="tags" size="60"
  1087. placeholder="Comma-seperated list of at least 5 tags"
  1088. value="$TorrentTagList" $AutocompleteOption />
  1089. </td>
  1090. </tr>
  1091. HTML;
  1092. } # fi NewTorrent
  1093. /**
  1094. * Picture
  1095. *
  1096. * Another obvious field.
  1097. */
  1098. if ($this->NewTorrent) {
  1099. $TorrentImage = display_str($Torrent['Image']);
  1100. $Disabled = $this->Disabled;
  1101. echo <<<HTML
  1102. <tr id="cover_tr">
  1103. <td>
  1104. <label for="image">
  1105. Picture
  1106. </label>
  1107. </td>
  1108. <td>
  1109. <input type="text" id="image" name="image" size="60"
  1110. placeholder="A meaningful picture, e.g., the specimen or a thumbnail"
  1111. value="$TorrentImage" $Disabled? />
  1112. </td>
  1113. </tr>
  1114. HTML;
  1115. }
  1116. /**
  1117. * Mirrors
  1118. *
  1119. * This should be in the `torrents` table not `torrents_group`.
  1120. * The intended use is for web seeds, Dat mirrors, etc.
  1121. */
  1122. if (!$this->DisabledFlag && $this->NewTorrent) {
  1123. $TorrentMirrors = display_str($Torrent['Mirrors']);
  1124. echo <<<HTML
  1125. <tr id="mirrors_tr">
  1126. <td>
  1127. <label for="mirrors">
  1128. Mirrors
  1129. </label>
  1130. </td>
  1131. <td>
  1132. <!-- Needs to be all on one line -->
  1133. <textarea rows="2" name="mirrors" id="mirrors"
  1134. placeholder="Up to two FTP/HTTP addresses that either point directly to a file, or for multi-file torrents, to the enclosing folder">$TorrentMirrors</textarea>
  1135. </td>
  1136. </tr>
  1137. HTML;
  1138. }
  1139. /**
  1140. * Samples
  1141. *
  1142. * Called Screenshots in OT Gazelle.
  1143. * Called Publication in Bio Gazelle.
  1144. * Eventually this will be a proper database in itself,
  1145. * pulling info from DOI to populate the schema.
  1146. */
  1147. if (!$this->DisabledFlag && $this->NewTorrent) {
  1148. $TorrentSamples = display_str($Torrent['Screenshots']);
  1149. echo <<<HTML
  1150. <tr id="screenshots_tr">
  1151. <td>
  1152. <label for="screenshots">
  1153. Publications
  1154. </label>
  1155. </td>
  1156. <td>
  1157. <!-- Needs to be all on one line -->
  1158. <textarea rows="8" name="screenshots" id="screenshots"
  1159. placeholder="Up to ten DOI numbers, one per line">$TorrentSamples</textarea>
  1160. </td>
  1161. </tr>
  1162. HTML;
  1163. }
  1164. /**
  1165. * Torrent group description
  1166. *
  1167. * The text on the main torrent pages,
  1168. * between torrent info and torrent comments,
  1169. * visible even if individual torrents are collapsed.
  1170. */
  1171. if ($this->NewTorrent) {
  1172. echo <<<HTML
  1173. <tr id="group_desc_tr">
  1174. <td>
  1175. <label for="album_desc" class="required">
  1176. Torrent Group Description
  1177. </label>
  1178. </td>
  1179. <td>
  1180. HTML;
  1181. new TEXTAREA_PREVIEW(
  1182. $Name = 'album_desc',
  1183. $ID = 'album_desc',
  1184. $Value = display_str($Torrent['GroupDescription']) ?? '',
  1185. $Placeholder = "General info about the torrent subject's function or significance",
  1186. );
  1187. echo '</td></tr>';
  1188. } # fi NewTorrent
  1189. /**
  1190. * ============================
  1191. * = End if NewTorrent fields =
  1192. * ============================
  1193. */
  1194. /**
  1195. * Torrent description
  1196. *
  1197. * The test displayed when torrent info is expanded.
  1198. * It should describe the specific torrent, not the group.
  1199. */
  1200. echo <<<HTML
  1201. <tr id="release_desc_tr">
  1202. <td>
  1203. <label for="release_desc">
  1204. Torrent Description
  1205. </label>
  1206. </td>
  1207. <td>
  1208. HTML;
  1209. new TEXTAREA_PREVIEW(
  1210. $Name = 'release_desc',
  1211. $ID = 'release_desc',
  1212. $Value = display_str($Torrent['TorrentDescription'] ?? ''),
  1213. $Placeholder = 'Specific info about the protocols and equipment used to produce the data',
  1214. );
  1215. echo '</td></tr>';
  1216. /**
  1217. * Boolean options
  1218. *
  1219. * Simple checkboxes that do stuff.
  1220. * Currently checks for data annotations and anonymous uploads.
  1221. * More fields could be created as the need arises.
  1222. */
  1223. /**
  1224. * Aligned/Annontated
  1225. *
  1226. * Called Censored in OT Gazelle.
  1227. */
  1228. $TorrentAnnotated = ($Torrent['Censored'] ?? 0) ? ' checked' : '';
  1229. echo <<<HTML
  1230. <tr id="censored_tr">
  1231. <td>
  1232. <label for="censored">
  1233. Aligned/Annotated
  1234. </label>
  1235. </td>
  1236. <td>
  1237. <input type="checkbox" name="censored" value="1" $TorrentAnnotated />
  1238. &ensp;
  1239. Whether the torrent contains alignments, annotations, or other structural metadata
  1240. </td>
  1241. </tr>
  1242. HTML;
  1243. /**
  1244. * Upload Anonymously
  1245. */
  1246. $TorrentAnonymous = ($Torrent['Anonymous'] ?? false) ? ' checked' : '';
  1247. echo <<<HTML
  1248. <tr id="anon_tr">
  1249. <td>
  1250. <label for="anonymous">
  1251. Upload Anonymously
  1252. </label>
  1253. </td>
  1254. <td>
  1255. <input type="checkbox" name="anonymous" value="1" $TorrentAnonymous />
  1256. &ensp;
  1257. Hide your username from other users on the torrent details page
  1258. </td>
  1259. </tr>
  1260. HTML;
  1261. # End the giant dynamic form table
  1262. echo '</table>';
  1263. # Drink a stiff one
  1264. $this->foot();
  1265. G::$DB->set_query_id($QueryID);
  1266. } # End upload_form()
  1267. } # End TorrentForm()