I've been studying PHP for a while now and decided to dive into OOP. Most of my code was a mess and I've begun to refactor much of the website to OOP; however, I'm having an issue with redundancy in my class functions. Below is a my Tracking.class.php file, which is responsible for returning arrays based on the function and the instance. This is my first time using OOP so I'm unsure if I'm being overly redundant in my child classes, and not entirely sure if there is a way I could clean up my code even more. Any help would be great!
class Tracking {
protected $type;
protected $user_id;
protected $response_array;
protected $result;
protected $typeToTable = array('weight' => 'wp_weight', 'calories' => 'wp_calories', 'move' => 'wp_move', 'sleep' => 'wp_sleep');
protected $arrayValue = array('weight' => 'value', 'calories' => 'totalcal', 'move' => 'length', 'sleep' => 'value');
function __construct($user_id, $type){
$this->type = $type;
$this->user_id = $user_id;
}
public static function getInstance($user_id, $type){
switch($type) {
case "weight" : $obj = new weightTracking($user_id, $type); break;
case "calories" : $obj = new caloriesTracking($user_id, $type); break;
case "move" : $obj = new moveTracking($user_id, $type); break;
case "sleep" : $obj = new sleepTracking($user_id, $type); break;
case "mood" : $obj = new feelTracking($user_id, $type); break;
}
return $obj;
}
function stats( Database $pdo ) {
$table_value = $this->arrayValue[$this->type];
$table = $this->typeToTable[$this->type];
$query = "SELECT AVG($table_value) as avg, MAX($table_value) as max, MIN($table_value) as min from $table WHERE user_id = :user_id";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->single();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
$avg = round($row['avg'], 2);
$min = round($row['min'], 2);
$max = round($row['max'], 2);
$this->response_array['avg'] = $avg;
$this->response_array['min'] = $min;
$this->response_array['max'] = $max;
return $this->response_array;
}
function returnGoalData( Database $pdo ) {
$query = 'SELECT * FROM wp_goals WHERE goal_type = :goal_type AND user_id = :user_id AND completed = :completed';
$pdo->query($query);
$pdo->bind(':goal_type', $this->type);
$pdo->bind(':user_id', $this->user_id);
$pdo->bind(':completed', 'N');
$pdo->execute();
$row = $pdo->single();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
if ($this->type == 'weight'){
$this->response_array['status'] = 'success';
$this->response_array['value'] = $row['value'];
$this->response_array['diff'] = days_diff($row['end']);
}
else {
$this->response_array['status'] = 'success';
$this->response_array['value'] = $row['value'];
}
return $this->response_array;
}
function lastResult( Database $pdo ){
$table_value = $this->arrayValue[$this->type];
$table = $this->typeToTable[$this->type];
date_default_timezone_set('America/Indiana/Indianapolis');
$date = new DateTime('now');
$date = date('Y-m-d', strtotime($date));
$query = "SELECT $table_value FROM $table WHERE user_id = :user_id AND time = :time";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->bind(':time' , $date);
$pdo->execute();
$row = $pdo->single();
if ( empty( $row ) ) {
$this->response_array['status'] = 'success';
$this->response_array['last'] = '0';
} else {
$this->response_array['status'] = 'success';
$this->response_array['last'] = $row['value'];
}
return $this->response_array;
}
}
class caloriesTracking extends Tracking {
function prepareGraph( $pdo ){
$query = "SELECT time, SUM(totalcal) as cal FROM wp_calories WHERE user_id = :user_id GROUP BY time ORDER BY time";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->resultset();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
// Initialize Array
$data = array('cols' => array(array('label' => 'time', 'type' => 'date'), array('label' => 'value', 'type' => 'number')),'rows' => array());
// Build Array
foreach($row as $rows){
$data['rows'][] = array('c' => array(array('v' => datecleanse($rows['time'])), array('v' => $rows['cal'])));
}
return $data;
}
function enumerateGraph( Database $pdo ){
$query = "SELECT wp_calories.time as time, food_db.desc as `desc`, wp_calories.totalcal as totalcal, wp_calories.food_id as food_id, wp_calories.servenum as servenum, food_weight.desc as weight_desc, wp_calories.meal as meal FROM wp_calories INNER JOIN food_db ON food_db.food_id = wp_calories.food_id INNER JOIN food_weight on food_weight.food_id = wp_calories.food_id AND food_weight.unit_id = wp_calories.unit_id WHERE user_id = :user_id ORDER BY time";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->resultset();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
// Build Array
foreach($row as $rows){
$data['rows'][] = array('time' => datecleanse($rows['time']), 'desc' => $rows['desc'], 'totalcal' => $rows['totalcal'], 'food_id' => $rows['food_id'], 'servenum' => $rows['servenum'], 'weight_desc' => $rows['weight_desc'], 'meal' => $rows['meal']);
}
return $data;
}
}
class moveTracking extends Tracking {
function prepareGraph( Database $pdo ){
$query = "SELECT time, length FROM wp_move WHERE user_id = :user_id GROUP BY time ORDER BY time";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->resultset();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
// Initialize Array
$data = array('cols' => array(array('label' => 'time', 'type' => 'date'), array('label' => 'value', 'type' => 'number')),'rows' => array());
// Build Array
foreach($row as $rows){
$data['rows'][] = array('c' => array(array('v' => datecleanse($rows['time'])), array('v' => $rows['length'])));
}
return $data;
}
function enumerateGraph( Database $pdo ){
$query = "SELECT time, value, length, calburn FROM wp_move WHERE user_id = :user_id GROUP BY time";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->resultset();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
// Initialize Array
$data = array('cols' => array(array('label' => 'time', 'type' => 'date'), array('label' => 'value', 'type' => 'string'), array('label' => 'value', 'type' => 'number'), array('label' => 'value', 'type' => 'number')), 'rows' => array());
// Build Array
foreach($row as $rows){
$data['rows'][] = array('c' => array(array('v' => datecleanse($rows['time'])), array('v' => $rows['value']), array('v' => $rows['length']), array('v' => $rows['calburn'])));
}
return $data;
}
}
class sleepTracking extends Tracking {
function prepareGraph( Database $pdo ){
$query = "SELECT time, value FROM wp_sleep WHERE user_id = :user_id ORDER BY time";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->resultset();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
$data = array('cols' => array(array('label' => 'time', 'type' => 'date'), array('label' => 'value', 'type' => 'number')),'rows' => array());
foreach($row as $rows){
$data['rows'][] = array('c' => array(array('v' => datecleanse($rows['time'])), array('v' => $rows['value'])));
}
return $data;
}
}
class feelTracking extends Tracking {
function prepareGraph( Database $pdo ){
$query = "SELECT time, value FROM wp_mood WHERE user_id = :user_id ORDER BY time";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->resultset();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
// Initialize Array
$data = array('cols' => array(array('label' => 'time', 'type' => 'string'),array('label' => 'value', 'type' => 'number')));
// Build Array
foreach($row as $rows){
$data['rows'][] = array('c' => array(array('v' => datecleanse($rows['time'])), array('v' => $rows['value'])));
}
return $data;
}
function enumerateGraph( Database $pdo ){
$query = "SELECT value, count(*) as count FROM wp_mood WHERE user_id = :user_id GROUP BY value";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->resultset();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
// Initialize Array
$data = array('cols' => array(array('label' => 'time', 'type' => 'string'),array('label' => 'Frequency', 'type' => 'number')));
// Build Array
foreach($row as $rows){
$data['rows'][] = array('c' => array(array('v' => $rows['value']), array('v' => $rows['count'])));
}
return $data;
}
}
class weightTracking extends Tracking {
function lastResult( Database $pdo ){
$query = "SELECT value from wp_weight WHERE user_id = :user_id ORDER BY time DESC Limit 1";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->single();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
$this->response_array['status'] = 'success';
$this->response_array['last'] = $row['value'];
return $this->response_array;
}
function prepareGraph( Database $pdo ){
$query = "SELECT time, value FROM wp_weight WHERE user_id = :user_id ORDER BY time";
$pdo->query($query);
$pdo->bind(':user_id', $this->user_id);
$pdo->execute();
$row = $pdo->resultset();
if ( empty( $row ) ) {
throw new Exception('No Results');
}
$data = array('cols' => array(array('label' => 'time', 'type' => 'date'), array('label' => 'value', 'type' => 'number')),'rows' => array());
foreach($row as $rows){
$data['rows'][] = array('c' => array(array('v' => datecleanse($rows['time'])), array('v' => $rows['value'])));
}
return $data;
}
}
function days_diff($date){
date_default_timezone_set('America/Indiana/Indianapolis');
$today = new DateTime('now');
$date = new DateTime($date);
$diff = date_diff($date, $today);
return $diff->d . " days";
}
function datecleanse($date){
$year = substr($date, 0, 4);
$month = intval(substr($date, 5, -3)) - 1;
$day = substr($date, -2);
$newd = 'Date('.$year.', '.$month.', '.$day.')';
return $newd;
}
Edit: For reference is here my Database Class.
class Database {
protected $host = DB_HOST;
protected $user = DB_USER;
protected $pass = DB_PASS;
protected $dbname = DB_NAME;
protected $dbh;
protected $error;
protected $stmt;
public function __construct() {
// SET DSN
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
// Set options
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
// Create a new PDO instance
try{
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
}
catch(PDOException $e){
$this->error = $e->getMessage();
}
}
public function query($query){
$this->stmt = $this->dbh->prepare($query);
}
public function bind($param, $value, $type = null){
if (is_null($type)) {
switch (true) {
case is_int($value) :
$type = PDO::PARAM_INT;
break;
case is_bool($value) :
$type = PDO::PARAM_BOOL;
break;
case is_null($value) :
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}
public function execute(){
return $this->stmt->execute();
}
public function resultset(){
$this->execute();
return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function single(){
$this->execute();
return $this->stmt->fetch(PDO::FETCH_ASSOC);
}
public function rowCount(){
return $this->stmt->rowCount();
}
public function lastInsertId(){
return $this->dbh->lastInsertId();
}
}
PDO
is not the greatest of ideas, as I have explained before. Just pass aroundPDO
instances instead \$\endgroup\$