com.lokorin.lokorin.lib
[ class tree: com.lokorin.lokorin.lib ] [ index: com.lokorin.lokorin.lib ] [ all elements ]

Source for file lib_downloads.php

Documentation is available at lib_downloads.php

  1. <?php
  2. /*
  3. * Lokorin.com
  4. * Copyright 2004-2006
  5. * Licensed under the GNU LGPL. See COPYING for full terms.
  6. */
  7. /**
  8. * A library that contains everything that is connected with downloads.
  9. * @author Andreas Launila
  10. * @version $Revision: 1.12 $
  11. * @package com.lokorin.lokorin.lib
  12. * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  13. */
  14.  
  15. /**
  16. * For access to common constants and functions.
  17. */
  18. require_once('common.php');
  19. CssHandler::getInstance()->includeCss('downloads');
  20.  
  21. /**
  22. * Gets all download items that match a specified sql selector, grouped by
  23. * their download category.
  24. * @param string $sqlSelector The sql selector that describes which download
  25. * items should be retrieved.
  26. * @return array An array where the key is an unique identifier for a download
  27. * category and the corresponding value is an array of DownloadItem
  28. * instances, where each such instance represents a downloadable item in
  29. * the category.
  30. * @access public
  31. */
  32. function getDownloadsGroupedByCategory($sqlSelector) {
  33. global $db;
  34. $result = $db->query("SELECT ".TABLE_DOWNLOADS.".id, category_id ".
  35. "FROM ".TABLE_DOWNLOADS." LEFT JOIN ".TABLE_DOWNLOAD_CATEGORIES." ".
  36. "ON category_id = ".TABLE_DOWNLOAD_CATEGORIES.".id ".
  37. $sqlSelector." ORDER BY priority DESC");
  38. $categories = array();
  39. $downloads = array();
  40. while(list($downloadId, $categoryId) = mysql_fetch_row($result)) {
  41. if(!isset($downloads[$categoryId])) {
  42. //The category doesn't exist, create an array for it.
  43. $downloads[$categoryId] = array();
  44. }
  45. $downloads[$categoryId][] = new DownloadItem($downloadId);
  46. }
  47. return $downloads;
  48. }
  49.  
  50. /**
  51. * Sorts downloads descendingly based on their popularity.
  52. * @param array $downloads The downloads that should be sorted.
  53. * @return array The downloads ordered descendingly by popularity.
  54. * @access public
  55. */
  56. function sortDownloadsByPopularity($downloads) {
  57. //Get the number of hits for each downloadable item.
  58. $hits = array();
  59. foreach($downloads as $k => $download) {
  60. try {
  61. $counter = $download->getCounter();
  62. $hits[$k] = $counter->getHits();
  63. } catch(Exception $e) {
  64. //There is no counter, meaning 0 hits.
  65. $hits[$k] = 0;
  66. }
  67. }
  68. //Sort based on the number of hits.
  69. array_multisort($hits, $downloads);
  70. $downloads = array_reverse($downloads);
  71. return $downloads;
  72. }
  73.  
  74. /**
  75. * Gets a list of all download categories names.
  76. * @return array Key is the id, value is the name of the corresponding download
  77. * category.
  78. * @access public
  79. */
  80. function getAllDownloadCategoryNames() {
  81. global $db;
  82. $fields = array(
  83. 'id',
  84. 'name'
  85. );
  86. $rows = $db->querySelect(TABLE_DOWNLOAD_CATEGORIES, $fields);
  87. $names = array();
  88. foreach($rows as $row) {
  89. $names[$row['id']] = $row['name'];
  90. }
  91. return $names;
  92. }
  93.  
  94. /**
  95. * Describes a download item. An file that is connected to a project and
  96. * that can be downloaded from the site
  97. * @author Andreas Launila
  98. * @package com.lokorin.lokorin.lib
  99. */
  100. class DownloadItem extends TableEntry {
  101. /**
  102. * The name of the item. The name does not reference the actual file that
  103. * the download item is connected to, rather it is a short description of
  104. * what the connected file actually is.
  105. * @var string
  106. */
  107. private $name;
  108. /**
  109. * The absolute path on the server filesystem for the downloadable item.
  110. * @var string
  111. */
  112. private $filePath;
  113. /**
  114. * The unique identifier of the project that the download item is connected
  115. * to.
  116. * @var integer
  117. */
  118. private $projectId;
  119. /**
  120. * An optional version string, describing the current version of the
  121. * downloadable item.
  122. * @var string
  123. */
  124. private $version;
  125. /**
  126. * A description of what the item actually contains, what it can be used
  127. * for and so on.
  128. * @var string
  129. */
  130. private $description;
  131. /**
  132. * The unique identifier for the language that was used to create the
  133. * download item.
  134. * @var integer
  135. */
  136. private $langId;
  137. /**
  138. * The unique identifier for the counter (of any) that is connected to the
  139. * download item. The counter is increase once for every time the item us
  140. * downloaded.
  141. * @var integer
  142. */
  143. private $counterId;
  144. /**
  145. * Constructor for DownloadItem.
  146. * @param integer $id The unique identifier for the download item.
  147. */
  148. public function __construct($id) {
  149. $fields = array(
  150. 'name',
  151. 'file_name',
  152. 'project_id',
  153. 'version',
  154. 'description',
  155. 'lang_id',
  156. 'counter_id'
  157. );
  158. parent::__construct(TABLE_DOWNLOADS, $id, $fields);
  159. }
  160. /**
  161. * @see com.lokorin.lokorin.includes.TableEntry.readRow($row)
  162. */
  163. protected function readRow($row) {
  164. $this->name = $row['name'];
  165. $this->filePath = DOC_ROOT.FOLDER_DOWNLOADS.$row['file_name'];
  166. $this->projectId = $row['project_id'];
  167. $this->version = $row['version'];
  168. $this->description = $row['description'];
  169. $this->langId = $row['lang_id'];
  170. $this->counterId = $row['counter_id'];
  171. //Make sure that the file actually exists.
  172. if(!file_exists($this->filePath)) {
  173. logFatalException(new FileNotFoundException('DownloadItem The file ('.
  174. $this->filePath.') does not exist.'));
  175. }
  176. }
  177. /**
  178. * Gets the name of the download item. The name is a short description of
  179. * what the associated file actually is.
  180. * @return string A describing name.
  181. */
  182. public function getName() {
  183. $name = $this->name;
  184. if(strlen($this->version) != 0) {
  185. $name .= ' v'.$this->version;
  186. }
  187. return $name;
  188. }
  189. /**
  190. * Gets the size of the file that is connected to the download item in
  191. * kilobytes.
  192. * @return integer The number of kilobytes that the connected file
  193. * occupies.
  194. */
  195. public function getSize() {
  196. return round(filesize($this->filePath)/1024);
  197. }
  198. /**
  199. * Gets the size of the file along with the unit, i.e. 'kB', 'MB' and so
  200. * on. Which unit is used is decided by the size of the file in the
  201. * following way (the ranges are in kB):
  202. * <ul>
  203. * <li>[0, 1000): kB (no decimals)</li>
  204. * <li>[1000, 10000): MB (two decimals precision)</li>
  205. * <li>[10000, 100000): MB (one decomals precision)</li>
  206. * <li>[100000, 1000000): MB (no decimals)</li>
  207. * <li>[1000000, infinity): GB (two decimals precision)</li>
  208. * </ul>
  209. */
  210. public function getSizeLabel() {
  211. $size = $this->getSize();
  212. if($size < 0) {
  213. logException(new IllegalStateException('DownloadItem File ('.
  214. $file->path.') has a negative size.'));
  215. return 'Unknown';
  216. } else if($size < 1000) {
  217. return $size.' kB';
  218. } else if($size < 10000) {
  219. return round($size / 1024, 2).' MB';
  220. } else if($size < 100000) {
  221. return round($size / 1024, 1).' MB';
  222. } else if($size < 1000000) {
  223. return round($size / 1024).' MB';
  224. } else {
  225. return round($size / (1024 * 1024), 2).' GB';
  226. }
  227. }
  228. /**
  229. * Gets a description of the download item. The description describes what
  230. * the file actually contains, along with any notes regarding it.
  231. * @return string A description.
  232. */
  233. public function getDescription() {
  234. return $this->description;
  235. }
  236. /**
  237. * Gets the programming language of the download item.
  238. * @return ProgrammingLanguage The ProgrammingLanguage instance that
  239. * represents the language that is used for the download item.
  240. */
  241. public function getLanguage() {
  242. doInclude('lib_languages');
  243. return new ProgrammingLanguage($this->langId);
  244. }
  245. /**
  246. * Downloads the download item.
  247. */
  248. public function download() {
  249. //Increase the counter if there is one.
  250. doInclude('lib_counters');
  251. try {
  252. $counter = new Counter($this->counterId);
  253. $counter->recordHit();
  254. } catch(Exception $e) {}
  255. //Download the item.
  256. header('Location: '.str_replace($_SERVER['DOCUMENT_ROOT'], '', $this->filePath));
  257. }
  258. /**
  259. * Gets the project that this download item is connected to.
  260. * @return Project The Project instance that represents the project that
  261. * the download item is connected to.
  262. */
  263. public function getProject() {
  264. return new Project($this->projectId);
  265. }
  266. /**
  267. * Gets the counter (if any) associated with the download.
  268. * @return Counter The associated counter. Use isValid() to check if it is
  269. * indeed valid or if the download had no counter.
  270. */
  271. public function getCounter() {
  272. doInclude('lib_counters');
  273. return new Counter($this->counterId);
  274. }
  275. }
  276.  
  277. /**
  278. * Describes a download category. Download items are connected to a download
  279. * category and can be grouped by it.
  280. * @author Andreas Launila
  281. * @package com.lokorin.lokorin.lib
  282. */
  283. class DownloadCategory extends TableEntry {
  284. /**
  285. * The name of the category, a few words that describes it.
  286. * @var string
  287. */
  288. private $name;
  289. /**
  290. * The priority of the category, a higher priority means that it is
  291. * displayed earlier than an category with lower priority.
  292. */
  293. private $priority;
  294. /**
  295. * A short description of the category, may be empty.
  296. */
  297. private $description;
  298. /**
  299. * Constructor for DownloadCategory.
  300. * @param integer $id The unique identifier for the download category.
  301. */
  302. public function __construct($id) {
  303. $fields = array(
  304. 'name',
  305. 'priority',
  306. 'description'
  307. );
  308. parent::__construct(TABLE_DOWNLOAD_CATEGORIES, $id, $fields);
  309. }
  310. /**
  311. * @see com.lokorin.lokorin.includes.TableEntry.readRow($row)
  312. */
  313. protected function readRow($row) {
  314. $this->name = $row['name'];
  315. $this->priority = $row['priority'];
  316. $this->description = $row['description'];
  317. }
  318. /**
  319. * Gets the name of the category.
  320. * @return string A category name.
  321. */
  322. public function getName() {
  323. return $this->name;
  324. }
  325. /**
  326. * Gets the description of the category.
  327. * @return string A short category description.
  328. */
  329. public function getDescription() {
  330. return $this->description;
  331. }
  332. }
  333. ?>

Documentation generated on Sun, 16 Apr 2006 21:03:20 +0200 by phpDocumentor 1.3.0RC4