288 lines
7.4 KiB
PHP
288 lines
7.4 KiB
PHP
|
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||
|
|
||
|
/**
|
||
|
* This class extends Kohana's [ORM] class to create defaults for OSB.
|
||
|
*
|
||
|
* @package OSB
|
||
|
* @category Helpers
|
||
|
* @author Deon George
|
||
|
* @copyright (c) 2009-2013 Open Source Billing
|
||
|
* @license http://dev.osbill.net/license.html
|
||
|
*/
|
||
|
abstract class ORM_OSB extends ORM {
|
||
|
/**
|
||
|
* @var string Database to connect to
|
||
|
*/
|
||
|
protected $_db = 'default';
|
||
|
|
||
|
protected $_created_column = array('column'=>'date_orig','format'=>TRUE);
|
||
|
protected $_updated_column = array('column'=>'date_last','format'=>TRUE);
|
||
|
|
||
|
// Our attributes used in forms.
|
||
|
protected $_form = array();
|
||
|
|
||
|
// Our attributes that should be converted to NULL when empty
|
||
|
protected $_nullifempty = array();
|
||
|
|
||
|
// Our attribute values that need to be stored as serialized
|
||
|
protected $_serialize_column = array();
|
||
|
|
||
|
// If we need to load any sub items on loading this model
|
||
|
protected $_sub_items = array();
|
||
|
protected $_sub_items_load = array();
|
||
|
protected $_sub_items_sorted = FALSE;
|
||
|
|
||
|
// Rules to assist with site ID and getting next record ID for inserts.
|
||
|
public function xrules() {
|
||
|
return array(
|
||
|
'id'=>array(
|
||
|
array('ORM_OSB::get_next_id',array(':model',':field')),
|
||
|
),
|
||
|
'site_id'=>array(
|
||
|
array('ORM_OSB::set_site_id',array(':model',':field')),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieve and Store DB BLOB data.
|
||
|
*/
|
||
|
private function _blob($data,$set=FALSE) {
|
||
|
try {
|
||
|
return $set ? gzcompress($this->_serialize($data,$set)) : $this->_serialize(gzuncompress($data));
|
||
|
|
||
|
// Maybe the data isnt compressed?
|
||
|
} catch (Exception $e) {
|
||
|
return $this->_serialize($data,$set);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Auto process some data as it comes from the database
|
||
|
* @see parent::__get()
|
||
|
*/
|
||
|
public function __get($column) {
|
||
|
if (array_key_exists($column,$this->_table_columns)) {
|
||
|
// If the column is a blob, we'll decode it automatically
|
||
|
if (
|
||
|
$this->_table_columns[$column]['data_type'] == 'blob'
|
||
|
AND ! is_null($this->_object[$column])
|
||
|
AND ! isset($this->_changed[$column])
|
||
|
AND (! isset($this->_table_columns[$column]['auto_convert']) OR ! $this->_table_columns[$column]['auto_convert'])
|
||
|
) {
|
||
|
|
||
|
// In case our blob hasnt been saved as one.
|
||
|
try {
|
||
|
$this->_object[$column] = $this->_blob($this->_object[$column]);
|
||
|
}
|
||
|
catch(Exception $e) {
|
||
|
HTTP_Exception::factory(501,Kohana_Exception::text($e));
|
||
|
}
|
||
|
|
||
|
$this->_table_columns[$column]['auto_convert'] = TRUE;
|
||
|
}
|
||
|
|
||
|
// If the column is a serialized object, we'll unserialize it.
|
||
|
if (
|
||
|
in_array($column,$this->_serialize_column)
|
||
|
AND is_string($this->_object[$column])
|
||
|
AND ! is_null($this->_object[$column])
|
||
|
AND ! isset($this->_changed[$column])
|
||
|
AND (! isset($this->_table_columns[$column]['unserialized']) OR ! $this->_table_columns[$column]['unserialized'])
|
||
|
) {
|
||
|
|
||
|
// In case our object hasnt been saved as serialized.
|
||
|
try {
|
||
|
$this->_object[$column] = unserialize($this->_object[$column]);
|
||
|
}
|
||
|
catch(Exception $e) {
|
||
|
HTTP_Exception::factory(501,Kohana_Exception::text($e));
|
||
|
}
|
||
|
|
||
|
$this->_table_columns[$column]['unserialized'] = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return parent::__get($column);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Intercept our object load, so that we can load our subitems
|
||
|
*/
|
||
|
protected function _load_values(array $values) {
|
||
|
parent::_load_values($values);
|
||
|
|
||
|
$sort = FALSE;
|
||
|
if ($this->_loaded AND $this->_sub_items_load AND count($this->_sub_items_load) == 1)
|
||
|
foreach ($this->_sub_items_load as $item => $sort)
|
||
|
$this->_sub_items = $this->$item->find_all()->as_array();
|
||
|
|
||
|
if ($sort) {
|
||
|
Sort::MAsort($this->_sub_items,$sort);
|
||
|
$this->_sub_items_sorted = TRUE;
|
||
|
}
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* If a column is marked to be nullified if it is empty, this is where it is done.
|
||
|
*/
|
||
|
private function _nullifempty(array $array) {
|
||
|
foreach ($array as $k=>$v) {
|
||
|
if (is_array($v)) {
|
||
|
if (is_null($x=$this->_nullifempty($v)))
|
||
|
unset($array[$k]);
|
||
|
else
|
||
|
$array[$k] = $x;
|
||
|
|
||
|
} elseif (! $v AND $v !== 0 AND $v !== '0')
|
||
|
unset($array[$k]);
|
||
|
|
||
|
}
|
||
|
|
||
|
return count($array) ? $array : NULL;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Try and (un)serialize our data, and if it fails, just return it.
|
||
|
*/
|
||
|
private function _serialize($data,$set=FALSE) {
|
||
|
try {
|
||
|
return $set ? serialize($data) : unserialize($data);
|
||
|
|
||
|
// Maybe the data serialized?
|
||
|
} catch (Exception $e) {
|
||
|
return $data;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function config($key) {
|
||
|
$mc = Config::instance()->module_config($this->_object_name);
|
||
|
|
||
|
return empty($mc[$key]) ? '' : $mc[$key];
|
||
|
}
|
||
|
|
||
|
public function dump() {
|
||
|
$result = array();
|
||
|
|
||
|
$result['this'] = $this->object();
|
||
|
|
||
|
foreach ($this->_sub_items as $o)
|
||
|
$result['sub'][] = $o->dump();
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Next record id
|
||
|
*
|
||
|
* @param array Validate object
|
||
|
* @param string Primary Key
|
||
|
*/
|
||
|
final public static function get_next_id($model,$field) {
|
||
|
if (! is_null($model->$field))
|
||
|
return TRUE;
|
||
|
|
||
|
$model->_changed[$field] = $field;
|
||
|
|
||
|
$ido = ORM::factory('Module')
|
||
|
->where('name','=',$model->_table_name)
|
||
|
->find();
|
||
|
|
||
|
if (! $ido->loaded())
|
||
|
throw new Kohana_Exception('Problem getting record_id for :table',array(':table'=>$model->_table_name));
|
||
|
|
||
|
$model->$field = $ido->record_id->next_id($ido->id);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
public function keyget($column,$key=NULL) {
|
||
|
if (is_null($key) OR ! is_array($this->$column))
|
||
|
return $this->$column;
|
||
|
else
|
||
|
return array_key_exists($key,$this->$column) ? $this->{$column}[$key] : NULL;
|
||
|
}
|
||
|
|
||
|
final public function mid() {
|
||
|
return ORM::factory('Module',array('name'=>$this->_table_name));
|
||
|
}
|
||
|
|
||
|
public function xsave(Validation $validation=NULL) {
|
||
|
// Find any fields that have changed, and process them.
|
||
|
if ($this->_changed)
|
||
|
foreach ($this->_changed as $c) {
|
||
|
// Any fields that are blobs, and encode them.
|
||
|
if (! is_null($this->_object[$c]) AND $this->_table_columns[$c]['data_type'] == 'blob') {
|
||
|
$this->_object[$c] = $this->_blob($this->_object[$c],TRUE);
|
||
|
|
||
|
// We need to reset our auto_convert flag
|
||
|
if (isset($this->_table_columns[$c]['auto_convert']))
|
||
|
$this->_table_columns[$c]['auto_convert'] = FALSE;
|
||
|
|
||
|
// Any fields that should be seriailzed, we'll do that.
|
||
|
} elseif (is_array($this->_object[$c]) AND in_array($c,$this->_serialize_column)) {
|
||
|
$this->_object[$c] = serialize($this->_object[$c]);
|
||
|
}
|
||
|
|
||
|
// Test if the value has still changed
|
||
|
if ($this->_original_values AND $this->_object[$c] == $this->_original_values[$c])
|
||
|
unset($this->_changed[$c]);
|
||
|
}
|
||
|
|
||
|
return parent::save($validation);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the site ID attribute for each row update
|
||
|
*/
|
||
|
final public static function set_site_id($model,$field) {
|
||
|
if (! is_null($model->$field))
|
||
|
return TRUE;
|
||
|
|
||
|
$model->_changed[$field] = $field;
|
||
|
$model->$field = Company::instance()->site();
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
public function subitems() {
|
||
|
return $this->_sub_items;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Override the Kohana processing so we can null values if required.
|
||
|
*/
|
||
|
public function values(array $values,array $expected=NULL) {
|
||
|
foreach ($values as $k=>$v) {
|
||
|
// Convert to NULL
|
||
|
if (in_array($k,$this->_nullifempty)) {
|
||
|
if (is_array($v))
|
||
|
$values[$k] = $this->_nullifempty($v);
|
||
|
|
||
|
elseif (! $v AND $v !== 0 AND $v !== '0')
|
||
|
$values[$k] = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return parent::values($values,$expected);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function help to find records that are active
|
||
|
*/
|
||
|
public function list_active($active=TRUE) {
|
||
|
$x=($active ? $this->_where_active() : $this);
|
||
|
|
||
|
return $x->find_all();
|
||
|
}
|
||
|
|
||
|
public function list_count($active=TRUE) {
|
||
|
$x=($active ? $this->_where_active() : $this);
|
||
|
|
||
|
return $x->find_all()->count();
|
||
|
}
|
||
|
}
|
||
|
?>
|