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

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