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.

requests.php 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. <?php
  2. #declare(strict_types=1);
  3. # todo: Go through line by line
  4. $SphQL = new SphinxqlQuery();
  5. $SphQL->select('id, votes, bounty')->from('requests, requests_delta');
  6. $SortOrders = array(
  7. 'votes' => 'votes',
  8. 'bounty' => 'bounty',
  9. 'lastvote' => 'lastvote',
  10. 'filled' => 'timefilled',
  11. 'year' => 'year',
  12. 'created' => 'timeadded',
  13. 'random' => false);
  14. if (empty($_GET['order']) || !isset($SortOrders[$_GET['order']])) {
  15. $_GET['order'] = 'created';
  16. }
  17. $OrderBy = $_GET['order'];
  18. if (!empty($_GET['sort']) && $_GET['sort'] === 'asc') {
  19. $OrderWay = 'asc';
  20. } else {
  21. $_GET['sort'] = 'desc';
  22. $OrderWay = 'desc';
  23. }
  24. $NewSort = $_GET['sort'] === 'asc' ? 'desc' : 'asc';
  25. if ($OrderBy === 'random') {
  26. $SphQL->order_by('RAND()', '');
  27. unset($_GET['page']);
  28. } else {
  29. $SphQL->order_by($SortOrders[$OrderBy], $OrderWay);
  30. }
  31. $Submitted = !empty($_GET['submit']);
  32. //Paranoia
  33. if (!empty($_GET['userid'])) {
  34. if (!is_number($_GET['userid'])) {
  35. json_die("failure");
  36. }
  37. $UserInfo = Users::user_info($_GET['userid']);
  38. if (empty($UserInfo)) {
  39. json_die("failure");
  40. }
  41. $Perms = Permissions::get_permissions($UserInfo['PermissionID']);
  42. $UserClass = $Perms['Class'];
  43. }
  44. $BookmarkView = false;
  45. if (empty($_GET['type'])) {
  46. $Title = 'Requests';
  47. if (empty($_GET['showall'])) {
  48. $SphQL->where('visible', 1);
  49. }
  50. } else {
  51. switch ($_GET['type']) {
  52. case 'created':
  53. if (!empty($UserInfo)) {
  54. if (!check_paranoia('requestsvoted_list', $UserInfo['Paranoia'], $Perms['Class'], $UserInfo['ID'])) {
  55. json_die("failure");
  56. }
  57. $Title = "Requests created by $UserInfo[Username]";
  58. $SphQL->where('userid', $UserInfo['ID']);
  59. } else {
  60. $Title = 'My requests';
  61. $SphQL->where('userid', $LoggedUser['ID']);
  62. }
  63. break;
  64. case 'voted':
  65. if (!empty($UserInfo)) {
  66. if (!check_paranoia('requestsvoted_list', $UserInfo['Paranoia'], $Perms['Class'], $UserInfo['ID'])) {
  67. json_die("failure");
  68. }
  69. $Title = "Requests voted for by $UserInfo[Username]";
  70. $SphQL->where('voter', $UserInfo['ID']);
  71. } else {
  72. $Title = 'Requests I have voted on';
  73. $SphQL->where('voter', $LoggedUser['ID']);
  74. }
  75. break;
  76. case 'filled':
  77. if (!empty($UserInfo)) {
  78. if (!check_paranoia('requestsfilled_list', $UserInfo['Paranoia'], $Perms['Class'], $UserInfo['ID'])) {
  79. json_die("failure");
  80. }
  81. $Title = "Requests filled by $UserInfo[Username]";
  82. $SphQL->where('fillerid', $UserInfo['ID']);
  83. } else {
  84. $Title = 'Requests I have filled';
  85. $SphQL->where('fillerid', $LoggedUser['ID']);
  86. }
  87. break;
  88. case 'bookmarks':
  89. $Title = 'Your bookmarked requests';
  90. $BookmarkView = true;
  91. $SphQL->where('bookmarker', $LoggedUser['ID']);
  92. break;
  93. default:
  94. json_die("failure");
  95. }
  96. }
  97. if ($Submitted && empty($_GET['show_filled'])) {
  98. $SphQL->where('torrentid', 0);
  99. }
  100. if (!empty($_GET['formats'])) {
  101. $FormatArray = $_GET['formats'];
  102. if (count($FormatArray) !== count($Formats)) {
  103. $FormatNameArray = [];
  104. foreach ($FormatArray as $Index => $MasterIndex) {
  105. if (isset($Formats[$MasterIndex])) {
  106. $FormatNameArray[$Index] = '"' . strtr(Sphinxql::sph_escape_string($Formats[$MasterIndex]), '-.', ' ') . '"';
  107. }
  108. }
  109. if (count($FormatNameArray) >= 1) {
  110. if (!empty($_GET['formats_strict'])) {
  111. $SearchString = '(' . implode(' | ', $FormatNameArray) . ')';
  112. } else {
  113. $SearchString = '(any | ' . implode(' | ', $FormatNameArray) . ')';
  114. }
  115. $SphQL->where_match($SearchString, 'formatlist', false);
  116. }
  117. }
  118. }
  119. if (!empty($_GET['media'])) {
  120. $MediaArray = $_GET['media'];
  121. if (count($MediaArray) !== count($Media)) {
  122. $MediaNameArray = [];
  123. foreach ($MediaArray as $Index => $MasterIndex) {
  124. if (isset($Media[$MasterIndex])) {
  125. $MediaNameArray[$Index] = '"' . strtr(Sphinxql::sph_escape_string($Media[$MasterIndex]), '-.', ' ') . '"';
  126. }
  127. }
  128. if (count($MediaNameArray) >= 1) {
  129. if (!empty($_GET['media_strict'])) {
  130. $SearchString = '(' . implode(' | ', $MediaNameArray) . ')';
  131. } else {
  132. $SearchString = '(any | ' . implode(' | ', $MediaNameArray) . ')';
  133. }
  134. $SphQL->where_match($SearchString, 'medialist', false);
  135. }
  136. }
  137. }
  138. if (!empty($_GET['bitrates'])) {
  139. $BitrateArray = $_GET['bitrates'];
  140. if (count($BitrateArray) !== count($Bitrates)) {
  141. $BitrateNameArray = [];
  142. foreach ($BitrateArray as $Index => $MasterIndex) {
  143. if (isset($Bitrates[$MasterIndex])) {
  144. $BitrateNameArray[$Index] = '"' . strtr(Sphinxql::sph_escape_string($Bitrates[$MasterIndex]), '-.', ' ') . '"';
  145. }
  146. }
  147. if (count($BitrateNameArray) >= 1) {
  148. if (!empty($_GET['bitrate_strict'])) {
  149. $SearchString = '(' . implode(' | ', $BitrateNameArray) . ')';
  150. } else {
  151. $SearchString = '(any | ' . implode(' | ', $BitrateNameArray) . ')';
  152. }
  153. $SphQL->where_match($SearchString, 'bitratelist', false);
  154. }
  155. }
  156. }
  157. if (!empty($_GET['search'])) {
  158. $SearchString = trim($_GET['search']);
  159. if ($SearchString !== '') {
  160. $SearchWords = array('include' => [], 'exclude' => []);
  161. $Words = explode(' ', $SearchString);
  162. foreach ($Words as $Word) {
  163. $Word = trim($Word);
  164. // Skip isolated hyphens to enable "Artist - Title" searches
  165. if ($Word === '-') {
  166. continue;
  167. }
  168. if ($Word[0] === '!' && strlen($Word) >= 2) {
  169. if (strpos($Word, '!', 1) === false) {
  170. $SearchWords['exclude'][] = $Word;
  171. } else {
  172. $SearchWords['include'][] = $Word;
  173. }
  174. } elseif ($Word !== '') {
  175. $SearchWords['include'][] = $Word;
  176. }
  177. }
  178. }
  179. }
  180. if (!isset($_GET['tags_type']) || $_GET['tags_type'] === '1') {
  181. $TagType = 1;
  182. $_GET['tags_type'] = '1';
  183. } else {
  184. $TagType = 0;
  185. $_GET['tags_type'] = '0';
  186. }
  187. if (!empty($_GET['tags'])) {
  188. $SearchTags = array('include' => [], 'exclude' => []);
  189. $Tags = explode(',', $_GET['tags']);
  190. foreach ($Tags as $Tag) {
  191. $Tag = trim($Tag);
  192. if ($Tag[0] === '!' && strlen($Tag) >= 2) {
  193. if (strpos($Tag, '!', 1) === false) {
  194. $SearchTags['exclude'][] = $Tag;
  195. } else {
  196. $SearchTags['include'][] = $Tag;
  197. }
  198. } elseif ($Tag !== '') {
  199. $SearchTags['include'][] = $Tag;
  200. }
  201. }
  202. $TagFilter = Tags::tag_filter_sph($SearchTags, $TagType);
  203. if (!empty($TagFilter['predicate'])) {
  204. $SphQL->where_match($TagFilter['predicate'], 'taglist', false);
  205. }
  206. } elseif (!isset($_GET['tags_type']) || $_GET['tags_type'] !== '0') {
  207. $_GET['tags_type'] = 1;
  208. } else {
  209. $_GET['tags_type'] = 0;
  210. }
  211. if (isset($SearchWords)) {
  212. $QueryParts = [];
  213. foreach ($SearchWords['include'] as $Word) {
  214. $QueryParts[] = Sphinxql::sph_escape_string($Word);
  215. }
  216. if (!empty($SearchWords['exclude'])) {
  217. foreach ($SearchWords['exclude'] as $Word) {
  218. $QueryParts[] = '!' . Sphinxql::sph_escape_string(substr($Word, 1));
  219. }
  220. }
  221. if (!empty($QueryParts)) {
  222. $SearchString = implode(' ', $QueryParts);
  223. $SphQL->where_match($SearchString, '*', false);
  224. }
  225. }
  226. if (!empty($_GET['filter_cat'])) {
  227. $CategoryArray = array_keys($_GET['filter_cat']);
  228. if (count($CategoryArray) !== count($Categories)) {
  229. foreach ($CategoryArray as $Key => $Index) {
  230. if (!isset($Categories[$Index - 1])) {
  231. unset($CategoryArray[$Key]);
  232. }
  233. }
  234. if (count($CategoryArray) >= 1) {
  235. $SphQL->where('categoryid', $CategoryArray);
  236. }
  237. }
  238. }
  239. if (!empty($_GET['releases'])) {
  240. $ReleaseArray = $_GET['releases'];
  241. if (count($ReleaseArray) !== count($ReleaseTypes)) {
  242. foreach ($ReleaseArray as $Index => $Value) {
  243. if (!isset($ReleaseTypes[$Value])) {
  244. unset($ReleaseArray[$Index]);
  245. }
  246. }
  247. if (count($ReleaseArray) >= 1) {
  248. $SphQL->where('releasetype', $ReleaseArray);
  249. }
  250. }
  251. }
  252. if (!empty($_GET['requestor'])) {
  253. if (is_number($_GET['requestor'])) {
  254. $SphQL->where('userid', $_GET['requestor']);
  255. } else {
  256. error(404);
  257. }
  258. }
  259. if (isset($_GET['year'])) {
  260. if (is_number($_GET['year']) || $_GET['year'] === '0') {
  261. $SphQL->where('year', $_GET['year']);
  262. } else {
  263. error(404);
  264. }
  265. }
  266. if (!empty($_GET['page']) && is_number($_GET['page']) && $_GET['page'] > 0) {
  267. $Page = $_GET['page'];
  268. $Offset = ($Page - 1) * REQUESTS_PER_PAGE;
  269. $SphQL->limit($Offset, REQUESTS_PER_PAGE, $Offset + REQUESTS_PER_PAGE);
  270. } else {
  271. $Page = 1;
  272. $SphQL->limit(0, REQUESTS_PER_PAGE, REQUESTS_PER_PAGE);
  273. }
  274. $SphQLResult = $SphQL->query();
  275. $NumResults = (int)$SphQLResult->get_meta('total_found');
  276. if ($NumResults > 0) {
  277. $SphRequests = $SphQLResult->to_array('id');
  278. if ($OrderBy === 'random') {
  279. $NumResults = count($RequestIDs);
  280. }
  281. if ($NumResults > REQUESTS_PER_PAGE) {
  282. if (($Page - 1) * REQUESTS_PER_PAGE > $NumResults) {
  283. $Page = 0;
  284. }
  285. }
  286. }
  287. if ($NumResults == 0) {
  288. json_die("success", array(
  289. 'currentPage' => 1,
  290. 'pages' => 1,
  291. 'results' => []
  292. ));
  293. } else {
  294. $JsonResults = [];
  295. $Requests = Requests::get_requests(array_keys($SphRequests));
  296. foreach ($SphRequests as $RequestID => $SphRequest) {
  297. $Request = $Requests[$RequestID];
  298. $VoteCount = $SphRequest['votes'];
  299. $Bounty = $SphRequest['bounty'] * 1024; // Sphinx stores bounty in kB
  300. $Requestor = Users::user_info($Request['UserID']);
  301. $Filler = $Request['FillerID'] ? Users::user_info($Request['FillerID']) : null;
  302. if ($Request['CategoryID'] == 0) {
  303. $CategoryName = 'Unknown';
  304. } else {
  305. $CategoryName = $Categories[$Request['CategoryID'] - 1];
  306. }
  307. $JsonArtists = Requests::get_artists($RequestID);
  308. $Tags = $Request['Tags'];
  309. $JsonResults[] = array(
  310. 'requestId' => (int)$RequestID,
  311. 'requestorId' => (int)$Requestor['ID'],
  312. 'requestorName' => $Requestor['Username'],
  313. 'timeAdded' => $Request['TimeAdded'],
  314. 'lastVote' => $Request['LastVote'],
  315. 'voteCount' => (int)$VoteCount,
  316. 'bounty' => (int)$Bounty,
  317. 'categoryId' => (int)$Request['CategoryID'],
  318. 'categoryName' => $CategoryName,
  319. 'authors' => $JsonArtists,
  320. #'artists' => $JsonArtists,
  321. 'title' => $Request['Title'],
  322. 'year' => (int)$Request['Year'],
  323. 'picture' => $Request['Image'],
  324. #'image' => $Request['Image'],
  325. 'description' => $Request['Description'],
  326. 'isFilled' => ($Request['TorrentID'] > 0),
  327. 'fillerId' => (int)$Request['FillerID'],
  328. 'fillerName' => $Filler ? $Filler['Username'] : '',
  329. 'torrentId' => (int)$Request['TorrentID'],
  330. 'timeFilled' => $Request['TimeFilled'] == 0 ? '' : $Request['TimeFilled']
  331. );
  332. }
  333. json_die("success", array(
  334. 'currentPage' => intval($Page),
  335. 'pages' => ceil($NumResults / REQUESTS_PER_PAGE),
  336. 'results' => $JsonResults
  337. ));
  338. }