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.php 41KB

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