rosehill/libraries/Blossom/Classes/ActiveRecord.php

213 lines
5.0 KiB
PHP

<?php
/**
* @copyright 2011-2013 City of Bloomington, Indiana
* @license http://www.gnu.org/licenses/agpl.txt GNU/AGPL, see LICENSE.txt
* @author Cliff Ingham <inghamn@bloomington.in.gov>
*/
namespace Blossom\Classes;
use Zend\Db\Sql\Sql;
abstract class ActiveRecord
{
protected $tablename;
protected $data = array();
const MYSQL_DATE_FORMAT = 'Y-m-d H:i:s';
abstract public function validate();
/**
* Callback from TableGateway
*/
public function exchangeArray($data)
{
$this->data = $data;
}
/**
* Writes the database back to the database
*/
protected function save()
{
$this->validate();
$zend_db = Database::getConnection();
$sql = new Sql($zend_db, $this->tablename);
if ($this->getId()) {
$update = $sql->update()
->set($this->data)
->where(array('id'=>$this->getId()));
$sql->prepareStatementForSqlObject($update)->execute();
}
else {
$insert = $sql->insert()->values($this->data);
$sql->prepareStatementForSqlObject($insert)->execute();
$this->data['id'] = $zend_db->getDriver()->getLastGeneratedValue();
}
}
/**
* Removes this record from the database
*/
protected function delete()
{
if ($this->getId()) {
$sql = new Sql(Database::getConnection(), $this->tablename);
$delete = $sql->delete()->where(['id'=>$this->getId()]);
$sql->prepareStatementForSqlObject($delete)->execute();
}
}
/**
* Returns any field stored in $data
*
* @param string $fieldname
*/
protected function get($fieldname)
{
if (isset($this->data[$fieldname])) {
return $this->data[$fieldname];
}
}
/**
* @param string $fieldname
* @param string $value
*/
protected function set($fieldname, $value)
{
$value = trim($value);
$this->data[$fieldname] = $value ? $value : null;
}
/**
* Returns the date/time in the desired format
*
* Format is specified using PHP's date() syntax
* http://www.php.net/manual/en/function.date.php
* If no format is given, the database's raw data is returned
*
* @param string $field
* @param string $format
* @param DateTimeZone $timezone
* @return string
*/
protected function getDateData($dateField, $format=null, \DateTimeZone $timezone=null)
{
if (isset($this->data[$dateField])) {
if ($format) {
$date = new \DateTime($this->data[$dateField]);
if ($timezone) { $date->setTimezone($timezone); }
return $date->format($format);
}
else {
return $this->data[$dateField];
}
}
}
/**
* Sets a date
*
* Dates should be in DATE_FORMAT, set in configuration.inc
* If we cannot parse the string using DATE_FORMAT, we will
* fall back to trying something strtotime() understands
* http://www.php.net/manual/en/function.strtotime.php
*
* @param string $dateField
* @param string $date
*/
protected function setDateData($dateField, $date)
{
$date = trim($date);
if ($date) {
$d = \DateTime::createFromFormat(DATE_FORMAT, $date);
if (!$d) {
try {
$d = new \DateTime($date);
}
catch (Exception $e) {
throw new \Exception('unknownDateFormat');
}
}
$this->data[$dateField] = $d->format(self::MYSQL_DATE_FORMAT);
}
else {
$this->data[$dateField] = null;
}
}
/**
* Loads and returns an object for a foreign key _id field
*
* Will cache the object in a protected variable to avoid multiple database
* lookups. Make sure to declare a protected variable matching the class
*
* @param string $class Fully namespaced classname
* @param string $field
*/
protected function getForeignKeyObject($class, $field)
{
$var = preg_replace('/_id$/', '', $field);
if (!$this->$var && isset($this->data[$field])) {
$this->$var = new $class($this->data[$field]);
}
return $this->$var;
}
/**
* Verifies and saves the ID for a foreign key field
*
* Loads the object record for the foreign key and caches
* the object in a private variable
*
* @param string $class Fully namespaced classname
* @param string $field Name of field to set
* @param string $id The value to set
*/
protected function setForeignKeyField($class, $field, $id)
{
$id = trim($id);
$var = preg_replace('/_id$/', '', $field);
if ($id) {
$this->$var = new $class($id);
$this->data[$field] = $this->$var->getId();
}
else {
$this->$field = null;
$this->data[$field] = null;
}
}
/**
* Verifies and saves the ID for a foreign key object
*
* Caches the object in a private variable and sets
* the ID value in the data
*
* @param string $class Fully namespaced classname
* @param string $field Name of field to set
* @param Object $object Value to set
*/
protected function setForeignKeyObject($class, $field, $object)
{
if ($object instanceof $class) {
$var = preg_replace('/_id$/', '', $field);
$this->data[$field] = $object->getId();
$this->$var = $object;
}
else {
throw new \Exception('Object does not match the given class');
}
}
/**
* Returns whether the value can be an ID for a record
*
* return @bool
*/
public static function isId($id)
{
return ((is_int($id) && $id>0) || (is_string($id) && ctype_digit($id)));
}
}