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

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