id = intval($artist_id);
/* Get the information from the db */
$info = $this->_get_info();
if (count($info)) {
/* Assign Vars */
$this->name = $info['name'];
$this->prefix = $info['prefix'];
} // if info
return true;
} //constructor
/*!
@function _get_info
@discussion get's the vars for $this out of the database
@param $this->id Taken from the object
*/
function _get_info() {
/* Grab the basic information from the catalog and return it */
$sql = "SELECT * FROM artist WHERE id='" . sql_escape($this->id) . "'";
$db_results = mysql_query($sql, dbh());
$results = mysql_fetch_assoc($db_results);
return $results;
} //get_info
/*!
@function get_albums
@discussion gets the albums for this artist
//FIXME: Appears to not be used?
*/
function get_albums($sql) {
$results = array();
// $sql = "SELECT DISTINCT(album.id) FROM song,album WHERE song.album=album.id AND song.artist='$this->id' ORDER BY album.name";
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_object($db_results)) {
$results[] = new Album($r->id);
}
return $results;
} // get_albums
/*!
@function get_songs
@discussion gets the songs for this artist
*/
function get_songs() {
$sql = "SELECT song.id FROM song WHERE song.artist='" . sql_escape($this->id) . "'";
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_assoc($db_results)) {
$results[] = new Song($r['id']);
}
return $results;
} // get_songs
/**
* get_song_ids
* This gets an array of song ids that are assoicated with this artist. This is great for using
* with the show_songs function
*/
function get_song_ids() {
$sql = "SELECT id FROM song WHERE artist='" . sql_escape($this->id) . "' ORDER BY album, track";
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_assoc($db_results)) {
$results[] = $r['id'];
}
return $results;
} // get_song_ids
/*!
@function get_random_songs
@discussion gets a random number, and
a random assortment of songs from this
album
*/
function get_random_songs() {
$results = array();
$sql = "SELECT id FROM song WHERE artist='$this->id' ORDER BY RAND() LIMIT " . rand(1,$this->songs);
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_array($db_results)) {
$results[] = $r[0];
}
return $results;
} // get_random_songs
/*!
@function get_count
@discussion gets the album and song count of
this artist
*/
function get_count() {
/* Define vars */
$songs = 0;
$albums = 0;
$sql = "SELECT COUNT(song.id) FROM song WHERE song.artist='$this->id' GROUP BY song.album";
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_array($db_results)) {
$songs += $r[0];
$albums++;
}
/* Set Object Vars */
$this->songs = $songs;
$this->albums = $albums;
return true;
} // get_count
/**
* format
* this function takes an array of artist
* information and reformats the relevent values
* so they can be displayed in a table for example
* it changes the title into a full link.
*/
function format() {
/* Combine prefix and name, trim then add ... if needed */
$name = scrub_out(truncate_with_ellipse(trim($this->prefix . " " . $this->name)));
$this->f_name = $this->name;
//FIXME: This shouldn't be scrubing right here!!!!
$this->full_name = scrub_out(trim($this->prefix . " " . $this->name));
//FIXME: This should be f_link
$this->link = "id . "\" title=\"" . $this->full_name . "\">" . $name . "";
$this->name = $this->link;
// Get the counts
$this->get_count();
return true;
} // format
/**
* format_artist
* DEFUNCT, do not use anymore
*/
function format_artist() {
$this->format();
} // format_artist
/*!
@function rename
@discussion changes the name of the artist in the db,
and then merge()s songs
@param $newname the artist's new name, either a new
artist will be created or songs added to existing
artist if name exists already
@return the id of the new artist, or false if an error
*/
function rename($newname) {
/*
* There is this nifty function called check_artists in catalog that does exactly what we want it to do
* to use it, we first have to hax us a catalog
*/
$catalog = new Catalog();
/* now we can get the new artist id in question */
$newid = $catalog->check_artist($newname);
/* check that it wasn't just whitespace that we were called to change */
if ($newid == $this->id) {
$GLOBALS['error']->add_error('artist_name',_("Error: Name Identical"));
return false;
}
/* now we can just call merge */
if (!$this->merge($newid))
return false;
//now return id
return $newid;
} // rename
/*!
@function merge
@discussion changes the artist id of all songs by this artist
to the given id and deletes self from db
@param $newid the new artist id that this artist's songs should have
@return the name of the new artist on success, false if error
*/
function merge($newid) {
$catalog = new Catalog();
/* Make sure this is a valid ID */
if (!is_numeric($newid)) {
$GLOBALS['error']->add_error('general',"Error: Invalid Artist ID");
return false;
}
// First check newid exists
$check_exists_qstring = "SELECT name FROM artist WHERE id='" . $newid . "'"; //no need to escape newid, it's numeric
$check_exists_query = mysql_query($check_exists_qstring, dbh());
if ($check_exists_result = mysql_fetch_assoc($check_exists_query)) {
$NewName = $check_exists_result['name'];
// Now the query
$sql = "UPDATE song SET artist='" . $newid . "' " .
"WHERE artist='" . sql_escape($this->id) . "'";
$db_results = mysql_query($sql, dbh());
$num_stats_changed = $catalog->merge_stats('artist',$this->id,$newid);
/* If we've done the merege we need to clean up */
$catalog->clean_artists();
$catalog->clean_albums();
return $NewName;
}
else {
$GLOBALS['error']->add_error('general',"Error: No such artist to merge with");
return false;
}
} // merge
/*!
@function show_albums
@discussion displays the show albums by artist page
*/
function show_albums($sql = 0) {
/* Set Vars */
$web_path = conf('web_path');
$albums = $this->get_albums($sql);
$this->format_artist();
$artist = $this;
require (conf('prefix') . "/templates/show_artist.inc");
} // show_albums
/*!
@function get_similar_artists
@discussion returns an array of artist (id,name) arrays that are similar in name
All whitespace and special chars are ignored
@param extra arguments to normalize and compre, in that order
@return array of artist, each element is (id,name)
*/
function get_similar_artists ($n_rep_uml,$n_filter,$n_ignore,$c_mode,$c_count_w,$c_percent_w,$c_distance_l) {
//strip out just about everything, including whitespace, numbers and weird chars, and then
//lowercase it
$name = $this->normalize_name($this->name,$n_rep_uml,$n_filter,$n_ignore);
//now for a bit of mysql query
$sql = "SELECT id, name FROM artist WHERE id != '" . sql_escape($this->id) . "'";
$query = mysql_query($sql, dbh());
//loop it
$similar_artists = array();
while ($r = mysql_fetch_assoc($query)) {
$artist_name = $this->normalize_name($r['name'],$n_rep_uml,$n_filter,$n_ignore);
//echo "'" . $r['name'] . "' => '" . $artist_name . "'
\n";
if ($this->compare_loose($name,$artist_name,$c_mode,$c_count_w,$c_percent_w,$c_distance_l)) {
//echo "***MATCH***
\n";
$similar_artists[] = array($r['id'],$r['name']);
}
}
return $similar_artists;
} // get_similar_artists
/*!
@function normalize_name
@param artist name to normalize
@param $replace_umlaut wether to replace umlauts and others with the plain letter, default true
@param $filter what to filter out, defulat /[^a-z ]/
@param $ignore terms to ignore, default /\s(the|an?)\s/ (name is padded with whitespace beforehand)
@returns the normalized version of the given artist name, containing only letters and single spaces
*/
function normalize_name ($name,$replace_umlaut = NULL, $filter = NULL, $ignore = NULL) {
if (is_null($replace_umlaut)) $replace_umlaut = true;
if (is_null($filter)) $filter = "/[^a-z ]/";
if (is_null($ignore)) $ignore = "/\s(the|an?)\s/";
if ($replace_umlaut) {
//convert ümlauts, idea from http://php.net/manual/en/function.str-replace.php#50081
$umlauts = array("uml","acute","grave","cedil","ring","circ","tilde","lig","slash");
$name = str_replace($umlauts,"",htmlentities($name));
//now replace all &.; with .
$name = preg_replace("/&(.);/","\$1",$name);
//back to normal
$name = html_entity_decode($name);
}
//lowercase
$name = strtolower($name);
//now rip out all the special chars and spaces
$name = preg_replace($filter,"",$name);
//now certains terms can be dropped completely
//we have to add spaces on the sides though
$name = " " . $name . " ";
$name = preg_replace($ignore,"",$name);
//now single spaces
$name = preg_replace("/\s{2,}/"," ",$name);
//return
return trim($name);
} //normalize_name
/*!
@function compare_loose
@discussion percent and count are ORed together
@param $name1 artist name
@param $name2 artist name to compare against
@param $mode the type of matching to perform, one of line or word, default word
@param $countwords WORD MODE number of words that must be shared to match, 0 to disable, default 0
@param $percentwords WORD MODE percentage of words that must be shared to match, 0 to disable, default 50%
@param $distance LETTER MODE max levenshtein distance to pass as a match
@return true if given params are similar, false if not
*/
function compare_loose ($name1,$name2,$mode = NULL,$countwords = NULL,$percentwords = NULL,$distance = NULL) {
if (is_null($mode)) $mode = "word";
if (is_null($countwords)) $countwords = 0;
if (is_null($percentwords)) $percentwords = 50;
if (is_null($distance)) $distance = 2;
//echo "Compare '$name1' vs. '$name2'
\n";
$modes = array("line" => 0,"word" => 0,"letter" => 0);
$mode = (isset($modes[$mode]) ? $mode : "word");
switch ($mode) {
case "line":
//this is still relevant because of the normalize
return $name1 == $name2;
break;
case "word":
//echo " COMPARE: Word mode
\n";
//first, count the number of terms in name1, and then the number that also appear in name2
$words = explode(" ",$name1);
$num_words = count($words);
$num_words_shared = 0;
foreach ($words as $word) {
//echo " Looking for word '$word'... ";
if (strpos($name2,$word) !== false) {
//echo "MATCHED";
$num_words_shared++;
} else {
//echo " Nope";
}
//echo "
\n";
}
//now make the descision
return (
($countwords > 0 && $num_words_shared >= $countwords) ||
($percentwords > 0 && $num_words_shared > 0 && $num_words_shared/$num_words >= $percentwords/100)
);
break;
case "letter":
//simple
return levenshtein($name1,$name2) <= $distance;
break;
}
} // compare_loose
} // end of artist class
?>