OK...I'm having one of those programmer awakening mind contortions here. Bounçable sounds fabulous if I was writing games, but can we use the idea of a website asset as an example? This is what I'm actually wrestling with.
The custom CMS I've been roped into working on has this concept of 'asset' which can be an audio file, a logo image (small 100x100 image), a photo (large image), or a video. has a variety of functions that let you attach an asset to a variety of things: a user account, a company, your mom, etc. Each asset has an associated file (or sometimes two: e.g., cropped and raw logos) which is located somewhere. There is also a table, 'asset' which is used to logically connect these assets to the various other data entities.
I've been mulling this over for awhile now and seems to me I should probably create an abstract class called 'Asset' which would perhaps implement a method or two to create the db records and then specify some abstract methods such as getFilePath which would return the full file system path to an image and getWebPath which would return the apache path to an object for use in html. Maybe like the ones below...i have some questions in there so I'd appreciate it if you could take a peek for me:
Asset
abstract class Asset{
protected $db; // reference to pear db object
protected $validator; // object containing validation primitives
protected $id = NULL; // the id from the db table
protected $type = NULL; // specifies whether logo, audio, video, photo
protected $fileName = NULL; // the name of the file
/* other db fields blah blah blah */
/* all child classes will have to implement these */
abstract public function getWebPath(); // apache path for html display
abstract public function getFilePath(); // actual filesystem path
abstract public validateMedia(); // checks file format, size, etc.
public function __construct($dbConnection){
$this->db = $dbConnection;
require_once(SERVER_CLASSES."/Validator.php");
$this->validator = new Validator($this->db);
}
public function createDBREcord() {
// code here validates properties and attempts to store in a new DB record
// sets $this->id to last_insert_id
}
public function updateDBREcord() {
// code here validates properties and updates an existing DB record
}
public function save() {
if (is_null($this->id)) {
$this->createDBREcord();
} else {
$this->updateDBREcord();
}
}
}
Then an Image class would extend asset
class Image extends Asset {
public $width = NULL;
public $height = NULL;
public $format = NULL; // GIF, JPG, PNG, etc.
public function getWebPath() {
return WEB_IMAGE_PATH . $this->fileName; // the const is defined in site config file
}
public function getFilePath() {
return FS_IMAGE_PATH . $this->fileName; // the const is defined in site config file
}
public validateMedia() {
// i reckon i would use PECL extensions to check mime type or something
}
public function __construct($dbConnection){
// would i need to override the construct of abstract class? can I?
}
public function crop(x, y, w, h) {
}
public function resize(w, h) {
}
}
And finally Logo extends Image
class Logo extends Image {
const MAX_WIDTH = ASSET_LOG_MAX_WIDTH; // defined in sitewide config;
const MAX_HEIGHT = ASSET_LOG_MAX_HEIGHT; // defined in sitewide config;
public function __construct($dbConnection){
// is there any way to call the Asset constructor here? I just want to add some code to it?
}
public function dimensionsAreOK() {
if ($this->width > self::MAX_WIDTH) {
return false;
}
if ($this->height > self::MAX_HEIGHT) {
return false;
}
return true;
}
}
I don't really see any need for interfaces in this scheme. They just seem like gelded abstract classes. Just extra hassle. Speaking of hassle, where does one keep all these interfaces? In the same folder as your classes? [man]Autoload[/man] doesn't work on these does it?