- <?php
- /*
- * Lokorin.com
- * Copyright 2004-2006
- * Licensed under the GNU LGPL. See COPYING for full terms.
- */
- /**
- * A library that contains everything that is connected with downloads.
- * @author Andreas Launila
- * @version $Revision: 1.12 $
- * @package com.lokorin.lokorin.lib
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
- */
-
- /**
- * For access to common constants and functions.
- */
- require_once('common.php');
- CssHandler::getInstance()->includeCss('downloads');
-
- /**
- * Gets all download items that match a specified sql selector, grouped by
- * their download category.
- * @param string $sqlSelector The sql selector that describes which download
- * items should be retrieved.
- * @return array An array where the key is an unique identifier for a download
- * category and the corresponding value is an array of DownloadItem
- * instances, where each such instance represents a downloadable item in
- * the category.
- * @access public
- */
- function getDownloadsGroupedByCategory($sqlSelector) {
- global $db;
-
- $result = $db->query("SELECT ".TABLE_DOWNLOADS.".id, category_id ".
- "FROM ".TABLE_DOWNLOADS." LEFT JOIN ".TABLE_DOWNLOAD_CATEGORIES." ".
- "ON category_id = ".TABLE_DOWNLOAD_CATEGORIES.".id ".
- $sqlSelector." ORDER BY priority DESC");
- $categories = array();
- $downloads = array();
- while(list($downloadId, $categoryId) = mysql_fetch_row($result)) {
- if(!isset($downloads[$categoryId])) {
- //The category doesn't exist, create an array for it.
- $downloads[$categoryId] = array();
- }
- $downloads[$categoryId][] = new DownloadItem($downloadId);
- }
- return $downloads;
- }
-
- /**
- * Sorts downloads descendingly based on their popularity.
- * @param array $downloads The downloads that should be sorted.
- * @return array The downloads ordered descendingly by popularity.
- * @access public
- */
- function sortDownloadsByPopularity($downloads) {
- //Get the number of hits for each downloadable item.
- $hits = array();
- foreach($downloads as $k => $download) {
- try {
- $counter = $download->getCounter();
- $hits[$k] = $counter->getHits();
- } catch(Exception $e) {
- //There is no counter, meaning 0 hits.
- $hits[$k] = 0;
- }
- }
-
- //Sort based on the number of hits.
- array_multisort($hits, $downloads);
- $downloads = array_reverse($downloads);
- return $downloads;
- }
-
- /**
- * Gets a list of all download categories names.
- * @return array Key is the id, value is the name of the corresponding download
- * category.
- * @access public
- */
- function getAllDownloadCategoryNames() {
- global $db;
-
- $fields = array(
- 'id',
- 'name'
- );
- $rows = $db->querySelect(TABLE_DOWNLOAD_CATEGORIES, $fields);
- $names = array();
- foreach($rows as $row) {
- $names[$row['id']] = $row['name'];
- }
-
- return $names;
- }
-
- /**
- * Describes a download item. An file that is connected to a project and
- * that can be downloaded from the site
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class DownloadItem extends TableEntry {
- /**
- * The name of the item. The name does not reference the actual file that
- * the download item is connected to, rather it is a short description of
- * what the connected file actually is.
- * @var string
- */
- private $name;
- /**
- * The absolute path on the server filesystem for the downloadable item.
- * @var string
- */
- private $filePath;
- /**
- * The unique identifier of the project that the download item is connected
- * to.
- * @var integer
- */
- private $projectId;
- /**
- * An optional version string, describing the current version of the
- * downloadable item.
- * @var string
- */
- private $version;
- /**
- * A description of what the item actually contains, what it can be used
- * for and so on.
- * @var string
- */
- private $description;
- /**
- * The unique identifier for the language that was used to create the
- * download item.
- * @var integer
- */
- private $langId;
- /**
- * The unique identifier for the counter (of any) that is connected to the
- * download item. The counter is increase once for every time the item us
- * downloaded.
- * @var integer
- */
- private $counterId;
-
- /**
- * Constructor for DownloadItem.
- * @param integer $id The unique identifier for the download item.
- */
- public function __construct($id) {
- $fields = array(
- 'name',
- 'file_name',
- 'project_id',
- 'version',
- 'description',
- 'lang_id',
- 'counter_id'
- );
- parent::__construct(TABLE_DOWNLOADS, $id, $fields);
- }
-
- /**
- * @see com.lokorin.lokorin.includes.TableEntry.readRow($row)
- */
- protected function readRow($row) {
- $this->name = $row['name'];
- $this->filePath = DOC_ROOT.FOLDER_DOWNLOADS.$row['file_name'];
- $this->projectId = $row['project_id'];
- $this->version = $row['version'];
- $this->description = $row['description'];
- $this->langId = $row['lang_id'];
- $this->counterId = $row['counter_id'];
-
- //Make sure that the file actually exists.
- if(!file_exists($this->filePath)) {
- logFatalException(new FileNotFoundException('DownloadItem The file ('.
- $this->filePath.') does not exist.'));
- }
- }
-
- /**
- * Gets the name of the download item. The name is a short description of
- * what the associated file actually is.
- * @return string A describing name.
- */
- public function getName() {
- $name = $this->name;
- if(strlen($this->version) != 0) {
- $name .= ' v'.$this->version;
- }
- return $name;
- }
-
- /**
- * Gets the size of the file that is connected to the download item in
- * kilobytes.
- * @return integer The number of kilobytes that the connected file
- * occupies.
- */
- public function getSize() {
- return round(filesize($this->filePath)/1024);
- }
-
- /**
- * Gets the size of the file along with the unit, i.e. 'kB', 'MB' and so
- * on. Which unit is used is decided by the size of the file in the
- * following way (the ranges are in kB):
- * <ul>
- * <li>[0, 1000): kB (no decimals)</li>
- * <li>[1000, 10000): MB (two decimals precision)</li>
- * <li>[10000, 100000): MB (one decomals precision)</li>
- * <li>[100000, 1000000): MB (no decimals)</li>
- * <li>[1000000, infinity): GB (two decimals precision)</li>
- * </ul>
- */
- public function getSizeLabel() {
- $size = $this->getSize();
- if($size < 0) {
- logException(new IllegalStateException('DownloadItem File ('.
- $file->path.') has a negative size.'));
- return 'Unknown';
- } else if($size < 1000) {
- return $size.' kB';
- } else if($size < 10000) {
- return round($size / 1024, 2).' MB';
- } else if($size < 100000) {
- return round($size / 1024, 1).' MB';
- } else if($size < 1000000) {
- return round($size / 1024).' MB';
- } else {
- return round($size / (1024 * 1024), 2).' GB';
- }
- }
-
- /**
- * Gets a description of the download item. The description describes what
- * the file actually contains, along with any notes regarding it.
- * @return string A description.
- */
- public function getDescription() {
- return $this->description;
- }
-
- /**
- * Gets the programming language of the download item.
- * @return ProgrammingLanguage The ProgrammingLanguage instance that
- * represents the language that is used for the download item.
- */
- public function getLanguage() {
- doInclude('lib_languages');
- return new ProgrammingLanguage($this->langId);
- }
-
- /**
- * Downloads the download item.
- */
- public function download() {
- //Increase the counter if there is one.
- doInclude('lib_counters');
- try {
- $counter = new Counter($this->counterId);
- $counter->recordHit();
- } catch(Exception $e) {}
- //Download the item.
- header('Location: '.str_replace($_SERVER['DOCUMENT_ROOT'], '', $this->filePath));
- }
-
- /**
- * Gets the project that this download item is connected to.
- * @return Project The Project instance that represents the project that
- * the download item is connected to.
- */
- public function getProject() {
- return new Project($this->projectId);
- }
-
- /**
- * Gets the counter (if any) associated with the download.
- * @return Counter The associated counter. Use isValid() to check if it is
- * indeed valid or if the download had no counter.
- */
- public function getCounter() {
- doInclude('lib_counters');
- return new Counter($this->counterId);
- }
- }
-
- /**
- * Describes a download category. Download items are connected to a download
- * category and can be grouped by it.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class DownloadCategory extends TableEntry {
- /**
- * The name of the category, a few words that describes it.
- * @var string
- */
- private $name;
- /**
- * The priority of the category, a higher priority means that it is
- * displayed earlier than an category with lower priority.
- */
- private $priority;
- /**
- * A short description of the category, may be empty.
- */
- private $description;
-
- /**
- * Constructor for DownloadCategory.
- * @param integer $id The unique identifier for the download category.
- */
- public function __construct($id) {
- $fields = array(
- 'name',
- 'priority',
- 'description'
- );
- parent::__construct(TABLE_DOWNLOAD_CATEGORIES, $id, $fields);
- }
-
- /**
- * @see com.lokorin.lokorin.includes.TableEntry.readRow($row)
- */
- protected function readRow($row) {
- $this->name = $row['name'];
- $this->priority = $row['priority'];
- $this->description = $row['description'];
- }
-
- /**
- * Gets the name of the category.
- * @return string A category name.
- */
- public function getName() {
- return $this->name;
- }
-
- /**
- * Gets the description of the category.
- * @return string A short category description.
- */
- public function getDescription() {
- return $this->description;
- }
- }
- ?>