diff --git a/app/Config/Schema/sonerezh_mysql.php b/app/Config/Schema/sonerezh_mysql.php index 1600cd8..eb46a23 100644 --- a/app/Config/Schema/sonerezh_mysql.php +++ b/app/Config/Schema/sonerezh_mysql.php @@ -8,6 +8,34 @@ public function before($event = array()) { public function after($event = array()) { } + public $albums = array( + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), + 'name' => array('type' => 'string', 'null' => false, 'default' => null, 'key' => 'index', 'collate' => 'utf8mb4_unicode_ci', 'charset' => 'utf8mb4'), + 'cover' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 37, 'collate' => 'utf8mb4_unicode_ci', 'charset' => 'utf8mb4'), + 'band_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false, 'key' => 'index'), + 'year' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 4, 'unsigned' => false), + 'created' => array('type' => 'timestamp', 'null' => false, 'default' => null), + 'updated' => array('type' => 'timestamp', 'null' => true, 'default' => null), + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => 1), + 'albums_bands_id_fk' => array('column' => 'band_id', 'unique' => 0), + 'albums_name_index' => array('column' => 'name', 'unique' => 0) + ), + 'tableParameters' => array('charset' => 'utf8mb4', 'collate' => 'utf8mb4_unicode_ci', 'engine' => 'InnoDB') + ); + + public $bands = array( + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), + 'name' => array('type' => 'string', 'null' => false, 'default' => null, 'key' => 'index', 'collate' => 'utf8mb4_unicode_ci', 'charset' => 'utf8mb4'), + 'created' => array('type' => 'timestamp', 'null' => false, 'default' => null), + 'updated' => array('type' => 'timestamp', 'null' => true, 'default' => null), + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => 1), + 'bands_name_index' => array('column' => 'name', 'unique' => 0) + ), + 'tableParameters' => array('charset' => 'utf8mb4', 'collate' => 'utf8mb4_unicode_ci', 'engine' => 'InnoDB') + ); + public $playlist_memberships = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 8, 'unsigned' => true, 'key' => 'primary'), 'playlist_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 8, 'unsigned' => true), @@ -79,6 +107,33 @@ public function after($event = array()) { 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB') ); + public $tracks = array( + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'), + 'title' => array('type' => 'string', 'null' => true, 'default' => null, 'key' => 'index', 'collate' => 'utf8mb4_unicode_ci', 'charset' => 'utf8mb4'), + 'source_path' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 4096, 'collate' => 'utf8mb4_unicode_ci', 'charset' => 'utf8mb4'), + 'playtime' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 9, 'collate' => 'utf8mb4_unicode_ci', 'charset' => 'utf8mb4'), + 'track_number' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 5, 'unsigned' => false), + 'max_track_number' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 5, 'unsigned' => false), + 'disc_number' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 7, 'collate' => 'utf8mb4_unicode_ci', 'charset' => 'utf8mb4'), + 'max_disc_number' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 5, 'unsigned' => false), + 'year' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 4, 'unsigned' => false), + 'genre' => array('type' => 'string', 'null' => true, 'default' => null, 'key' => 'index', 'collate' => 'utf8mb4_unicode_ci', 'charset' => 'utf8mb4'), + 'artist' => array('type' => 'string', 'null' => true, 'default' => null, 'key' => 'index', 'collate' => 'utf8mb4_unicode_ci', 'charset' => 'utf8mb4'), + 'created' => array('type' => 'timestamp', 'null' => false, 'default' => null), + 'album_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false, 'key' => 'index'), + 'updated' => array('type' => 'timestamp', 'null' => false, 'default' => null), + 'imported' => array('type' => 'boolean', 'null' => true, 'default' => '1', 'key' => 'index'), + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => 1), + 'tracks_albums_id_fk' => array('column' => 'album_id', 'unique' => 0), + 'tracks_title_index' => array('column' => 'title', 'unique' => 0), + 'tracks_artist_index' => array('column' => 'artist', 'unique' => 0), + 'tracks_genre_index' => array('column' => 'genre', 'unique' => 0), + 'tracks_imported_index' => array('column' => 'imported', 'unique' => 0) + ), + 'tableParameters' => array('charset' => 'utf8mb4', 'collate' => 'utf8mb4_unicode_ci', 'engine' => 'InnoDB') + ); + public $users = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 5, 'unsigned' => true, 'key' => 'primary'), 'email' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'), diff --git a/app/Config/Schema/sonerezh_pgsql.php b/app/Config/Schema/sonerezh_pgsql.php index a42a312..4745f02 100644 --- a/app/Config/Schema/sonerezh_pgsql.php +++ b/app/Config/Schema/sonerezh_pgsql.php @@ -8,6 +8,34 @@ public function before($event = array()) { public function after($event = array()) { } + public $albums = array( + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 11, 'key' => 'primary'), + 'name' => array('type' => 'string', 'null' => false, 'default' => null), + 'cover' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 37), + 'band_id' => array('type' => 'integer', 'null' => true, 'default' => null), + 'year' => array('type' => 'integer', 'null' => true, 'default' => null), + 'created' => array('type' => 'datetime', 'null' => false, 'default' => null), + 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'indexes' => array( + 'PRIMARY' => array('unique' => true, 'column' => 'id'), + 'albums_bands_id_fk' => array('unique' => false, 'column' => 'band_id'), + 'albums_name_index' => array('unique' => false, 'column' => 'name') + ), + 'tableParameters' => array() + ); + + public $bands = array( + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 11, 'key' => 'primary'), + 'name' => array('type' => 'string', 'null' => false, 'default' => null), + 'created' => array('type' => 'datetime', 'null' => false, 'default' => null), + 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'indexes' => array( + 'PRIMARY' => array('unique' => true, 'column' => 'id'), + 'bands_name_index' => array('unique' => false, 'column' => 'name') + ), + 'tableParameters' => array() + ); + public $playlist_memberships = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 11, 'key' => 'primary'), 'playlist_id' => array('type' => 'integer', 'null' => false, 'default' => null), @@ -79,6 +107,33 @@ public function after($event = array()) { 'tableParameters' => array() ); + public $tracks = array( + 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 11, 'key' => 'primary'), + 'title' => array('type' => 'string', 'null' => true, 'default' => null), + 'source_path' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 4096), + 'playtime' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 9), + 'track_number' => array('type' => 'integer', 'null' => true, 'default' => null), + 'max_track_number' => array('type' => 'integer', 'null' => true, 'default' => null), + 'disc_number' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 7), + 'max_disc_number' => array('type' => 'integer', 'null' => true, 'default' => null), + 'year' => array('type' => 'integer', 'null' => true, 'default' => null), + 'genre' => array('type' => 'string', 'null' => true, 'default' => null), + 'artist' => array('type' => 'string', 'null' => true, 'default' => null), + 'created' => array('type' => 'datetime', 'null' => false, 'default' => 'CURRENT_TIMESTAMP'), + 'album_id' => array('type' => 'integer', 'null' => true, 'default' => null), + 'updated' => array('type' => 'datetime', 'null' => true, 'default' => 'CURRENT_TIMESTAMP'), + 'imported' => array('type' => 'boolean', 'null' => true, 'default' => true), + 'indexes' => array( + 'PRIMARY' => array('unique' => true, 'column' => 'id'), + 'tracks_albums_id_fk' => array('unique' => false, 'column' => 'album_id'), + 'tracks_artist_index' => array('unique' => false, 'column' => 'artist'), + 'tracks_genre_index' => array('unique' => false, 'column' => 'genre'), + 'tracks_imported_index' => array('unique' => false, 'column' => 'imported'), + 'tracks_title_index' => array('unique' => false, 'column' => 'title') + ), + 'tableParameters' => array() + ); + public $users = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 11, 'key' => 'primary'), 'email' => array('type' => 'string', 'null' => false, 'default' => null), diff --git a/app/Model/Album.php b/app/Model/Album.php new file mode 100644 index 0000000..651d691 --- /dev/null +++ b/app/Model/Album.php @@ -0,0 +1,105 @@ + array( + 'rule' => array('maxLength', 255), + 'required' => 'create', + 'allowEmpty' => false, + 'message' => 'Album\'s name cannot be empty or exceed 255 characters.' + ), + 'cover' => array( + 'rule' => array('maxLength', 37), + 'allowEmpty' => true, + 'message' => 'Album\'s cover cannot exceed 37 characters.' + ), + 'year' => array( + 'rule' => array('date', 'y'), + 'allowEmpty' => true, + 'message' => 'Invalid album year.' + ) + ); + + /** + * Allow empty value for the "name" field on update. + * + * @param array $options + * @return bool|void + */ + public function beforeValidate($options = array()) + { + if (isset($this->data[$this->alias]['id'])) { + $this->validator()->getField('name')->getRule(0)->allowEmpty = true; + } + } + + /** + * Override the "created" and the "updated" fields to ensure they are + * properly filled. + * + * @param array $options + * @return bool + */ + public function beforeSave($options = array()) + { + if (isset($this->data[$this->alias]['id'])) { + $this->data[$this->alias]['updated'] = date('Y-m-d H:i:s'); + unset($this->data[$this->alias]['created']); + } else { + $this->data[$this->alias]['created'] = date('Y-m-d H:i:s'); + unset($this->data[$this->alias]['updated']); + } + return true; + } + + /** + * Stores the Band id the deleted album belongs to, to perform further + * checks once the record is deleted (the ID is used in the afterDelete() + * method). + * + * @param bool $cascade + * @return bool + */ + public function beforeDelete($cascade = false) + { + $album = $this->find('first', array( + 'fields' => array('band_id'), + 'conditions' => array('id' => $this->id) + )); + + if (isset($album)) { + $this->bandId = $album[$this->alias]['band_id']; + } + return true; + } + + /** + * Checks if the Band the deleted album belongs to still have albums, and + * deletes it if it's not the case. + */ + public function afterDelete() + { + if (!empty($this->bandId)) { + $neighbours = $this->find('count', array( + 'conditions' => array('band_id' => $this->bandId) + )); + + if ($neighbours == 0) { + $band = ClassRegistry::init('Band'); + $band->delete($this->bandId); + } + } + } +} \ No newline at end of file diff --git a/app/Model/Band.php b/app/Model/Band.php new file mode 100644 index 0000000..4c11f64 --- /dev/null +++ b/app/Model/Band.php @@ -0,0 +1,53 @@ + array( + 'rule' => array('maxLength', 255), + 'required' => 'create', + 'allowEmpty' => false, + 'message' => 'The band\'s name cannot be empty or exceed 255 characters.' + ) + ); + + /** + * Allow empty value for the "name" field on update. + * + * @param array $options + * @return bool|void + */ + public function beforeValidate($options = array()) + { + if (isset($this->data[$this->alias]['id'])) { + $this->validator()->getField('name')->getRule(0)->allowEmpty = true; + } + } + + /** + * Override the "created" and the "updated" fields to ensure they are + * properly filled. + * + * @param array $options + * @return bool + */ + public function beforeSave($options = array()) + { + if (isset($this->data[$this->alias]['id'])) { + $this->data[$this->alias]['updated'] = date('Y-m-d H:i:s'); + unset($this->data[$this->alias]['created']); + } else { + $this->data[$this->alias]['created'] = date('Y-m-d H:i:s'); + unset($this->data[$this->alias]['updated']); + } + return true; + } +} \ No newline at end of file diff --git a/app/Model/Track.php b/app/Model/Track.php new file mode 100644 index 0000000..e361b84 --- /dev/null +++ b/app/Model/Track.php @@ -0,0 +1,125 @@ + array( + 'rule' => array('maxLength', 255), + 'message' => 'The title of a track cannot exceed 255 characters.' + ), + 'source_path' => array( + 'rule' => array('maxLength', 4096), + 'allowEmpty' => false, + 'required' => 'create', + 'message' => 'The source path of a file cannot be empty or exceed 4096 characters.' + ), + 'playtime' => array( + 'rule' => array('maxLength', 9), + 'allowEmpty' => true, + 'message' => 'The playtime cannot exceed 9 characters.' + ), + 'track_number' => array( + 'rule' => array('naturalNumber', true), + 'allowEmpty' => true, + 'message' => 'The track number must be a natural integer.' + ), + 'max_track_number' => array( + 'rule' => array('naturalNumber', true), + 'allowEmpty' => true, + 'message' => 'The max track number must be a natural integer.' + ), + 'disc_number' => array( + 'rule' => array('naturalNumber', true), + 'allowEmpty' => true, + 'message' => 'The disc number must be a natural integer.' + ), + 'max_disc_number' => array( + 'rule' => array('naturalNumber', true), + 'allowEmpty' => true, + 'message' => 'The max disc number must be a natural integer.' + ), + 'year' => array( + 'rule' => array('date', 'y'), + 'allowEmpty' => true, + 'message' => 'Invalid track year.' + + ), + 'genre' => array( + 'rule' => array('maxLength', 255), + 'message' => 'The genre of a track cannot exceed 255 characters.' + ), + 'artist' => array( + 'rule' => array('maxLength', 255), + 'message' => 'The artist value cannot exceed 255 characters.' + ) + ); + + /** + * Override the "created" and the "updated" fields to ensure they are + * properly filled. + * + * @param array $options + * @return bool + */ + public function beforeSave($options = array()) + { + if (isset($this->data[$this->alias]['id'])) { + $this->data[$this->alias]['updated'] = date('Y-m-d H:i:s'); + unset($this->data[$this->alias]['created']); + } else { + $this->data[$this->alias]['created'] = date('Y-m-d H:i:s'); + unset($this->data[$this->alias]['updated']); + } + return true; + } + + /** + * Stores the Album id the deleted track belongs to, to perform further + * checks once the record is deleted (the ID is used in the afterDelete() + * method). + * + * @param bool $cascade + * @return bool + */ + public function beforeDelete($cascade = false) + { + $track = $this->find('first', array( + 'fields' => array('album_id'), + 'conditions' => array('id' => $this->id) + )); + + if (isset($track)) { + $this->albumId = $track[$this->alias]['album_id']; + } + return true; + } + + /** + * Checks if the Album the deleted track belongs to still have tracks, and + * deletes it if it's not the case. + */ + public function afterDelete() + { + if (!empty($this->albumId)) { + $neighbours = $this->find('count', array( + 'conditions' => array('album_id' => $this->albumId) + )); + + if ($neighbours == 0) { + $album = ClassRegistry::init('Album'); + $album->delete($this->albumId); + } + } + } +} \ No newline at end of file