I just want to know if I’m on the right path. Making most functions abstract didn’t seem necessary as the data is just about the same. Is this an invalid approach?
<?php
abstract class Model_Tasks {
/**
* Database object
*
* @access protected
*/
protected $db;
/**
* User ID
*
* @access protected
*/
protected $uid;
/**
* Data array
*
* @access protected
*/
protected $data;
/**
* SQL Query
*
* @access protected
*/
protected $query;
/**
* __construct
*
* @access protected
*/
protected function __construct($query) {
$this->db = Model_DB::getInstance();
$this->uid = $_SESSION['uid'];
$this->query = $query;
$this->getTasks();
}
/**
* getTasks
*
* @param string
* @access abstract protected
*/
protected function getTasks() {
$result = $this->db->prepare($this->query);
$result->execute(array(
':uid' => $this->uid
));
$this->data =& $result->fetchAll();
$this->taskCount = $result->rowCount();
}
/**
* constructTask
*
* Build the HTML of a task
*
* @param int
* @param int
* @param string
* @param string
* @access protected
*/
protected function constructTask(
$id, $cost, $title, $checked = 0
) {
$cost = money_format('$%i', $cost);
$title = stripslashes($title);
return '
<label class="task">
<input type="checkbox" name="done[]" rel="'.$id.'" '.($checked?'checked="checked"':'').' />
<code>'.$cost.'</code> — '.$title.'
</label>'."\n";
}
/**
* generateOutput
*
* Call by key [pending, completed] and return the constructed tasks
*
* @param bool
* @access final public
*/
final public function generateOutput($checked) {
try {
if(!is_bool($checked)) throw new Exception('generateOutput must contain a boolean variable');
if(!isset($this->data)) throw new Exception('Array has not been set.');
else $data = $this->data;
} catch(Exception $e) {
die('<pre>'.$e->getMessage().'<hr />'.$e->getTraceAsString());
}
if(is_array($data)): foreach($data AS &$r)
$str .= $this->constructTask($r['id'], $r['cost'], $r['title'], $checked);
else:
$str = '<label class="tasks"></label>';
endif;
return $str;
}
}
// ------------------------------------------------------------------------
/**
* pendingTasks
*
* @access public
*/
class pendingTasks extends Model_Tasks {
public $taskCount;
public function __construct() {
$query = '
SELECT id, title, cost
FROM tasks
WHERE (
status IS FALSE
AND uid = :uid
) ORDER BY cost DESC
';
parent::__construct($query);
}
}
/**
* completedTasks
*
* @access public
*/
class completedTasks extends Model_Tasks {
public function __construct() {
$query = '
SELECT id, title, cost
FROM tasks
WHERE (
status IS TRUE
AND uid = :uid
) ORDER BY id DESC
LIMIT 7
';
parent::__construct($query);
}
}
All it does is to print out a task with a specific query, and return an associative array.
“Is this an invalid approach?”
No. Your code is using abstract correctly. You are able to centralize common logic, but by declaring the parent class as abstract, you are forcing the instantiation of the class to be done via a child class (extends your abstract, parent class), which works well.
Piece of advice:
Declaring member variables in this fashion breaks encapsulation. I’d advise you to assign member variables like this via your calling code, and not in your constructor.