<?php
/**
*
* MusicAlbumsYearAnalyzer: Find the average age of your music albums.
*
* This class searches your music directory for folders with a consistant
* naming convention and finds out the average age of your music collection.
* It is assumed you store your albums in one main music folder, and your albums
* are named in a format similar to this:
* Band Name - Album Name (Album Year)
* or, a real world example:
* Sirenia - The 13th Floor (2009)
*
* Basically, it reads the year the album was made in by reading the right-most
* four digit year in the brackets (2009. If you store your music in folders
* with the year in brackets towards the front it will still pick out the year.
* If this is still no good to you you can provide your own regex to discover
* the year via the constructor by providing the regex as the second argument or
* by using the setRegex and scan methods.
*
* Usage:
*
include 'MusicAlbumsYearAnalyzer.php';
$myMusic = '/path/to/musicFolder';
$n = new MusicAlbumsYearAnalyzer($myMusic);
echo "<p>Path to music dir: " . $n->getPath() . "</p>";
$n->scan();
echo "Album Count: " . $n->countAlbums() . "<br />";
echo "Newest Album: " . $n->newestAlbumYear() . "<br />";
echo "Oldest Album: " . $n->oldestAlbumYear() . "<br />";
echo "Average Age: " . $n->averageYear() . "<br />";
echo "<p>No. Albums owned by year:</p>\n";
$decade = null;
$decadeSum = 0;
foreach($n->countByYear() AS $year => $count){
if(substr($year, -2, 1) != $decade){
if($decade != null)
echo "{$decadeSum} Albums from the {$decade}0's <br />\n";
$decade = substr($year, -2, 1);
$decadeSum = 0;
}
$decadeSum += $count;
echo "\t$year\t$count<br />\n";
}
echo "<p>Albums sorted by year:</p>\n";
foreach($n->albumsWithYears() AS $album => $year){
echo "\t$year \t-\t $album<br />\n";
}
*
* @author Ahmad Retha <hide@address.com>
* @version 0.0 07/03/2010 first
* @version 0.1 10/04/2010 cleanup + usage example
* @version 0.2 11/04/2010 changed method name to better one
* @version 0.3 12/04/2010 fixed original poor oop design, better now
* @version 0.4 10/05/2010 averageYear() method now correctly returns string
* type, comments amended & better usage example.
* Also added albumsWithYears() method and getters.
* @license This file (class) is subject to the new BSD license.
* It can be viewed here http://framework.zend.com/license/new-bsd
*
*/
class MusicAlbumsYearAnalyzer {
/**
* $dir is the absolute location of the music folder where the albums
* are stored. This can be set via the constructor
* @var string
*/
protected $_dir = '';
/**
* $dh the directory handle resource
* @var resource
*/
protected $_dh = null;
/**
* $years the array that holds the album production years
* @var array
*/
protected $_years = array();
/**
* $albums the array holds the album names and their production year
* @var array
*/
protected $_albums = array();
/**
* The regular expression that is used to discover the year of production
* from the name of the folder. \((\d{4}) - this regex searches for a left
* bracket '(' and then a four digit number '\d{4}' to find a value like
* '(2010' starting from the right end of the folder name, working backwards
* @var string
*/
protected $_regex = ''; //"/\((\d{4}).*?$/";
/**
* The constructor takes the music directory address as the first argument,
* and a new regex (if needed) as the second argument
* @param string $dir The absolute/relative path to the albums directory
* @param string $regex The regex to read the album names
*/
public function __construct($dir = 'C:\Documents and Settings\User\My Documents\My Music',
$regex = "/\((\d{4}).*?$/")
{
$this->_dir = @realpath($dir);
$this->_regex = $regex;
}
/**
* Scans the music folder and stores any information in the $_years array
*/
public function scan()
{
//open main music dir
$this->_dh = opendir($this->_dir)
or die('Error. Failed to open directory ' . $this->_dir);
//loop through dir and collect info
while(false !== ($x = readdir($this->_dh))){
if(is_dir($this->_dir . DIRECTORY_SEPARATOR . $x) && (strlen($x) > 2)){
preg_match($this->_regex, (string)$x, $matches);
if(!empty($matches)){
$this->_years[] = $matches[1];
$this->_albums[$x] = $matches[1];
}
}
}
//close dir
if($this->_dh){
try {
closedir($this->_dh);
}catch(Exception $e){
echo $e->__toString();
}
}
}
/**
* @return int The number of albums found in your music directory
* with a production year
*/
public function countAlbums()
{
return sizeof($this->_years);
}
/**
* @return int The newest album year e.g. 2009
*/
public function newestAlbumYear()
{
if(!empty($this->_years))
return max($this->_years);
return 0;
}
/**
* @return int The oldest album year e.g. 1967
*/
public function oldestAlbumYear()
{
if(!empty($this->_years))
return min($this->_years);
return 0;
}
/**
* @return string Average age of albums to 2 d.p. e.g. 1991.81
*/
public function averageYear()
{
if(!empty($this->_years)){
return number_format(
array_sum($this->_years) / sizeof($this->_years)
, 2, '.', '');
}
return "0.00";
}
/**
* Orders albums by age and returns the number of albums from each year
* as an array in format: [year] => count
* Like this:
* 1967 2
* 1972 3
* 1979 1
* 1987 3
* 2009 1
* @return array Number of albums from each year "[year] => count"
*/
public function countByYear()
{
if(!empty($this->_years)){
$hash = array_count_values($this->_years);
ksort($hash);
return $hash;
}
return array();
}
/**
* Returns a sorted array of album names by year.
* Given the argument true it returns it in reverse order - newest to oldest
* @return array sorted album names and production years "[Album] => year"
* @param boolean $reverse if true reverses order - returns newest to oldest
*/
public function albumsWithYears($reverse = false)
{
if(!empty($this->_albums)){
asort($this->_albums);
if($reverse)
return array_reverse($this->_albums);
return $this->_albums;
}
return array();
}
/**
* Getters and Setters, get and setPath are aliases for get and setDir
*/
public function setDir($dir){$this->_dir = realpath($dir)
or die('Error. Failed to open dir ' . $dir);}
public function getDir(){return $this->_dir;}
public function setPath($dir){$this->setDir($dir);}
public function getPath(){return $this->_dir;}
public function getYears(){return $this->_years;}
public function setRegex($regex){$this->_regex = $regex;}
public function getRegex(){return $this->_regex;}
public function getCountByYear(){return $this->countByYear();}
public function getCountAlbums(){return $this->countAlbums();}
public function getNewestAlbumYear(){return $this->newestAlbumYear();}
public function getOldestAlbumYear(){return $this->oldestAlbumYear();}
public function getAverageYear(){return $this->averageYear();}
public function getAlbumsWithYears($reverse = false){
return $this->albumsWithYears($reverse);}
}