PageRenderTime 42ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/class/random.class.php

https://gitlab.com/x33n/ampache
PHP | 362 lines | 236 code | 53 blank | 73 comment | 49 complexity | 3404a8cebb74721c8b97bf7a29cd2620 MD5 | raw file
  1. <?php
  2. /* vim:set softtabstop=4 shiftwidth=4 expandtab: */
  3. /**
  4. *
  5. * LICENSE: GNU General Public License, version 2 (GPLv2)
  6. * Copyright 2001 - 2015 Ampache.org
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; version 2
  11. * of the License.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. *
  22. */
  23. /**
  24. * Random Class
  25. *
  26. * All of the 'random' type events, elements
  27. */
  28. class Random
  29. {
  30. /**
  31. * artist
  32. * This returns the ID of a random artist, nothing special here for now
  33. */
  34. public static function artist()
  35. {
  36. $sql = "SELECT `artist`.`id` FROM `artist` " .
  37. "LEFT JOIN `song` ON `song`.`artist` = `artist`.`id` ";
  38. if (AmpConfig::get('catalog_disable')) {
  39. $sql .= "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog` " .
  40. "WHERE `catalog`.`enabled` = '1' ";
  41. }
  42. $sql .= "GROUP BY `artist`.`id` " .
  43. "ORDER BY RAND() LIMIT 1";
  44. $db_results = Dba::read($sql);
  45. $results = Dba::fetch_assoc($db_results);
  46. return $results['id'];
  47. } // artist
  48. /**
  49. * playlist
  50. * This returns a random Playlist with songs little bit of extra
  51. * logic require
  52. */
  53. public static function playlist()
  54. {
  55. $sql = "SELECT `playlist`.`id` FROM `playlist` LEFT JOIN `playlist_data` " .
  56. " ON `playlist`.`id`=`playlist_data`.`playlist` WHERE `playlist_data`.`object_id` IS NOT NULL " .
  57. " ORDER BY RAND()";
  58. $db_results = Dba::read($sql);
  59. $results = Dba::fetch_assoc($db_results);
  60. return $results['id'];
  61. } // playlist
  62. /**
  63. * get_single_song
  64. * This returns a single song pulled based on the passed random method
  65. */
  66. public static function get_single_song($type)
  67. {
  68. $method_name = 'get_' . $type;
  69. if (!method_exists('Random', $method_name)) {
  70. $method_name = 'get_default';
  71. }
  72. $song_ids = self::$method_name(1);
  73. $song_id = array_pop($song_ids);
  74. return $song_id;
  75. } // get_single_song
  76. /**
  77. * get_default
  78. * This just randomly picks a song at whim from all catalogs
  79. * nothing special here...
  80. */
  81. public static function get_default($limit = '')
  82. {
  83. $results = array();
  84. if (empty($limit)) {
  85. $limit = AmpConfig::get('offset_limit') ? AmpConfig::get('offset_limit') : '25';
  86. }
  87. $sql = "SELECT `song`.`id` FROM `song` ";
  88. if (AmpConfig::get('catalog_disable')) {
  89. $sql .= "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog` " .
  90. "WHERE `catalog`.`enabled` = '1' ";
  91. }
  92. $sql .= "ORDER BY RAND() LIMIT $limit";
  93. $db_results = Dba::read($sql);
  94. while ($row = Dba::fetch_assoc($db_results)) {
  95. $results[] = $row['id'];
  96. }
  97. return $results;
  98. } // get_default
  99. /**
  100. * get_album
  101. * This looks at the last album played by the current user and
  102. * picks something else in the same album
  103. */
  104. public static function get_album($limit)
  105. {
  106. $results = array();
  107. // Get the last album played by us
  108. $data = $GLOBALS['user']->get_recently_played('1', 'album');
  109. $where_sql = "";
  110. if ($data[0]) {
  111. $where_sql = " AND `song`.`album`='" . $data[0] . "' ";
  112. }
  113. $sql = "SELECT `song`.`id` FROM `song` ";
  114. if (AmpConfig::get('catalog_disable')) {
  115. $sql .= "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog` " .
  116. "WHERE `catalog`.`enabled` = '1' ";
  117. } else {
  118. $sql .= "WHERE '1' = '1' ";
  119. }
  120. $sql .= "$where_sql ORDER BY RAND() LIMIT $limit";
  121. $db_results = Dba::read($sql);
  122. while ($row = Dba::fetch_assoc($db_results)) {
  123. $results[] = $row['id'];
  124. }
  125. return $results;
  126. } // get_album
  127. /**
  128. * get_artist
  129. * This looks at the last artist played and then randomly picks a song from the
  130. * same artist
  131. */
  132. public static function get_artist($limit)
  133. {
  134. $results = array();
  135. $data = $GLOBALS['user']->get_recently_played('1','artist');
  136. $where_sql = "";
  137. if ($data[0]) {
  138. $where_sql = " AND `song`.`artist`='" . $data[0] . "' ";
  139. }
  140. $sql = "SELECT `song`.`id` FROM `song` ";
  141. if (AmpConfig::get('catalog_disable')) {
  142. $sql .= "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog` " .
  143. "WHERE `catalog`.`enabled` = '1' ";
  144. } else {
  145. $sql .= "WHERE '1' = '1' ";
  146. }
  147. $sql .= "$where_sql ORDER BY RAND() LIMIT $limit";
  148. $db_results = Dba::read($sql);
  149. while ($row = Dba::fetch_assoc($db_results)) {
  150. $results[] = $row['id'];
  151. }
  152. return $results;
  153. } // get_artist
  154. /**
  155. * advanced
  156. * This processes the results of a post from a form and returns an
  157. * array of song items that were returned from said randomness
  158. */
  159. public static function advanced($type, $data)
  160. {
  161. /* Figure out our object limit */
  162. $limit = intval($data['random']);
  163. // Generate our matchlist
  164. /* If they've passed -1 as limit then get everything */
  165. $limit_sql = "";
  166. if ($data['random'] == "-1") { unset($data['random']); } else { $limit_sql = "LIMIT " . Dba::escape($limit); }
  167. $search_data = Search::clean_request($data);
  168. $search_info = false;
  169. if (count($search_data) > 1) {
  170. $search = new Search(null, $type);
  171. $search->parse_rules($search_data);
  172. $search_info = $search->to_sql();
  173. }
  174. $sql = "";
  175. switch ($type) {
  176. case 'song':
  177. $sql = "SELECT `song`.`id`, `size`, `time` " .
  178. "FROM `song` ";
  179. if ($search_info) {
  180. $sql .= $search_info['table_sql'];
  181. }
  182. if (AmpConfig::get('catalog_disable')) {
  183. $sql .= " LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog`";
  184. $sql .= " WHERE `catalog`.`enabled` = '1'";
  185. }
  186. if ($search_info) {
  187. if (AmpConfig::get('catalog_disable')) {
  188. $sql .= ' AND ' . $search_info['where_sql'];
  189. } else {
  190. $sql .= ' WHERE ' . $search_info['where_sql'];
  191. }
  192. }
  193. break;
  194. case 'album':
  195. $sql = "SELECT `album`.`id`, SUM(`song`.`size`) AS `size`, SUM(`song`.`time`) AS `time` FROM `album` ";
  196. if (! $search_info || ! $search_info['join']['song']) {
  197. $sql .= "LEFT JOIN `song` ON `song`.`album`=`album`.`id` ";
  198. }
  199. if ($search_info) {
  200. $sql .= $search_info['table_sql'];
  201. }
  202. if (AmpConfig::get('catalog_disable')) {
  203. $sql .= " LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog`";
  204. $sql .= " WHERE `catalog`.`enabled` = '1'";
  205. }
  206. if ($search_info) {
  207. if (AmpConfig::get('catalog_disable')) {
  208. $sql .= ' AND ' . $search_info['where_sql'];
  209. } else {
  210. $sql .= ' WHERE ' . $search_info['where_sql'];
  211. }
  212. }
  213. $sql .= ' GROUP BY `album`.`id`';
  214. break;
  215. case 'artist':
  216. $sql = "SELECT `artist`.`id`, SUM(`song`.`size`) AS `size`, SUM(`song`.`time`) AS `time` FROM `artist` ";
  217. if (! $search_info || ! $search_info['join']['song']) {
  218. $sql .= "LEFT JOIN `song` ON `song`.`artist`=`artist`.`id` ";
  219. }
  220. if ($search_info) {
  221. $sql .= $search_info['table_sql'];
  222. }
  223. if (AmpConfig::get('catalog_disable')) {
  224. $sql .= " LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog`";
  225. $sql .= " WHERE `catalog`.`enabled` = '1'";
  226. }
  227. if ($search_info) {
  228. if (AmpConfig::get('catalog_disable')) {
  229. $sql .= ' AND ' . $search_info['where_sql'];
  230. } else {
  231. $sql .= ' WHERE ' . $search_info['where_sql'];
  232. }
  233. }
  234. $sql .= ' GROUP BY `artist`.`id`';
  235. break;
  236. }
  237. $sql .= " ORDER BY RAND() $limit_sql";
  238. // Run the query generated above so we can while it
  239. $db_results = Dba::read($sql);
  240. $results = array();
  241. $size_total = 0;
  242. $fuzzy_size = 0;
  243. $time_total = 0;
  244. $fuzzy_time = 0;
  245. while ($row = Dba::fetch_assoc($db_results)) {
  246. // If size limit is specified
  247. if ($data['size_limit']) {
  248. // Convert
  249. $new_size = ($row['size'] / 1024) / 1024;
  250. // Only fuzzy 100 times
  251. if ($fuzzy_size > 100) {
  252. break;
  253. }
  254. // Add and check, skip if over size
  255. if (($size_total + $new_size) > $data['size_limit']) {
  256. $fuzzy_size++;
  257. continue;
  258. }
  259. $size_total = $size_total + $new_size;
  260. $results[] = $row['id'];
  261. // If we are within 4mb of target then jump ship
  262. if (($data['size_limit'] - floor($size_total)) < 4) {
  263. break; }
  264. } // if size_limit
  265. // If length really does matter
  266. if ($data['length']) {
  267. // base on min, seconds are for chumps and chumpettes
  268. $new_time = floor($row['time'] / 60);
  269. if ($fuzzy_time > 100) {
  270. break;;
  271. }
  272. // If the new one would go over skip!
  273. if (($time_total + $new_time) > $data['length']) {
  274. $fuzzy_time++;
  275. continue;
  276. }
  277. $time_total = $time_total + $new_time;
  278. $results[] = $row['id'];
  279. // If there are less then 2 min of free space return
  280. if (($data['length'] - $time_total) < 2) {
  281. return $results;
  282. }
  283. } // if length does matter
  284. if (!$data['size_limit'] && !$data['length']) {
  285. $results[] = $row['id'];
  286. }
  287. } // end while results
  288. switch ($type) {
  289. case 'song':
  290. return $results;
  291. case 'album':
  292. $songs = array();
  293. foreach ($results as $result) {
  294. $album = new Album($result);
  295. $songs = array_merge($songs, $album->get_songs());
  296. }
  297. return $songs;
  298. case 'artist':
  299. $songs = array();
  300. foreach ($results as $result) {
  301. $artist = new Artist($result);
  302. $songs = array_merge($songs, $artist->get_songs());
  303. }
  304. return $songs;
  305. default:
  306. return false;
  307. }
  308. } // advanced
  309. } //end of random class