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 40KB

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