mirror of
https://github.com/Yetangitu/ampache
synced 2025-10-03 01:39:28 +02:00
1087 lines
31 KiB
PHP
1087 lines
31 KiB
PHP
<?php
|
||
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||
/**
|
||
*
|
||
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||
* Copyright 2001 - 2016 Ampache.org
|
||
*
|
||
* This program is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU Affero General Public License as published by
|
||
* the Free Software Foundation, either version 3 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU Affero General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU Affero General Public License
|
||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*
|
||
*/
|
||
|
||
/**
|
||
* Album Class
|
||
*
|
||
* This is the class responsible for handling the Album object
|
||
* it is related to the album table in the database.
|
||
*
|
||
*/
|
||
class Album extends database_object implements library_item
|
||
{
|
||
/* Variables from DB */
|
||
|
||
/**
|
||
* @var int $id
|
||
*/
|
||
public $id;
|
||
/**
|
||
* @var string $name
|
||
*/
|
||
public $name;
|
||
/**
|
||
* @var int $album_artist
|
||
*/
|
||
public $album_artist;
|
||
/**
|
||
* @var int $disk
|
||
*/
|
||
public $disk;
|
||
/**
|
||
* @var int $year
|
||
*/
|
||
public $year;
|
||
/**
|
||
* @var string $prefix
|
||
*/
|
||
public $prefix;
|
||
/**
|
||
* @var string $mbid
|
||
*/
|
||
public $mbid; // MusicBrainz ID
|
||
/**
|
||
* @var string $mbid_group
|
||
*/
|
||
public $mbid_group; // MusicBrainz Release Group ID
|
||
/**
|
||
* @var string $release_type
|
||
*/
|
||
public $release_type;
|
||
|
||
/**
|
||
* @var int $catalog_id
|
||
*/
|
||
public $catalog_id;
|
||
/**
|
||
* @var int $song_count
|
||
*/
|
||
public $song_count;
|
||
/**
|
||
* @var string $artist_prefix
|
||
*/
|
||
public $artist_prefix;
|
||
/**
|
||
* @var string $artist_name
|
||
*/
|
||
public $artist_name;
|
||
/**
|
||
* @var int $artist_id
|
||
*/
|
||
public $artist_id;
|
||
/**
|
||
* @var array $tags
|
||
*/
|
||
public $tags;
|
||
/**
|
||
* @var string $full_name
|
||
*/
|
||
public $full_name; // Prefix + Name, generated
|
||
/**
|
||
* @var int $artist_count
|
||
*/
|
||
public $artist_count;
|
||
/**
|
||
* @var string $f_artist_name
|
||
*/
|
||
public $f_artist_name;
|
||
/**
|
||
* @var string $f_artist_link
|
||
*/
|
||
public $f_artist_link;
|
||
/**
|
||
* @var string $f_artist
|
||
*/
|
||
public $f_artist;
|
||
/**
|
||
* @var string $album_artist_name
|
||
*/
|
||
public $album_artist_name;
|
||
/**
|
||
* @var string $f_album_artist_name
|
||
*/
|
||
public $f_album_artist_name;
|
||
/**
|
||
* @var string $f_album_artist_link
|
||
*/
|
||
public $f_album_artist_link;
|
||
/**
|
||
* @var string $f_name
|
||
*/
|
||
public $f_name;
|
||
/**
|
||
* @var string $link
|
||
*/
|
||
public $link;
|
||
/**
|
||
* @var string $f_link
|
||
*/
|
||
public $f_link;
|
||
/**
|
||
* @var string $f_tags
|
||
*/
|
||
public $f_tags;
|
||
/**
|
||
* @var string $f_year
|
||
*/
|
||
public $f_year;
|
||
/**
|
||
* @var string $f_title
|
||
*/
|
||
public $f_title;
|
||
/**
|
||
* @var string $f_release_type
|
||
*/
|
||
public $f_release_type;
|
||
|
||
// cached information
|
||
/**
|
||
* @var boolean $_fake
|
||
*/
|
||
public $_fake;
|
||
/**
|
||
* @var array $_songs
|
||
*/
|
||
public $_songs = array();
|
||
/**
|
||
* @var array $_mapcache
|
||
*/
|
||
private static $_mapcache = array();
|
||
|
||
/**
|
||
* @var array $album_suite
|
||
*/
|
||
public $album_suite = array();
|
||
/**
|
||
* @var boolean $allow_group_disks
|
||
*/
|
||
public $allow_group_disks = false;
|
||
|
||
/**
|
||
* __construct
|
||
* Album constructor it loads everything relating
|
||
* to this album from the database it does not
|
||
* pull the album or thumb art by default or
|
||
* get any of the counts.
|
||
* @param int|null $id
|
||
*/
|
||
public function __construct($id=null)
|
||
{
|
||
if (!$id) {
|
||
return false;
|
||
}
|
||
|
||
/* Get the information from the db */
|
||
$info = $this->get_info($id);
|
||
|
||
// Foreach what we've got
|
||
foreach ($info as $key=>$value) {
|
||
$this->$key = $value;
|
||
}
|
||
|
||
// Little bit of formatting here
|
||
$this->full_name = trim(trim($info['prefix']) . ' ' . trim($info['name']));
|
||
|
||
// Looking for other albums with same mbid, ordering by disk ascending
|
||
if ($this->disk && !empty($this->mbid) && AmpConfig::get('album_group')) {
|
||
$this->album_suite = $this->get_album_suite();
|
||
}
|
||
|
||
return true;
|
||
} // constructor
|
||
|
||
/**
|
||
* construct_from_array
|
||
* This is often used by the metadata class, it fills out an album object from a
|
||
* named array, _fake is set to true
|
||
* @param array $data
|
||
* @return Album
|
||
*/
|
||
public static function construct_from_array(array $data)
|
||
{
|
||
$album = new Album(0);
|
||
foreach ($data as $key=>$value) {
|
||
$album->$key = $value;
|
||
}
|
||
|
||
$album->_fake = true; // Make sure that we tell em it's fake
|
||
|
||
return $album;
|
||
} // construct_from_array
|
||
|
||
/**
|
||
* gc
|
||
*
|
||
* Cleans out unused albums
|
||
*/
|
||
public static function gc()
|
||
{
|
||
Dba::write('DELETE FROM `album` USING `album` LEFT JOIN `song` ON `song`.`album` = `album`.`id` WHERE `song`.`id` IS NULL');
|
||
}
|
||
|
||
/**
|
||
* build_cache
|
||
* This takes an array of object ids and caches all of their information
|
||
* with a single query
|
||
* @param array $ids
|
||
* @return boolean
|
||
*/
|
||
public static function build_cache(array $ids)
|
||
{
|
||
// Nothing to do if they pass us nothing
|
||
if (!is_array($ids) or !count($ids)) {
|
||
return false;
|
||
}
|
||
|
||
$idlist = '(' . implode(',', $ids) . ')';
|
||
|
||
$sql = "SELECT * FROM `album` WHERE `id` IN $idlist";
|
||
$db_results = Dba::read($sql);
|
||
|
||
while ($row = Dba::fetch_assoc($db_results)) {
|
||
parent::add_to_cache('album', $row['id'], $row);
|
||
}
|
||
|
||
return true;
|
||
} // build_cache
|
||
|
||
/**
|
||
* _get_extra_info
|
||
* This pulls the extra information from our tables, this is a 3 table join, which is why we don't normally
|
||
* do it
|
||
* @return array
|
||
*/
|
||
private function _get_extra_info($limit_threshold = '')
|
||
{
|
||
if (!$this->id) {
|
||
return array();
|
||
}
|
||
|
||
if (parent::is_cached('album_extra', $this->id)) {
|
||
return parent::get_from_cache('album_extra', $this->id);
|
||
}
|
||
|
||
// Calculation
|
||
$sql = "SELECT " .
|
||
"COUNT(DISTINCT(`song`.`artist`)) AS `artist_count`, " .
|
||
"COUNT(`song`.`id`) AS `song_count`, " .
|
||
"SUM(`song`.`time`) as `total_duration` " .
|
||
"FROM `song` ";
|
||
|
||
$sqlj = '';
|
||
if (AmpConfig::get('catalog_disable')) {
|
||
$sqlj = "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog` ";
|
||
}
|
||
|
||
$suite_array = array();
|
||
if ($this->allow_group_disks) {
|
||
$suite_array = $this->album_suite;
|
||
}
|
||
if (!count($suite_array)) {
|
||
$suite_array[] = $this->id;
|
||
}
|
||
|
||
$idlist = '(' . implode(',', $suite_array) . ')';
|
||
$sqlw = "WHERE `song`.`album` IN $idlist ";
|
||
|
||
if (AmpConfig::get('catalog_disable')) {
|
||
$sqlw .= "AND `catalog`.`enabled` = '1' ";
|
||
}
|
||
$sql .= $sqlj . $sqlw;
|
||
if (!count($this->album_suite)) {
|
||
$sql .= "GROUP BY `song`.`album` ";
|
||
} else {
|
||
$sql .= "GROUP BY `song`.`artist` ";
|
||
}
|
||
|
||
$db_results = Dba::read($sql);
|
||
$results = Dba::fetch_assoc($db_results);
|
||
|
||
|
||
// Get associated information from first song only
|
||
$sql = "SELECT " .
|
||
"`song`.`catalog` as `catalog_id`," .
|
||
"`artist`.`name` AS `artist_name`, " .
|
||
"`artist`.`prefix` AS `artist_prefix`, " .
|
||
"`artist`.`id` AS `artist_id` " .
|
||
"FROM `song` INNER JOIN `artist` " .
|
||
"ON `artist`.`id`=`song`.`artist` ";
|
||
$sql .= $sqlj . $sqlw . "LIMIT 1";
|
||
|
||
$db_results = Dba::read($sql);
|
||
$results = array_merge($results, Dba::fetch_assoc($db_results));
|
||
|
||
$art = new Art($this->id, 'album');
|
||
$art->get_db();
|
||
$results['has_art'] = make_bool($art->raw);
|
||
$results['has_thumb'] = make_bool($art->thumb);
|
||
|
||
if (AmpConfig::get('show_played_times')) {
|
||
$results['object_cnt'] = Stats::get_object_count('album', $this->id, $limit_threshold);
|
||
}
|
||
|
||
parent::add_to_cache('album_extra', $this->id, $results);
|
||
|
||
return $results;
|
||
} // _get_extra_info
|
||
|
||
public function can_edit($user = null)
|
||
{
|
||
if (!$user) {
|
||
$user = $GLOBALS['user']->id;
|
||
}
|
||
|
||
if (!$user) {
|
||
return false;
|
||
}
|
||
|
||
if ($this->user !== null && $user == $this->user) {
|
||
return true;
|
||
}
|
||
|
||
if (Access::check('interface', 50, $user)) {
|
||
return true;
|
||
}
|
||
|
||
if (!$this->album_artist) {
|
||
return false;
|
||
}
|
||
|
||
if (!AmpConfig::get('upload_allow_edit')) {
|
||
return false;
|
||
}
|
||
|
||
$owner = $this->get_user_owner();
|
||
return ($owner && $owner === $user);
|
||
}
|
||
|
||
/**
|
||
* check
|
||
*
|
||
* Searches for an album; if none is found, insert a new one.
|
||
* @param string $name
|
||
* @param int $year
|
||
* @param int $disk
|
||
* @param string $mbid
|
||
* @param string $mbid_group
|
||
* @param string $album_artist
|
||
* @param string $release_type
|
||
* @param boolean $readonly
|
||
* @return int|null
|
||
*/
|
||
public static function check($name, $year = 0, $disk = 0, $mbid = null, $mbid_group = null, $album_artist = null, $release_type = null, $readonly = false)
|
||
{
|
||
$trimmed = Catalog::trim_prefix(trim($name));
|
||
$name = $trimmed['string'];
|
||
$prefix = $trimmed['prefix'];
|
||
$album_artist = intval($album_artist);
|
||
$album_artist = ($album_artist <= 0) ? null : $album_artist;
|
||
$mbid = empty($mbid) ? null : $mbid;
|
||
$mbid_group = empty($mbid_group) ? null : $mbid_group;
|
||
$release_type = empty($release_type) ? null : $release_type;
|
||
|
||
// Not even sure if these can be negative, but better safe than llama.
|
||
$year = Catalog::normalize_year($year);
|
||
$disk = abs(intval($disk));
|
||
|
||
if (!$name) {
|
||
$name = T_('Unknown (Orphaned)');
|
||
$year = 0;
|
||
$disk = 0;
|
||
$album_artist = null;
|
||
}
|
||
if (isset(self::$_mapcache[$name][$disk][$mbid][$album_artist])) {
|
||
return self::$_mapcache[$name][$disk][$mbid][$album_artist];
|
||
}
|
||
|
||
$sql = 'SELECT `album`.`id` FROM `album` WHERE `album`.`name` = ? AND `album`.`disk` = ? ';
|
||
$params = array($name, $disk);
|
||
|
||
if ($mbid) {
|
||
$sql .= 'AND `album`.`mbid` = ? ';
|
||
$params[] = $mbid;
|
||
} else {
|
||
$sql .= 'AND `album`.`mbid` IS NULL ';
|
||
}
|
||
if ($prefix) {
|
||
$sql .= 'AND `album`.`prefix` = ? ';
|
||
$params[] = $prefix;
|
||
}
|
||
|
||
if ($album_artist) {
|
||
$sql .= 'AND `album`.`album_artist` = ? ';
|
||
$params[] = $album_artist;
|
||
}
|
||
|
||
$db_results = Dba::read($sql, $params);
|
||
|
||
if ($row = Dba::fetch_assoc($db_results)) {
|
||
$id = $row['id'];
|
||
self::$_mapcache[$name][$disk][$mbid][$album_artist] = $id;
|
||
return $id;
|
||
}
|
||
|
||
if ($readonly) {
|
||
return null;
|
||
}
|
||
|
||
$sql = 'INSERT INTO `album` (`name`, `prefix`, `year`, `disk`, `mbid`, `mbid_group`, `release_type`, `album_artist`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)';
|
||
|
||
$db_results = Dba::write($sql, array($name, $prefix, $year, $disk, $mbid, $mbid_group, $release_type, $album_artist));
|
||
if (!$db_results) {
|
||
return null;
|
||
}
|
||
|
||
$id = Dba::insert_id();
|
||
|
||
// Remove from wanted album list if any request on it
|
||
if (!empty($mbid) && AmpConfig::get('wanted')) {
|
||
try {
|
||
Wanted::delete_wanted_release($mbid);
|
||
} catch (Exception $e) {
|
||
debug_event('wanted', 'Cannot process wanted releases auto-removal check: ' . $e->getMessage(), '1');
|
||
}
|
||
}
|
||
|
||
self::$_mapcache[$name][$disk][$mbid][$album_artist] = $id;
|
||
return $id;
|
||
}
|
||
|
||
/**
|
||
* get_songs
|
||
* gets the songs for this album takes an optional limit
|
||
* and an optional artist, if artist is passed it only gets
|
||
* songs with this album + specified artist
|
||
* @param int $limit
|
||
* @param string $artist
|
||
* @return int[]
|
||
*/
|
||
public function get_songs($limit = 0, $artist='')
|
||
{
|
||
$results = array();
|
||
|
||
$sql = "SELECT `song`.`id` FROM `song` ";
|
||
if (AmpConfig::get('catalog_disable')) {
|
||
$sql .= "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog` ";
|
||
}
|
||
$sql .= "WHERE `song`.`album` = ? ";
|
||
$params = array($this->id);
|
||
if (strlen($artist)) {
|
||
$sql .= "AND `artist` = ? ";
|
||
$params[] = $artist;
|
||
}
|
||
if (AmpConfig::get('catalog_disable')) {
|
||
$sql .= "AND `catalog`.`enabled` = '1' ";
|
||
}
|
||
$sql .= "ORDER BY `song`.`track`, `song`.`title`";
|
||
if ($limit) {
|
||
$sql .= " LIMIT " . intval($limit);
|
||
}
|
||
$db_results = Dba::read($sql, $params);
|
||
|
||
while ($r = Dba::fetch_assoc($db_results)) {
|
||
$results[] = $r['id'];
|
||
}
|
||
|
||
return $results;
|
||
} // get_songs
|
||
|
||
/**
|
||
* get_http_album_query_ids
|
||
* return the html album parameters with all album suite ids
|
||
* @param string $url_param_name
|
||
* @return string
|
||
*/
|
||
public function get_http_album_query_ids($url_param_name)
|
||
{
|
||
if ($this->allow_group_disks) {
|
||
$suite_array = $this->get_group_disks_ids();
|
||
} else {
|
||
$suite_array = array($this->id);
|
||
}
|
||
|
||
return http_build_query(array($url_param_name => $suite_array));
|
||
}
|
||
|
||
/**
|
||
* get_group_disks_ids
|
||
* return all album suite ids or current album if no albums
|
||
* @return int[]
|
||
*/
|
||
public function get_group_disks_ids()
|
||
{
|
||
$suite_array = $this->album_suite;
|
||
if (!count($suite_array)) {
|
||
$suite_array[] = $this->id;
|
||
}
|
||
|
||
return $suite_array;
|
||
}
|
||
|
||
/**
|
||
* get_album_suite
|
||
* gets the album ids with the same musicbrainz identifier
|
||
* @param int $catalog
|
||
* return int[]
|
||
*/
|
||
public function get_album_suite($catalog = 0)
|
||
{
|
||
$results = array();
|
||
|
||
$catalog_where = "";
|
||
$catalog_join = "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog`";
|
||
if ($catalog) {
|
||
$catalog_where .= " AND `catalog`.`id` = '$catalog'";
|
||
}
|
||
if (AmpConfig::get('catalog_disable')) {
|
||
$catalog_where .= " AND `catalog`.`enabled` = '1'";
|
||
}
|
||
|
||
$sql = "SELECT DISTINCT `album`.`id`, `album`.`disk` FROM album LEFT JOIN `song` ON `song`.`album`=`album`.`id` $catalog_join " .
|
||
"WHERE `album`.`mbid`='$this->mbid' $catalog_where ORDER BY `album`.`disk` ASC";
|
||
|
||
$db_results = Dba::read($sql);
|
||
|
||
while ($r = Dba::fetch_assoc($db_results)) {
|
||
$results[] = $r['id'];
|
||
}
|
||
|
||
return $results;
|
||
} // get_album_suite
|
||
|
||
/**
|
||
* has_track
|
||
* This checks to see if this album has a track of the specified title
|
||
* @param string $title
|
||
* @return array
|
||
*/
|
||
public function has_track($title)
|
||
{
|
||
$sql = "SELECT `id` FROM `song` WHERE `album` = ? AND `title` = ?";
|
||
$db_results = Dba::read($sql, array($this->id, $title));
|
||
|
||
$data = Dba::fetch_assoc($db_results);
|
||
|
||
return $data;
|
||
} // has_track
|
||
|
||
/**
|
||
* get_addtime_first_song
|
||
* Get the add date of first added song.
|
||
* @return int
|
||
*/
|
||
public function get_addtime_first_song()
|
||
{
|
||
$time = 0;
|
||
|
||
$sql = "SELECT MIN(`addition_time`) FROM `song` WHERE `album` = ?";
|
||
$db_results = Dba::read($sql, array($this->id));
|
||
if ($data = Dba::fetch_row($db_results)) {
|
||
$time = $data[0];
|
||
}
|
||
|
||
return $time;
|
||
}
|
||
|
||
/**
|
||
* format
|
||
* This is the format function for this object. It sets cleaned up
|
||
* album information with the base required
|
||
* f_link, f_name
|
||
*/
|
||
public function format($details = true, $limit_threshold = '')
|
||
{
|
||
$web_path = AmpConfig::get('web_path');
|
||
|
||
if ($details) {
|
||
/* Pull the advanced information */
|
||
$data = $this->_get_extra_info($limit_threshold);
|
||
foreach ($data as $key=>$value) {
|
||
$this->$key = $value;
|
||
}
|
||
|
||
if ($this->album_artist) {
|
||
$Album_artist = new Artist($this->album_artist);
|
||
$Album_artist->format();
|
||
$this->album_artist_name = $Album_artist->name;
|
||
$this->f_album_artist_name = $Album_artist->f_name;
|
||
$this->f_album_artist_link = "<a href=\"" . $web_path . "/artists.php?action=show&artist=" . $this->album_artist . "\" title=\"" . scrub_out($this->album_artist_name) . "\">" . $this->f_album_artist_name . "</a>";
|
||
}
|
||
|
||
$this->tags = Tag::get_top_tags('album', $this->id);
|
||
$this->f_tags = Tag::get_display($this->tags, true, 'album');
|
||
}
|
||
|
||
/* Truncate the string if it's to long */
|
||
$this->f_name = $this->full_name;
|
||
|
||
$this->link = $web_path . '/albums.php?action=show&album=' . scrub_out($this->id);
|
||
$this->f_link = "<a href=\"" . $this->link . "\" title=\"" . scrub_out($this->full_name) . "\">" . scrub_out($this->f_name);
|
||
|
||
// Looking if we need to combine or display disks
|
||
if ($this->disk && (!$this->allow_group_disks || ($this->allow_group_disks && !AmpConfig::get('album_group')))) {
|
||
$this->f_link .= " <span class=\"discnb\">[" . T_('Disk') . " " . $this->disk . "]</span>";
|
||
}
|
||
|
||
$this->f_link .="</a>";
|
||
|
||
$this->f_title = $this->full_name;
|
||
if ($this->artist_count == '1') {
|
||
$artist = trim(trim($this->artist_prefix) . ' ' . trim($this->artist_name));
|
||
$this->f_artist_name = $artist;
|
||
$this->f_artist_link = "<a href=\"$web_path/artists.php?action=show&artist=" . $this->artist_id . "\" title=\"" . scrub_out($this->artist_name) . "\">" . $artist . "</a>";
|
||
$this->f_artist = $artist;
|
||
} else {
|
||
$this->f_artist_link = "<span title=\"$this->artist_count " . T_('Artists') . "\">" . T_('Various') . "</span>";
|
||
$this->f_artist = T_('Various');
|
||
$this->f_artist_name = $this->f_artist;
|
||
}
|
||
|
||
if (!$this->year) {
|
||
$this->f_year = "N/A";
|
||
}
|
||
|
||
$this->f_release_type = ucwords($this->release_type);
|
||
} // format
|
||
|
||
/**
|
||
* Get item keywords for metadata searches.
|
||
* @return array
|
||
*/
|
||
public function get_keywords()
|
||
{
|
||
$keywords = array();
|
||
$keywords['mb_albumid'] = array('important' => false,
|
||
'label' => T_('Album MusicBrainzID'),
|
||
'value' => $this->mbid);
|
||
$keywords['mb_albumid_group'] = array('important' => false,
|
||
'label' => T_('Release Group MusicBrainzID'),
|
||
'value' => $this->mbid_group);
|
||
$keywords['artist'] = array('important' => true,
|
||
'label' => T_('Artist'),
|
||
'value' => (($this->artist_count < 2) ? $this->f_artist_name : ''));
|
||
$keywords['album'] = array('important' => true,
|
||
'label' => T_('Album'),
|
||
'value' => $this->f_name);
|
||
|
||
return $keywords;
|
||
}
|
||
|
||
/**
|
||
* Get item fullname.
|
||
* @return string
|
||
*/
|
||
public function get_fullname()
|
||
{
|
||
return $this->f_name;
|
||
}
|
||
|
||
/**
|
||
* Get parent item description.
|
||
* @return array|null
|
||
*/
|
||
public function get_parent()
|
||
{
|
||
if ($this->artist_count == 1) {
|
||
return array('object_type' => 'artist', 'object_id' => $this->artist_id);
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* Get item childrens.
|
||
* @return array
|
||
*/
|
||
public function get_childrens()
|
||
{
|
||
return $this->get_medias();
|
||
}
|
||
|
||
/**
|
||
* Search for item childrens.
|
||
* @param string $name
|
||
* @return array
|
||
*/
|
||
public function search_childrens($name)
|
||
{
|
||
$search['type'] = "song";
|
||
$search['rule_0_input'] = $name;
|
||
$search['rule_0_operator'] = 4;
|
||
$search['rule_0'] = "title";
|
||
$search['rule_1_input'] = $this->name;
|
||
$search['rule_1_operator'] = 4;
|
||
$search['rule_1'] = "album";
|
||
$search['rule_2_input'] = $this->album_artist_name;
|
||
$search['rule_2_operator'] = 4;
|
||
$search['rule_2'] = "artist";
|
||
$songs = Search::run($search);
|
||
|
||
$childrens = array();
|
||
foreach ($songs as $song) {
|
||
$childrens[] = array(
|
||
'object_type' => 'song',
|
||
'object_id' => $song
|
||
);
|
||
}
|
||
|
||
return $childrens;
|
||
}
|
||
|
||
/**
|
||
* Get all childrens and sub-childrens medias.
|
||
* @param string $filter_type
|
||
* @return array
|
||
*/
|
||
public function get_medias($filter_type = null)
|
||
{
|
||
$medias = array();
|
||
if (!$filter_type || $filter_type == 'song') {
|
||
$songs = $this->get_songs();
|
||
foreach ($songs as $song_id) {
|
||
$medias[] = array(
|
||
'object_type' => 'song',
|
||
'object_id' => $song_id
|
||
);
|
||
}
|
||
}
|
||
return $medias;
|
||
}
|
||
|
||
/**
|
||
* get_catalogs
|
||
*
|
||
* Get all catalog ids related to this item.
|
||
* @return int[]
|
||
*/
|
||
public function get_catalogs()
|
||
{
|
||
return array($this->catalog_id);
|
||
}
|
||
|
||
/**
|
||
* Get item's owner.
|
||
* @return int|null
|
||
*/
|
||
public function get_user_owner()
|
||
{
|
||
if (!$this->album_artist) {
|
||
return null;
|
||
}
|
||
|
||
$artist = new Artist($this->album_artist);
|
||
return $artist->get_user_owner();
|
||
}
|
||
|
||
/**
|
||
* Get default art kind for this item.
|
||
* @return string
|
||
*/
|
||
public function get_default_art_kind()
|
||
{
|
||
return 'default';
|
||
}
|
||
|
||
public function get_description()
|
||
{
|
||
// Album description is not supported yet, always return artist description
|
||
$artist = new Artist($this->artist_id);
|
||
return $artist->get_description();
|
||
}
|
||
|
||
public function display_art($thumb = 2, $force = false)
|
||
{
|
||
$id = null;
|
||
$type = null;
|
||
|
||
if (Art::has_db($this->id, 'album')) {
|
||
$id = $this->id;
|
||
$type = 'album';
|
||
} else {
|
||
if (Art::has_db($this->artist_id, 'artist') || $force) {
|
||
$id = $this->artist_id;
|
||
$type = 'artist';
|
||
}
|
||
}
|
||
|
||
if ($id !== null && $type !== null) {
|
||
$title = '[' . ($this->f_album_artist_name ?: $this->f_artist) . '] ' . $this->f_name;
|
||
Art::display($type, $id, $title, $thumb, $this->link);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* get_random_songs
|
||
* gets a random number, and a random assortment of songs from this album
|
||
* @return int[]
|
||
*/
|
||
public function get_random_songs()
|
||
{
|
||
$sql = "SELECT `song`.`id` FROM `song` ";
|
||
if (AmpConfig::get('catalog_disable')) {
|
||
$sql .= "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog` ";
|
||
}
|
||
$sql .= "WHERE `song`.`album` = ? ";
|
||
if (AmpConfig::get('catalog_disable')) {
|
||
$sql .= "AND `catalog`.`enabled` = '1' ";
|
||
}
|
||
$sql .= "ORDER BY RAND()";
|
||
$db_results = Dba::read($sql, array($this->id));
|
||
|
||
$results = array();
|
||
while ($r = Dba::fetch_row($db_results)) {
|
||
$results[] = $r['0'];
|
||
}
|
||
|
||
return $results;
|
||
} // get_random_songs
|
||
|
||
/**
|
||
* update
|
||
* This function takes a key'd array of data and updates this object
|
||
* as needed
|
||
* @param array $data
|
||
* @return int
|
||
*/
|
||
public function update(array $data)
|
||
{
|
||
$year = isset($data['year']) ? $data['year'] : $this->year;
|
||
$artist = isset($data['artist']) ? intval($data['artist']) : $this->artist_id;
|
||
$album_artist = isset($data['album_artist']) ? intval($data['album_artist']) : $this->album_artist;
|
||
$name = isset($data['name']) ? $data['name'] : $this->name;
|
||
$disk = isset($data['disk']) ? $data['disk']: $this->disk;
|
||
$mbid = isset($data['mbid']) ? $data['mbid'] : $this->mbid;
|
||
$mbid_group = isset($data['mbid_group']) ? $data['mbid_group'] : $this->mbid_group;
|
||
$release_type = isset($data['release_type']) ? $data['release_type'] : $this->release_type;
|
||
|
||
$current_id = $this->id;
|
||
|
||
$updated = false;
|
||
$songs = null;
|
||
if ($artist != $this->artist_id && $artist) {
|
||
// Update every song
|
||
$songs = $this->get_songs();
|
||
foreach ($songs as $song_id) {
|
||
Song::update_artist($artist, $song_id);
|
||
}
|
||
$updated = true;
|
||
Artist::gc();
|
||
}
|
||
|
||
if (!empty($data['album_artist_name'])) {
|
||
// Need to create new artist according the name
|
||
$album_artist = Artist::check($data['album_artist_name']);
|
||
}
|
||
|
||
$album_id = self::check($name, $year, $disk, $mbid, $mbid_group, $album_artist, $release_type);
|
||
if ($album_id != $this->id) {
|
||
if (!is_array($songs)) {
|
||
$songs = $this->get_songs();
|
||
}
|
||
foreach ($songs as $song_id) {
|
||
Song::update_album($album_id, $song_id);
|
||
Song::update_year($year, $song_id);
|
||
Song::write_id3_for_song($song_id);
|
||
}
|
||
$current_id = $album_id;
|
||
$updated = true;
|
||
Stats::migrate('album', $this->id, $album_id);
|
||
Art::migrate('album', $this->id, $album_id);
|
||
self::gc();
|
||
} else {
|
||
Album::update_year($year, $album_id);
|
||
Album::update_mbid_group($mbid_group, $album_id);
|
||
Album::update_release_type($release_type, $album_id);
|
||
}
|
||
$this->year = $year;
|
||
$this->mbid_group = $mbid_group;
|
||
$this->release_type = $release_type;
|
||
$this->name = $name;
|
||
$this->disk = $disk;
|
||
$this->mbid = $mbid;
|
||
$this->album_artist = $album_artist;
|
||
|
||
if ($updated && is_array($songs)) {
|
||
foreach ($songs as $song_id) {
|
||
Song::update_utime($song_id);
|
||
} // foreach song of album
|
||
Stats::gc();
|
||
Rating::gc();
|
||
Userflag::gc();
|
||
Useractivity::gc();
|
||
} // if updated
|
||
|
||
$override_childs = false;
|
||
if ($data['overwrite_childs'] == 'checked') {
|
||
$override_childs = true;
|
||
}
|
||
|
||
$add_to_childs = false;
|
||
if ($data['add_to_childs'] == 'checked') {
|
||
$add_to_childs = true;
|
||
}
|
||
|
||
if (isset($data['edit_tags'])) {
|
||
$this->update_tags($data['edit_tags'], $override_childs, $add_to_childs, $current_id, true);
|
||
}
|
||
|
||
return $current_id;
|
||
} // update
|
||
|
||
/**
|
||
* update_tags
|
||
*
|
||
* Update tags of albums and/or songs
|
||
* @param string $tags_comma
|
||
* @param boolean $override_childs
|
||
* @param boolean $add_to_childs
|
||
* @param int|null $current_id
|
||
*/
|
||
public function update_tags($tags_comma, $override_childs, $add_to_childs, $current_id = null, $force_update = false)
|
||
{
|
||
if ($current_id == null) {
|
||
$current_id = $this->id;
|
||
}
|
||
|
||
// When current_id not empty we force to overwrite current object
|
||
Tag::update_tag_list($tags_comma, 'album', $current_id, $force_update ? true : $override_childs);
|
||
|
||
if ($override_childs || $add_to_childs) {
|
||
$songs = $this->get_songs();
|
||
foreach ($songs as $song_id) {
|
||
Tag::update_tag_list($tags_comma, 'song', $song_id, $override_childs);
|
||
}
|
||
}
|
||
}
|
||
|
||
public function remove_from_disk()
|
||
{
|
||
$deleted = true;
|
||
$song_ids = $this->get_songs();
|
||
foreach ($song_ids as $id) {
|
||
$song = new Song($id);
|
||
$deleted = $song->remove_from_disk();
|
||
if (!$deleted) {
|
||
debug_event('album', 'Error when deleting the song `' . $id . '`.', 1);
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ($deleted) {
|
||
$sql = "DELETE FROM `album` WHERE `id` = ?";
|
||
$deleted = Dba::write($sql, array($this->id));
|
||
if ($deleted) {
|
||
Art::gc('album', $this->id);
|
||
Userflag::gc('album', $this->id);
|
||
Rating::gc('album', $this->id);
|
||
Shoutbox::gc('album', $this->id);
|
||
Useractivity::gc('album', $this->id);
|
||
}
|
||
}
|
||
|
||
return $deleted;
|
||
}
|
||
|
||
/**
|
||
* Update album year.
|
||
* @param int $year
|
||
* @param int $album_id
|
||
*/
|
||
public static function update_year($year, $album_id)
|
||
{
|
||
self::update_field('year', $year, $album_id);
|
||
}
|
||
|
||
/**
|
||
* Update album mbid group.
|
||
* @param string $mbid_group
|
||
* @param int $album_id
|
||
*/
|
||
public static function update_mbid_group($mbid_group, $album_id)
|
||
{
|
||
$mbid_group = (!empty($mbid_group)) ? $mbid_group : null;
|
||
self::update_field('mbid_group', $mbid_group, $album_id);
|
||
}
|
||
|
||
/**
|
||
* Update album release type.
|
||
* @param string $release_type
|
||
* @param int $album_id
|
||
*/
|
||
public static function update_release_type($release_type, $album_id)
|
||
{
|
||
$release_type = (!empty($release_type)) ? $release_type : null;
|
||
self::update_field('release_type', $release_type, $album_id);
|
||
}
|
||
|
||
/**
|
||
* Update an album field.
|
||
* @param string $field
|
||
* @param int $album_id
|
||
* @return boolean
|
||
*/
|
||
private static function update_field($field, $value, $album_id)
|
||
{
|
||
$sql = "UPDATE `album` SET `" . $field . "` = ? WHERE `id` = ?";
|
||
return Dba::write($sql, array($value, $album_id));
|
||
}
|
||
|
||
/**
|
||
* get_random
|
||
*
|
||
* This returns a number of random albums.
|
||
* @param int $count
|
||
* @param boolean $with_art
|
||
* @return int[]
|
||
*/
|
||
public static function get_random($count = 1, $with_art = false)
|
||
{
|
||
$results = array();
|
||
|
||
if (!$count) {
|
||
$count = 1;
|
||
}
|
||
|
||
$sql = "SELECT DISTINCT `album`.`id` FROM `album` " .
|
||
"LEFT JOIN `song` ON `song`.`album` = `album`.`id` ";
|
||
if (AmpConfig::get('catalog_disable')) {
|
||
$sql .= "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog` ";
|
||
$where = "WHERE `catalog`.`enabled` = '1' ";
|
||
} else {
|
||
$where = "WHERE '1' = '1' ";
|
||
}
|
||
if ($with_art) {
|
||
$sql .= "LEFT JOIN `image` ON (`image`.`object_type` = 'album' AND `image`.`object_id` = `album`.`id`) ";
|
||
$where .="AND `image`.`id` IS NOT NULL ";
|
||
}
|
||
|
||
$sql .= $where;
|
||
$sql .= "ORDER BY RAND() LIMIT " . intval($count);
|
||
$db_results = Dba::read($sql);
|
||
|
||
while ($row = Dba::fetch_assoc($db_results)) {
|
||
$results[] = $row['id'];
|
||
}
|
||
|
||
return $results;
|
||
}
|
||
} //end of album class
|