* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
*/
class App_Module
{
/**
* @var self::DEFAULT_INSTANCE_TABLE Instance of Zend_Db_Table_Abstract object (or any DB Table related object)
* @see self::DEFAULT_INSTANCE_TABLE
* @see Zend_Db_Table_Abstract
*/
protected $_table = null;
protected $_adapter = null;
protected $_hooks = array();
const _EXCEPTION_CODE = 10050;
const DEFAULT_INSTANCE_ROW = 'Zend_Db_Table_Row_Abstract';
const DEFAULT_INSTANCE_USER_ROW = 'Row_User_Abstract';
const DEFAULT_INSTANCE_TABLE = 'Zend_Db_Table';
const DEFAULT_INSTANCE_ROWSET = 'Zend_Db_Table_Rowset';
const DEFAULT_INSTANCE_ROWSET_PAGINATE = 'Zend_Db_Table_Rowset';
const DEFAULT_INSTANCE_SELECT = 'Zend_Db_Select';
const DEFAULT_INSTANCE_DATABASE_ADAPTER = 'Zend_Db_Adapter_Abstract';
const DEFAULT_VAR_TABLE_NAME = 'table';
const DEFAULT_VAR_TABLE_NAME_SEPARATOR = '!';
const DEFAULT_KEY = 'id';
const DEFAULT_KEY_GET = 'get_id';
const DEFAULT_DATE = 'yyyy-MM-dd';
const DEFAULT_TIME = 'HH:mm:ss';
const DEFAULT_DATETIME = 'yyyy-MM-dd HH:mm:ss';
const DEFAULT_DATE_STD = 'Y-m-d';
const DEFAULT_TIME_STD = 'H:i:s';
const DEFAULT_DATETIME_STD = 'Y-m-d H:i:s';
const PLACEHOLDER_TABLENAME = '#TABLENAME#';
const LOG_EMERGENCY = Zend_Log::EMERG;
const LOG_ALERT = Zend_Log::ALERT;
const LOG_CRITICAL = Zend_Log::CRIT;
const LOG_ERROR = Zend_Log::ERR;
const LOG_WARNING = Zend_Log::WARN;
const LOG_NOTICE = Zend_Log::NOTICE;
const LOG_INFO = Zend_Log::INFO;
const LOG_DEBUG = Zend_Log::DEBUG;
/**
* Get row from database and transform it into array. You may apply WHERE conditions
*
* @param $id_or_val ID or value of row, which you want to get from database
* @param $key Column name for SELECT.
* Will be converted to string.
* If $key is empty or null, value will be self::DEFAULT_KEY
* @param $where Multidimensional array with WHERE conditions to apply
* @param $is_full Should related tables be joined or not.
* Be advised, that some functions also load related data in 'getData() ' method if $is_full is true.
* If you choose true, then you can't use this row for 'update()', 'delete()', etc. methods unless you set row's 'setReadOnly' property to false
* @param $instanceof Instance of which object desired row should be
* @param $var_table_name Which table should be used
* @return If Row exists, then return array from Row, else return NULL
* @throws
* @see self::DEFAULT_KEY
* @see getData()
* @final
*/
final public function getRecord($id_or_val, $key = self::DEFAULT_KEY, $where = array(), $is_full = false, $instanceof = self::DEFAULT_INSTANCE_ROW, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(!$key || !is_string($key)) $key = self::DEFAULT_KEY;
if(!$instanceof) $instanceof = self::DEFAULT_INSTANCE_ROW;
if(!is_null($id_or_val))
{
if(is_int($id_or_val))
{
try
{
$id_or_val = $this->prefilterId($id_or_val);
}
catch(App_Module_Exception $e)
{
$this->writeLog('Wrong value ("'. (int)$id_or_val .'") passed as ID');
if(!$this->isDebug())
{
throw new App_Module_Exception_WrongData('Wrong value passed as ID');
}
}
}
else
{
$id_or_val = (string)$id_or_val;
}
}
$data = array();
$row = $this->getRow($id_or_val, $key, $where, $is_full, $var_table_name);
try
{
$row = $this->prefilterRow($row, $instanceof);
if(method_exists($row, 'getData'))
{
$data = $row->getData($is_full);
}
else
{
$data = $row->toArray();
}
}
catch(App_Module_Exception $e)
{
$data = null;
}
return $data;
}
/**
* Get row from database. You may apply WHERE conditions
*
* @param $id_or_val ID or value of row, which you want to get from database
* @param $key Column name for SELECT.
* Will be converted to string.
* If $key is empty or null, value will be self::DEFAULT_KEY
* @param $where Multidimensional array with WHERE conditions to apply
* @param $is_full Should related tables be joined or not.
* If you choose true, then you can't use this row for 'update()', 'delete()', etc. methods unless you set row's 'setReadOnly' property to false
* @param $var_table_name Which table should be used
* @return self::DEFAULT_INSTANCE_ROW is Row exists, else return NULL
* @see self::DEFAULT_KEY
* @see self::DEFAULT_INSTANCE_ROW
* @final
*/
final public function getRow($id_or_val, $key = self::DEFAULT_KEY, $where = array(), $is_full = false, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(!$key || !is_string($key)) $key = self::DEFAULT_KEY;
$key = (string)$key;
if(!is_null($id_or_val))
{
if(is_int($id_or_val))
{
try
{
$id_or_val = $this->prefilterId($id_or_val);
}
catch(App_Module_Exception $e)
{
$this->writeLog('Wrong value ("'. (int)$id_or_val .'") passed as ID');
if(!$this->isDebug())
{
throw new App_Module_Exception_WrongData('Wrong value passed as ID');
}
}
}
else
{
$id_or_val = (string)$id_or_val;
}
}
$table_name = $this->getTableName($var_table_name);
$table = $this->getTable($var_table_name);
$where = $this->prefilterWhere($where);
if(!$this->getActor()->isAdmin() && empty($where))
{
$add_is_deleted = 1;
}
if($id_or_val)
{
$where[] = array(
'condition' => $table_name .'.'. $key .' = ?',
'value' => $id_or_val,
);
}
if($table->isColumnExists($table::COLUMN_IS_DELETED) && $add_is_deleted)
{
$where[] = array(
'condition' => $table_name .'.'. $table::COLUMN_IS_DELETED .' = ?',
'value' => 0,
);
}
$select = $this->prepareSelect($where, $var_table_name);
$select = $this->joinRelatedTables($select, $is_full, $var_table_name);
$row = $table->fetchRow($select);
if(isset($select)) unset($select);
if(isset($table)) unset($table);
return $row;
}
/**
* Get row, marked as Zend_Db_Table::COLUMN_IS_DEFAULT
*
* @param $where Multidimensional array with WHERE conditions to apply
* @param $is_full Should related tables be joined or not.
* Be advised, that some functions also load related data in 'getData() ' method if $is_full is true.
* If you choose true, then you can't use this row for 'update()', 'delete()', etc. methods unless you set row's 'setReadOnly' property to false
* @param $var_table_name Which table should be used
* @return self::DEFAULT_INSTANCE_ROW object, if row exists OR NULL if there is no such object
* @throws
* @see Zend_Db_Table::COLUMN_IS_DEFAULT
* @see getData()
* @see self::DEFAULT_INSTANCE_ROW
* @final
*/
final public function getDefaultRow($where = array(), $is_full = false, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$where = $this->prefilterWhere($where);
$is_full = ($is_full ? 1 : 0);
$table = $this->getTable($var_table_name);
if($table->isColumnExists($table::COLUMN_IS_DEFAULT))
{
if(isset($table)) unset($table);
return $this->getRow(1, $table::COLUMN_IS_DEFAULT, $where, $is_full, $var_table_name);
}
throw new App_Module_Exception_NotExists('Column `'. $table::COLUMN_IS_DEFAULT .'` not exists');
}
/**
* Return array with following structure:
* array(
* 'records' => array(), // Multidimensional array with records. Key will be self::DEFAULT_KEY , value - array with data, loaded via 'getData() ' method
* '__pagination' => array(), // Pagination array
* );
*
* @param $order_or_sorting ORDER BY value OR Sorting array like this:
* array(
* 'order' => self::PLACEHOLDER_TABLENAME .'.id DESC',
* 'limit' => 25,
* 'page' => 1,
* );
* @param $limit_or_where How many records to get OR Multidimensional array with WHERE conditions to apply
* @param $page_or_filter Current page OR Array with columns to filter via prepareFilter()
* @param $where_or_is_full Multidimensional array with WHERE conditions to apply OR Add joined columns in joinRelatedTables() or not
* @param $filter_or_var_table_name Array with columns to filter via prepareFilter() or Which table should be used
* @param $is_full Add joined columns in joinRelatedTables() or not
* @param $var_table_name Which table should be used
* @return Array with following structure:
* array(
* 'records' => array(), // Multidimensional array with records. Key will be self::DEFAULT_KEY , value - array with data, loaded via 'getData() ' method
* '__pagination' => array(), // Pagination array
* );
* @see prepareFilter()
* @see joinRelatedTables()
* @see self::DEFAULT_KEY
* @see Zend_Db_Table_Row_Abstract::getData()
* @final
*/
final public function getRecords($order_or_sorting = null, $limit_or_where = null, $page_or_filter = null, $where_or_is_full = array(), $filter_or_var_table_name = array(), $is_full = false, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$records = array();
$rowset = $this->getRowset($order_or_sorting, $limit_or_where, $page_or_filter, $where_or_is_full, $filter_or_var_table_name, $is_full, $var_table_name);
foreach($rowset as $row)
{
if(method_exists($row, 'getData'))
{
$data = $row->getData($is_full);
}
else
{
$data = $row->toArray();
}
if($row->isColumnExists(self::DEFAULT_KEY))
{
$_getter = self::DEFAULT_KEY_GET;
$id = $row->$_getter();
if(isset($_getter)) unset($_getter);
$records[$id] = $data;
}
else
{
$records[] = $data;
}
}
$result = array(
'records' => $records,
'__pagination' => $rowset->pagination(),
);
if(isset($rowset)) unset($rowset);
if(isset($records)) unset($records);
return $result;
}
/**
* Return self::DEFAULT_INSTANCE_ROWSET object filled with data from database
*
* @param $order_or_sorting ORDER BY value OR Sorting array like this:
* array(
* 'order' => self::PLACEHOLDER_TABLENAME .'.id DESC',
* 'limit' => 25,
* 'page' => 1,
* );
* @param $limit_or_where How many records to get OR Multidimensional array with WHERE conditions to apply
* @param $page_or_filter Current page OR Array with columns to filter via prepareFilter()
* @param $where_or_is_full Multidimensional array with WHERE conditions to apply OR Add joined columns in joinRelatedTables() or not
* @param $filter_or_var_table_name Array with columns to filter via prepareFilter() or Which table should be used
* @param $is_full Add joined columns in joinRelatedTables() or not
* @param $var_table_name Which table should be used
* @return Array with following structure:
* array(
* 'records' => array(), // Multidimensional array with records. Key will be self::DEFAULT_KEY , value - array with data, loaded via 'getData() ' method
* '__pagination' => array(), // Pagination array
* );
* @see self::DEFAULT_INSTANCE_ROWSET
* @see self::PLACEHOLDER_TABLENAME
* @see prepareFilter()
* @see joinRelatedTables()
* @see self::DEFAULT_KEY
* @see Zend_Db_Table_Row_Abstract::getData()
* @final
*/
final public function getRowset($order_or_sorting = null, $limit_or_where = null, $page_or_filter = null, $where_or_is_full = array(), $filter_or_var_table_name = array(), $is_full = false, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(!is_array($order_or_sorting))
{
$order = $order_or_sorting;
if(!$limit_or_where) $limit = null;
else $limit = (int)$limit_or_where;
if(!$page_or_filter) $page = null;
else $page = (int)$page_or_filter;
$where = $this->prefilterWhere($where_or_is_full);
$filter = $this->prefilterArray($filter_or_var_table_name);
}
else
{
if(!empty($order_or_sorting['order']))
{
$order = $order_or_sorting['order'];
$limit = $order_or_sorting['limit'];
$page = $order_or_sorting['page'];
$where = $this->prefilterWhere($limit_or_where);
$filter = $this->prefilterArray($page_or_filter);
$is_full = $where_or_is_full;
if($filter_or_var_table_name)
{
$var_table_name = $filter_or_var_table_name;
}
}
else
{
$order = $order_or_sorting;
if(!$limit_or_where) $limit = null;
else $limit = (int)$limit_or_where;
if(!$page_or_filter) $page = null;
else $page = (int)$page_or_filter;
$where = $this->prefilterWhere($where_or_is_full);
$filter = $this->prefilterArray($filter_or_var_table_name);
}
if(!$order) $order = null;
if(!$limit) $limit = null;
if(!$page) $page = null;
}
$is_full = ($is_full ? 1 : 0);
$var_table_name = (string)$var_table_name;
$select = $this->prepareSelect($where, $var_table_name);
$select = $this->prepareFilter($select, $filter, $var_table_name);
$select = $this->applyOrderAndLimit($select, $order, $limit, $page, $var_table_name);
$select = $this->joinRelatedTables($select, $is_full, $var_table_name);
$table = $this->getTable($var_table_name);
$rowset = $table->fetchAll($select);
$result = $this->getTotalRecordsWithPagination($rowset, $limit, $page, $where, $filter, $var_table_name);
if(isset($select)) unset($select);
if(isset($table)) unset($table);
if(isset($rowset)) unset($rowset);
return $result;
}
/**
* Count total records from rowset object and return paginated result
*
* @param $rowset Rowset object
* @param $limit How many records to get
* @param $page Current page
* @param $where Array with WHERE conditions to apply
* @param $filter Array with columns to filter via prepareFilter()
* @param $var_table_name Which table should be used
* @return type
* @see self::DEFAULT_INSTANCE_ROWSET
* @see prepareFilter()
* @final
*/
final public function getTotalRecordsWithPagination($rowset, $limit = null, $page = null, $where = array(), $filter = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$where = $this->prefilterWhere($where);
$filter = $this->prefilterArray($filter);
if(!$this->isObjectAndInstance($rowset, self::DEFAULT_INSTANCE_ROWSET))
{
throw new App_Module_Exception_NotObject('Passed rowset must be an object with instance of '. self::DEFAULT_INSTANCE_ROWSET, $this->getExceptionCode(18));
}
// Temporary solution: Is null passed as $limit, then we count rowset, instead we duplicate query to database
if($limit)
{
$total = $this->getTotalRecords($where, $filter, $var_table_name);
}
else
{
$total = $rowset->count('*');
}
$result = $this->getPagination($rowset, $total, $page, $limit);
if(isset($total)) unset($total);
if(isset($rowset)) unset($rowset);
if(isset($where)) unset($where);
if(isset($filter)) unset($filter);
return $result;
}
/**
* Return amount of rows which match WHERE conditions and filter
*
* @param $where Multidimensional array with WHERE conditions to apply
* @param $filter Array for filter purposes
* @param $var_table_name Which table should be used
* @return Total records, matcing WHERE conditions and filter
* @final
*/
final public function getTotalRecords($where = array(), $filter = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$where = $this->prefilterWhere($where);
$filter = $this->prefilterArray($filter);
$table = $this->getTable($var_table_name);
$select = $this->prepareSelect($where, $var_table_name);
$select = $this->prepareFilter($select, $filter, $var_table_name);
$select = $this->joinRelatedTables($select, true, $var_table_name);
$count = $table->fetchAll($select)->count('*');
if(isset($select)) unset($select);
if(isset($table)) unset($table);
if(isset($where)) unset($where);
return $count;
}
/**
* Prepare pagination in any format you want. You MUST override this function
*
* @param $rowset Rowset, which will be paginated
* @param $total Total records, taken from getTotalRecords()
* @param $page Current page
* @param $limit How many records to get
* @return
* @see self::DEFAULT_INSTANCE_ROWSET
* @see getTotalRecords()
* @see self::DEFAULT_INSTANCE_ROWSET_PAGINATE
*/
public function getPagination($rowset, $total, $page = null, $limit = null)
{
return array(
'page' => $page,
'per_page' => $limit,
'total' => $total,
);
}
/**
* Create new row in table, stored in $var_table_name . If you overrided $this->validation method, then validation will be called
*
* @param $data Data, which row must be consist from
* @param $var_table_name Which table should be used
* @return
* @final
*/
final public function createRow($data, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
/**
* If method 'hookPreCreate' exists, it will be called, passing data array and $var_table_name
*
* Usually, this method should return data array, but it depends on your own needs
*/
if(method_exists($this, 'hookPreCreate'))
{
$data = $this->hookPreCreate($data, $var_table_name);
}
//$data = $this->validate($data, 1, null, null, $var_table_name);
$table = $this->getTable($var_table_name);
try
{
$row = $table->createRow($data);
$row->save();
}
catch(Exception $e)
{
$this->writeLog('Exception catched while trying to create new row, exception message - '. $e->getMessage(), self::LOG_WARNING, $e);
$row = null;
}
/**
* If method 'hookPostCreate' exists, it will be called, passing newely created row, data array and $var_table_name
*
* Usually, this method should return row object, but you can use any methods you want
*/
if(method_exists($this, 'hookPostCreate'))
{
$row_post = $this->hookPostCreate($row, $data, $var_table_name);
// In case someone forget to return $row object in hookPostCreate method
if($row_post) $row = $row_post;
if(isset($row_post)) unset($row_post);
}
return $row;
}
/**
* Method, which will be called before creating row in createRow() method
*
* @param $data Data, passed to createRow() method
* @param $var_table_name Which table to use
* @return Usually, this method should return row object, but you can use any methods you want
* @see createRow()
*/
public function hookPreCreate($data, $var_table_name = self::PLACEHOLDER_TABLENAME)
{
$data = $this->prefilterArray($data);
if(isset($data[self::DEFAULT_KEY])) unset($data[self::DEFAULT_KEY]);
if(empty($data))
{
throw new App_Module_Exception_DataRequired('Data required for this operation', $this->getExceptionCode(15));
}
$data['created'] = date(self::DEFAULT_DATETIME_STD);
return $data;
}
/**
* Method, which will be called after row is created in createRow() method
*
* @param $row Newely created row object or, possibly, NULL, if any errors were triggered, during Zend_Db_Table::createRow() method
* @param $data Data, passed to createRow() method
* @param $var_table_name Which table to use
* @return Usually, this method should return row object
* @see Zend_Db_Table::createRow()
*/
public function hookPostCreate($row, $data, $var_table_name = self::PLACEHOLDER_TABLENAME)
{
return $row;
}
/**
* Updated record with $data by ID $id
*
* @param $id ID of record, which must be updated
* @param $data Data for update. Data will be validated via 'validate' method. If ID passed in data, it will be erased, due to data integrity
* @param $var_table_name Which table should be used
* @return Object is row updated or null if any error occurred
* @final
*/
final public function updateRecord($id, $data, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$id = $this->prefilterId($id);
$row = $this->getRow($id, null, array(), false, $var_table_name);
return $this->updateRow($row, $data);
}
/**
* Update $row with $data
*
* @param $row Row, which should be updated
* @param $data Data for update. Data will be validated via 'validate' method. If ID passed in data, it will be erased, due to data integrity
* @return Object is row updated or null if any error occurred
* @final
*/
final public function updateRow($row, $data)
{
$row = $this->prefilterRow($row);
$data = $this->prefilterArray($data);
$data = $this->validate($data, 0, $row);
if(isset($data['id'])) unset($data['id']);
$_getter = self::DEFAULT_KEY_GET;
$data[self::DEFAULT_KEY] = $row->$_getter();
unset($_getter);
if(isset($data['created'])) unset($data['created']);
$data['updated'] = date(self::DEFAULT_DATETIME_STD);
try
{
$row->setFromArray($data);
$row->save();
}
catch(Exception $e)
{
$this->writeLog('Exception catched while trying to update row with new data, exception message - '. $e->getMessage(), self::LOG_WARNING, $e);
$row = null;
}
return $row;
}
/**
* Delete record from database
*
* @param $id_or_val ID or value to get row from database (for example, $id_or_val = 'test', $key = 'descr' - result: %table%.descr = 'test')
* @param $key Column name for SELECT.
* Will be converted to string.
* If $key is empty or null, value will be self::DEFAULT_KEY
* @param $where Multidimensional array with WHERE conditions to apply
* @param $var_table_name Which table should be used
* @return If row $row only marked as deleted, then will be returned row, else will be returned amount of deleted rows
* @see self::DEFAULT_KEY
* @final
*/
final public function deleteRecord($id_or_val, $key = self::DEFAULT_KEY, $where = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$row = $this->getRow($id_or_val, $key, $where, false, $var_table_name);
return $this->deleteRow($row);
}
/**
* Mark row as deleted or delete row from database completely (according to your extended version of Zend_Db_Table_Row_Abstract )
*
* @param $row Row to delete or mark as deleted
* @return If row $row only marked as deleted, then will be returned row, else will be returned amount of deleted rows
* @see Zend_Db_Table_Row_Abstract
* @see self::DEFAULT_INSTANCE_ROW
* @final
*/
final public function deleteRow($row)
{
$row = $this->prefilterRow($row);
return $row->delete();
}
/**
* Mark row as deleted or delete row from database completely (according to your extended version of Zend_Db_Table_Row_Abstract )
*
* @param $row Row to delete or mark as deleted
* @return If row $row only marked as deleted, then will be returned row, else will be returned amount of deleted rows
* @see Zend_Db_Table_Row_Abstract
* @see self::DEFAULT_INSTANCE_ROW
* @final
*/
final public function forceDeleteRow($row)
{
$row = $this->prefilterRow($row);
return $row->delete(1);
}
/**
*
* @param type $row_or_val
* @param type $exclude_row_or_val
* @param type $key
* @param $var_table_name Which table should be used
* @return type
* @final
*/
final public function doesRecordExists($row_or_val, $exclude_row_or_val = null, $key = self::DEFAULT_KEY, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(!$key || empty($key)) $key = self::DEFAULT_KEY;
$table = $this->getTable($var_table_name);
$val = null;
$val_exclude = null;
if(is_int($row_or_val) && $row_or_val > 0)
{
$val = $row_or_val;
}
elseif($this->isObjectAndInstance($row_or_val, self::DEFAULT_INSTANCE_ROW))
{
$_getter = self::DEFAULT_KEY_GET;
$val = $row_or_val->$_getter();
if(isset($_getter)) unset($_getter);
$key = $this->prefilterArray($key);
foreach($key as $k)
{
if(!$row_or_val->isColumnExists($k))
{
throw new App_Module_Exception('doesRecordExists - column `'. $k .'` not exists in row "'. get_class($row_or_val) .'"', $this->getExceptionCode(25));
}
}
}
elseif(is_string($row_or_val))
{
$val = $row_or_val;
}
else
{
throw new App_Module_Exception('Incorrect parameter received - $row_or_val', $this->getExceptionCode(27));
}
$where = array();
if(is_array($key))
{
$_where_or = array();
foreach($key as $k)
{
$_where_or[] = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $k .' = ?',
'value' => $val,
);
}
$where = $this->prepareWhereOr($_where_or, $var_table_name);
}
else
{
$where[] = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $key .' = ?',
'value' => $val,
);
}
if(!$exclude_row_or_val)
{
if(is_int($exclude_row_or_val) && $exclude_row_or_val > 0)
{
$val_exclude = $exclude_row_or_val;
}
elseif($this->isObjectAndInstance($exclude_row_or_val, self::DEFAULT_INSTANCE_ROW))
{
$getter = 'get_'. self::DEFAULT_KEY;
$val_exclude = $exclude_row_or_val->$getter();
}
elseif(is_array($exclude_row_or_val))
{
$val_exclude = $exclude_row_or_val[self::DEFAULT_KEY];
}
elseif(is_string($exclude_row_or_val))
{
$val_exclude = $exclude_row_or_val;
}
else
{
$val_exclude = null;
}
}
if($val_exclude)
{
$where[] = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. self::DEFAULT_KEY .' != ?',
'value' => $val_exclude,
);
}
$select = $this->prepareSelect($where, $var_table_name);
$row = $table->fetchRow($select);
unset($select);
unset($row_or_val);
if(isset($exclude_row_or_val)) unset($exclude_row_or_val);
return !is_null($row);
}
/**
* Prefilter $var_table_name. Convert short name (%tablename%, _%tablename%, table_%tablename%) to full (_table_%tablename%)
*
* @param $var_table_name Value to prefilter
* @return Valid $var_table_name
* @final
*/
final public function prefilterVarTableName($var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$var_table_name = (string)$var_table_name;
if(!$var_table_name) $var_table_name = self::DEFAULT_VAR_TABLE_NAME;
if(strpos($var_table_name, '_') !== false)
{
if(strpos($var_table_name, '_') !== 0)
{
$var_table_name = '_'. $var_table_name;
}
}
else
{
$var_table_name = '_'. $var_table_name;
}
if(strpos($var_table_name, 'table') === false)
{
$var_table_name = '_table'. $var_table_name;
}
return $var_table_name;
}
/**
* Return table object, stored under $var_table_name
*
* @param $var_table_name Which table should be used
* @return Table object, if $this->$var_table_name exists, else throws exception
* @throws App_Module_Exception If table not object and instance of self::DEFAULT_INSTANCE_TABLE
* @final
* @see self::DEFAULT_INSTANCE_TABLE
*/
final public function getTable($var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if($this->isObjectAndInstance($var_table_name, self::DEFAULT_INSTANCE_TABLE))
{
return $var_table_name;
}
$var_table_name = $this->prefilterVarTableName($var_table_name);
if(strpos($var_table_name, self::DEFAULT_VAR_TABLE_NAME_SEPARATOR) !== false)
{
list($var_table_name, $type) = explode(self::DEFAULT_VAR_TABLE_NAME_SEPARATOR, $var_table_name);
}
$table = $this->$var_table_name;
if(!$this->isObjectAndInstance($table, self::DEFAULT_INSTANCE_TABLE))
{
throw new App_Module_Exception('Table not exists, not an object or not instance of '. self::DEFAULT_INSTANCE_TABLE, $this->getExceptionCode(155));
}
return $table;
}
/**
* Validation function. Could be useful for data validation before writing in database (so you can always be sure, that only valid data will be written)
*
* @param $data Array to validate
* @param $is_create Is you creating data or updating. Maybe you'll use different validation methods, based on updating you item or creating
* @param $row Row object. Can be useful, is you want to check some value in $data to be unique, but exclude value in $row
* @param $instanceof Check for $row object (if it's passed)
* @param $var_table_name Which table should be used
* @return If validation failed, null will be returned, else validated data array
* @throws App_Module_Exception If $instanceof is not a valid string (@link isValidString())
* @see self::DEFAULT_INSTANCE_ROW
*/
public function validate($data, $is_create = false, $row = null, $instanceof = self::DEFAULT_INSTANCE_ROW, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if($row)
{
if(!$this->isValidString($instanceof))
{
throw new App_Module_Exception('$instanceof is not a valid string');
}
$instanceof = (string)$instanceof;
if(!$instanceof) $instanceof = self::DEFAULT_INSTANCE_ROW;
try
{
$row = $this->prefilterRow($row, $instanceof);
$_getter = self::DEFAULT_KEY_GET;
$data[self::DEFAULT_KEY] = $row->$_getter();
}
catch(App_Module_Exception $e)
{
return null;
}
}
else
{
if(isset($data[self::DEFAULT_KEY])) unset($data[self::DEFAULT_KEY]);
}
return $data;
}
/**
* Checks that passed argument is NOT resource, object or null
*
* @param $string Value to check
* @return Is valid string or not
* @final
* @static
*/
final static public function isValidString($string)
{
return !(is_resource($string) || is_object($string) || is_null($string));
}
/**
* Get table name from table, stored in $var_table_name
*
* @param $var_table_name Which table should be used
* @return Table name
* @throws App_Module_Exception If there is no such table
* @throws App_Module_Exception Table name not defined (just in case)
* @final
*/
final public function getTableName($var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$table = null;
if(is_string($var_table_name))
{
$table = $this->getTable($var_table_name);
}
elseif($this->isObjectAndInstance($var_table_name, self::DEFAULT_INSTANCE_TABLE))
{
$table = $var_table_name;
}
if(!$table)
{
throw new App_Module_Exception_NotExists('Table not exists', $this->getExceptionCode(22));
}
$table_name = null;
$table_name = $table->getName();
$table_name = (string)$table_name;
if(!$table_name)
{
throw new App_Module_Exception_WrongData('Table name can\'t be empty', $this->getExceptionCode(20));
}
if(isset($table)) unset($table);
return $table_name;
}
/**
* Create new SELECT object with WHERE conditions applied for $var_table_name table
*
* @param $where WHERE conditions to apply
* @param $var_table_name Which table should be used
* @return SELECT object
* @see self::DEFAULT_INSTANCE_SELECT
* @final
*/
final public function prepareSelect($where = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$where = $this->prefilterWhere($where);
$table = $this->getTable($var_table_name);
$table_name = $this->getTableName($var_table_name);
$select = $table->select()->from(
array(
$table_name => $table_name,
)
);
$select = $this->applyWhere($select, $where, $var_table_name);
if(isset($table)) unset($table);
if(isset($where)) unset($where);
return $select;
}
/**
* Returns database adapter. Useful for inline quoting
*
* @param $var_table_name If null passed, then users table will be used, else table stored in $var_table_name
* @return Currently initialized database adapter
* @see
*/
public function getDatabaseAdapter($var_table_name = null)
{
$table = null;
if($this->isObjectAndInstance($this->_adapter, self::DEFAULT_INSTANCE_DATABASE_ADAPTER))
{
return $this->_adapter;
}
if(!$var_table_name) $table = $this->getActor()->getTable();
else $table = $this->getTable($var_table_name);
$adapter = $table->getAdapter();
$this->_adapter = $adapter;
if(isset($table)) unset($table);
if(isset($adapter)) unset($adapter);
return $this->_adapter;
}
/**
* Return array with related entries
*
* @param $from Special array with following structure:
* array(
* 'columns' => array(
* %COLUMN_LIST%
* ),
* 'value' => %STRING_WITH_KEYWORDS%,
* ),
* @param $order_or_sorting Order string (for example, self::PLACEHOLDER_TABLENAME .'.id DESC') or sorting array
* @param $limit_or_where Records limit or array with WHERE conditions
* @param $page_or_var_table_name Page or which table to use
* @param $where Array with WHERE conditions or empty array, if you passed pagination array as first parameter
* @param $is_full Load related data or not
* @param $var_table_name Which table to use
* @return Array of related entries
* @see self::PLACEHOLDER_TABLENAME
*/
public function getRelatedEntries($from, $order_or_sorting = null, $limit_or_where = null, $page_or_var_table_name = null, $where = array(), $is_full = false, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$records = array();
$rowset = $this->getRelatedEntriesRowset($from, $order_or_sorting, $limit_or_where, $page_or_var_table_name, $where, $is_full, $var_table_name);
foreach($rowset as $row)
{
if(method_exists($row, 'getData'))
{
$data = $row->getData($is_full);
}
else
{
$data = $row->toArray();
}
if($row->isColumnExists(self::DEFAULT_KEY))
{
$_getter = self::DEFAULT_KEY_GET;
$id = $row->$_getter();
unset($_getter);
$records[$id] = $data;
}
else
{
$records[] = $data;
}
}
if(isset($rowset)) unset($rowset);
return $records;
}
/**
* Return rowset with related entries
*
* @param $from Special array with following structure:
* array(
* 'columns' => array(
* %COLUMN_LIST%
* ),
* 'value' => %STRING_WITH_KEYWORDS%,
* ),
* @param $order_or_sorting Order string (for example, self::PLACEHOLDER_TABLENAME .'.id DESC') or sorting array
* @param $limit_or_where Records limit or array with WHERE conditions
* @param $page_or_var_table_name Page or which table to use
* @param $where Array with WHERE conditions or empty array, if you passed pagination array as first parameter
* @param $is_full Load related data or not
* @param $var_table_name Which table to use
* @return Rowset with related entries
* @throws
* @throws
* @see self::PLACEHOLDER_TABLENAME
* @see self::DEFAULT_INSTANCE_ROWSET
*/
public function getRelatedEntriesRowset($from, $order_or_sorting = null, $limit_or_where = null, $page_or_var_table_name = null, $where = array(), $is_full = false, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(!is_array($order_or_sorting))
{
$order = $order_or_sorting;
if(!$limit_or_where) $limit = null;
else $limit = (int)$limit_or_where;
if(!$page_or_var_table_name) $page = null;
else $page = (int)$page_or_var_table_name;
$where = $this->prefilterWhere($where);
}
else
{
if(!empty($order_or_sorting['order']))
{
$order = $order_or_sorting['order'];
$limit = $order_or_sorting['limit'];
$page = $order_or_sorting['page'];
$where = $this->prefilterWhere($limit_or_where);
if($page_or_var_table_name)
{
$var_table_name = $page_or_var_table_name;
}
}
else
{
$order = $order_or_sorting;
if(!$limit_or_where) $limit = null;
else $limit = (int)$limit_or_where;
if(!$page_or_var_table_name) $page = null;
else $page = (int)$page_or_var_table_name;
$where = $this->prefilterWhere($where);
}
if(!$order) $order = null;
if(!$limit) $limit = null;
if(!$page) $page = null;
}
$var_table_name = (string)$var_table_name;
$select = $this->prepareSelect($where, $var_table_name);
$select = $this->resetSelectPart($select, Zend_Db_Select::FROM);
$from = $this->prefilterArray($from, true);
if(!$from['columns'] && $from['cols'])
{
$from['columns'] = $from['cols'];
unset($from['cols']);
}
$from['columns'] = $this->prefilterArray($from['columns'], true);
if(empty($from) || empty($from['columns']) || !is_string($from['value']) || !$from['value'])
{
throw new App_Module_Exception_InvalidStructure('From must be a valid array with following structure: "columns" => array of column to search, "value" => value to search revelancy');
}
foreach($from['columns'] as $k => $column)
{
if(is_array($column))
{
unset($from['columns'][$k]);
continue;
}
$column = (string)$column;
$r = array(
'union',
'select',
'where',
);
$column = str_replace('', array_values($r), $column);
if(!$column)
{
unset($from['columns'][$k]);
}
}
if(is_array($from['value']) || !$from['value']) throw new App_Module_Exception_WrongData('Wrong value for FROM. It should be a string and not empty');
$adapter = $this->getDatabaseAdapter();
$table_name = $this->getTableName($var_table_name);
$select->from(
array(
$table_name => $table_name,
),
array(
'*',
'revelancy' => $adapter->quoteInto('MATCH('. implode(', ', $from['columns']) .') AGAINST(?)', $from['value']),
)
);
$select->where('MATCH('. implode(', ', $from['columns']) .') AGAINST(?)', $from['value']);
$select = $this->applyWhere($select, $where, $var_table_name);
$order = $this->prefilterArray($order);
$order = array_values($order);
$order[-1] = 'revelancy DESC';
ksort($order);
$select = $this->applyOrderAndLimit($select, $order, $limit, $page, $var_table_name);
$table = $this->getTable($var_table_name);
$rowset = $table->fetchAll($select);
if(isset($adapter)) unset($adapter);
if(isset($table)) unset($table);
return $rowset;
}
/**
* Applies WHERE (AND) conditions to SELECT object
*
* @param $select Select object
* @param $where Multidimensional array with WHERE conditions to apply
* @param $var_table_name Which table should be used
* @return
* @throws
* @see self::DEFAULT_INSTANCE_SELECT
* @final
*/
final public function applyWhere($select, $where = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$select = $this->prefilterSelect($select, $var_table_name);
$where = $this->prefilterWhere($where);
$is_debug = $this->isDebug();
if(!empty($where))
{
foreach($where as $condition)
{
$cond = $condition['condition'];
if(is_array($condition['value']))
{
if(is_array($cond))
{
if(count($condition['value']) == count($cond))
{
$value = $condition['value'];
$value = array_values($value);
$cond = array_values($cond);
$type = $condition['type'];
if(is_array($type) && count($type) == count($cond))
{
$type = array_values($type);
}
else
{
throw new App_Module_Exception_WrongData('Inner type wrong format');
}
foreach($cond as $k => $cnd)
{
$cnd = (string)$cnd;
$cnd = $this->_replacePlaceholders($cnd, $var_table_name);
if(!$cnd || is_array($cnd)) throw new App_Module_Exception_WrongData('Inner condition empty or wrong type');
try
{
$select->where($cnd, $value[$k], $type[$k]);
}
catch(Zend_Db_Select_Exception $e)
{
if(!$is_debug)
{
throw new App_Module_Exception_NotExists('Column "'. $cnd .'" not found in selected table, stored under "'. $var_table_name .'"');
}
else
{
$this->writeLog('Condition "'. $cnd .'" can\'t be applied (target column possibly not exists in selected table "'. $var_table_name .'"). Error: '. $e->getMessage(), self::LOG_WARNING);
}
}
}
}
else
{
throw new App_Module_Exception_WrongData('Wrong count for inner value');
}
}
else
{
$cond = (string)$cond;
$cond = $this->_replacePlaceholders($cond, $var_table_name);
$select->where($cond, $condition['value'], $condition['type']);
}
}
else
{
if(is_array(@$condition['type'])) throw new App_Module_Exception_WrongData('Type can\'t be an array in current situation');
if(is_array($cond))
{
foreach($cond as $cnd)
{
if(!$cnd || is_array($cnd)) throw new App_Module_Exception_WrongData('Inner condition empty or wrong type');
$cnd = $this->_replacePlaceholders($cnd, $var_table_name);
$select->where($cnd, $condition['value'], $condition['type']);
}
}
else
{
$cond = $this->_replacePlaceholders($cond, $var_table_name);
$select->where($cond, @$condition['value'], @$condition['type']);
}
}
}
}
return $select;
}
/**
* Applies WHERE (OR) conditions to SELECT object. This function will not be called automatically.
*
* @param $where_or Multidimensional array with WHERE (OR) conditions to apply
* @param $var_table_name Which table should be used
* @return
* @throws Empty $where_or array received
* @see self::DEFAULT_INSTANCE_SELECT
* @final
*/
final public function prepareWhereOr($where_or = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$where_or = $this->prefilterWhere($where_or);
if(empty($where_or))
{
throw new App_Module_Exception_DataRequired('Empty array received instead of array with WHERE (OR) conditions');
}
$adapter = $this->getDatabaseAdapter($var_table_name);
$where = array();
$_where_or = array();
foreach($where_or as $condition)
{
$cond = $condition['condition'];
$cond = $this->_replacePlaceholders($cond, $var_table_name);
$_where_or[] = '('. $adapter->quoteInto($cond, $condition['value'], $condition['type']) .')';
}
$where[] = array(
'condition' => '('. implode(' OR ', $_where_or) .')',
'value' => '',
);
if(isset($where_or)) unset($where_or);
if(isset($_where_or)) unset($_where_or);
if(isset($adapter)) unset($adapter);
return $where;
}
/**
* Reset part or all parts of SELECT object
*
* @param $select Select object
* @param $part What part to reset.
* If $part is empty or NULL , then all parts will be reseted
* @see self::DEFAULT_INSTANCE_SELECT::_partsInit
* @return
* @see self::DEFAULT_INSTANCE_SELECT
* @final
*/
final public function resetSelectPart($select, $part = null)
{
$select = $this->prefilterSelect($select);
if(!$part) $part = null;
$select = $select->reset($part);
return $select;
}
/**
* Add filter to $select object. By default, function just return $select object. This function must be overriden, in order to use
*
* @param $select SELECT object
* @param $filter Array, where key is column to filter and value is required value (duuuh!)
* @param $var_table_name Which table should be used
* @return Prepared SELECT object
* @see self::DEFAULT_INSTANCE_SELECT
*/
public function prepareFilter($select, $filter = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
return $select;
}
/**
* Return filter array, filled with rules values
*
* @param $filter Array with filter to apply
* @param $rules Rules to apply
* @param $var_table_name Which table should be used
* @return
* @throws Incorrect value passed as rules array
* @throws Unknown filter method called
* @final
*/
final public function applyFilterRules($filter, $rules, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(empty($rules) || !$this->isMultiArray($rules))
{
throw new App_Module_Exception_WrongData('Rules empty or not multidimensional array');
}
$conditions = array();
$filter = $this->prefilterArray($filter);
foreach($rules as $type => $columns)
{
if(!empty($columns))
{
$type_method = explode('-', $type);
foreach($type_method as $k => $v)
{
$type_method[$k] = ucfirst($v);
}
$type_method = 'filter'. implode('', $type_method);
if(method_exists($this, $type_method))
{
foreach($columns as $_column => $column)
{
$parameters = array();
$key = $column;
$_cond = null;
if(is_array($column))
{
$parameters = $column['parameters'];
$parameters = $this->prefilterArray($parameters);
if($column['apply_not'])
{
$parameters['apply_not'] = ($column['apply_not'] ? 1 : 0);
}
if(isset($column['apply_not'])) unset($column['apply_not']);
if($column['is_datetime'])
{
$parameters['is_datetime'] = ($column['is_datetime'] ? 1 : 0);
}
if(isset($column['is_datetime'])) unset($column['is_datetime']);
if($column['validation'])
{
$parameters['validation'] = ($column['validation'] ? 1 : 0);
}
if(isset($column['validation'])) unset($column['validation']);
if($column['var_table_name'])
{
$var_table_name = $column['var_table_name'];
}
if($column['column'])
{
$t_column = $column['column'];
$t_column = (string)$t_column;
if($column['key'])
{
$key = $column['key'];
$key = (string)$key;
$column = array(
'column' => $t_column,
'key' => $key,
);
}
else
{
$column = (string)$t_column;
}
}
else
{
$column = $_column;
}
if(!$key || is_array($key)) $key = $_column;
if(@$filter[$key] && !@empty($filter[$key]))
{
if(!$parameters)
{
$_cond = $this->$type_method($filter[$key], $column, $var_table_name);
}
else
{
$_cond = $this->$type_method($filter[$key], $column, $parameters, $var_table_name);
}
}
}
else
{
if($filter[$key] && !empty($filter[$key]))
{
$_cond = $this->$type_method($filter[$key], $key, $var_table_name);
}
}
if($_cond)
{
if($this->isMultiArray($_cond))
{
foreach($_cond as $_cond_children)
{
$conditions[] = $_cond_children;
}
}
else
{
$conditions[] = $_cond;
}
}
}
}
else
{
throw new App_Module_Exception_NotExists('Unknown filtration method "'. $type_method .'" requested');
}
}
}
return $conditions;
}
/**
*
* @param type $filter_id
* @param type $column
* @param type $parameters
* @param type $var_table_name
* @return string
* @final
*/
final public function filterId($filter_id, $column, $parameters = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$condition = array();
if(is_array($column))
{
$key = $column['key'];
$_column = $column['column'];
$column = '';
$column = $_column;
}
else
{
$column = (string)$column;
}
if(!$key) $key = $column;
$parameters = $this->prefilterArray($parameters);
$is_not = $parameters['apply_not'];
$is_not = ($is_not ? 1 : 0);
$table = $this->getTable($var_table_name);
if(!$column || !$table->isColumnExists($column))
{
throw new App_Module_Exception('Column name not set or not exists');
}
try
{
$filter_id = $this->prefilterId($filter_id);
if($is_not)
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?',
'value' => $filter_id,
);
}
else
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?',
'value' => $filter_id,
);
}
}
catch(App_Module_Exception $e)
{
}
if(empty($condition)) $condition = null;
if(isset($table)) unset($table);
return $condition;
}
/**
*
* @param type $filter_value
* @param type $column
* @param type $parameters
* @param type $var_table_name
* @return string
* @final
*/
final public function filterMultiple($filter_value, $column, $parameters = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$conditions = array();
$parameters = $this->prefilterArray($parameters);
$table = $this->getTable($var_table_name);
if(is_array($column))
{
$key = $column['key'];
$_column = $column['column'];
$column = '';
$column = $_column;
}
else
{
$column = (string)$column;
}
if(!$key) $key = $column;
$is_not = $parameters['apply_not'];
$is_not = ($is_not ? 1 : 0);
$validation = $parameters['validation'];
$adapter = $this->getDatabaseAdapter($var_table_name);
if(!$filter_value)
{
return null;
}
if(!$column || !$table->isColumnExists($column))
{
throw new App_Module_Exception('Column name not set or not exists');
}
if(is_array($filter_value))
{
$_where_or = array();
foreach ($filter_value as $_value)
{
if($_value)
{
if(!empty($validation))
{
if(Zend_Validate::is($_value, 'InArray', array($validation)))
{
if($is_not)
{
$_where_or[] = $adapter->quoteInto('('. self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?)', $_value);
}
else
{
$_where_or[] = $adapter->quoteInto('('. self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?)', $_value);
}
}
}
else
{
if($is_not)
{
$_where_or[] = $adapter->quoteInto('('. self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?)', $_value);
}
else
{
$_where_or[] = $adapter->quoteInto('('. self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?)', $_value);
}
}
}
}
if(!empty($_where_or))
{
$conditions = array(
'condition' => '('. implode(' OR ', $_where_or) .')',
'value' => '',
);
}
}
else
{
$filter_value = (string)$filter_value;
if($filter_value)
{
if(!empty($validation))
{
if(Zend_Validate::is($filter_value, 'InArray', array($validation)))
{
if($is_not)
{
$conditions = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?',
'value' => $filter_value,
);
}
else
{
$conditions = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?',
'value' => $filter_value,
);
}
}
}
else
{
if($is_not)
{
$conditions = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?',
'value' => $filter_value,
);
}
else
{
$conditions = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?',
'value' => $filter_value,
);
}
}
}
}
if(empty($conditions) || !is_array($conditions))
{
$conditions = null;
}
if(isset($table)) unset($table);
if(isset($parameters)) unset($parameters);
return $conditions;
}
/**
*
* @param type $filter_value
* @param type $column
* @param type $parameters
* @param type $var_table_name
* @return string
* @final
*/
final public function filterBoolean($filter_value, $column, $parameters = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$filter_value = ($filter_value ? 1 : 0);
if(is_array($column))
{
$key = $column['key'];
$_column = $column['column'];
$column = '';
$column = $_column;
}
else
{
$column = (string)$column;
}
if(!$key) $key = $column;
$table = $this->getTable($var_table_name);
$parameters = $this->prefilterArray($parameters);
$is_not = $parameters['apply_not'];
$is_not = ($is_not ? 1 : 0);
if(!$column || !$table->isColumnExists($column))
{
throw new App_Module_Exception('Column name not set or not exists');
}
if($is_not)
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?',
'value' => $filter_value,
);
}
else
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?',
'value' => $filter_value,
);
}
if(isset($table)) unset($table);
return $condition;
}
/**
*
* @param type $filter_range
* @param type $column
* @param type $parameters
* @param type $var_table_name
* @return string
* @final
*/
final public function filterRange($filter_range, $column, $parameters = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(!$filter_range) return array();
if(is_array($filter_range))
{
$filter_range = implode(', ', $filter_range);
}
if(is_array($column))
{
$key = $column['key'];
$_column = $column['column'];
$column = '';
$column = $_column;
}
else
{
$column = (string)$column;
}
if(!$key) $key = $column;
$table = $this->getTable($var_table_name);
$parameters = $this->prefilterArray($parameters);
$is_not = $parameters['apply_not'];
$is_not = ($is_not ? 1 : 0);
$condition = null;
if(!$column || !$table->isColumnExists($column))
{
throw new App_Module_Exception('Column name not set or not exists');
}
$filter_range_orig = $filter_range;
$ranges = array();
$replace = array(
'–' => '-',
' - ' => '-',
'–' => '-',
);
$filter_range = preg_replace("'\s+'", ' ', $filter_range);
$filter_range = preg_replace("[\n|\r]", ',', $filter_range);
$filter_range = explode(',', $filter_range);
if(is_array($filter_range) && count($filter_range))
{
foreach($filter_range as $k => $id_range)
{
$id_range = str_replace(array_keys($replace), array_values($replace), $id_range);
$id_range = @trim($id_range);
if(strpos($id_range, '-') === false)
{
unset($filter_range[$k]);
continue;
}
list($val['left'], $val['right']) = explode("-", $id_range);
$val['left'] = (int)$val['left'];
$val['right'] = (int)$val['right'];
if(!$val['left'] || !$val['right'])
{
unset($filter_range[$k]);
continue;
}
$left = $val['left'];
$right = $val['right'];
if($val['left'] > $val['right'])
{
$left = $val['right'];
$right = $val['left'];
}
$range = range($left, $right);
if(!is_array($range))
{
unset($filter_range[$k]);
continue;
}
unset($filter_range[$k]);
$ranges = array_merge($ranges, $range);
}
}
$ranges = array_unique($ranges);
$filter_range = $filter_range_orig;
$replace = array(
'.',
';',
'`',
'|',
);
$filter_range = preg_replace("[\n|\r]", ',', $filter_range);
$filter_range = explode(',', $filter_range);
if(is_array($filter_range) && count($filter_range))
{
foreach($filter_range as $k => $id)
{
if(strpos($id, '-') !== false)
{
unset($filter_range[$k]);
continue;
}
$id = str_replace($replace, ',', $id);
$id = @trim($id);
$id = (int)$id;
if(!$id)
{
unset($filter_range[$k]);
continue;
}
$filter_range[$k] = $id;
}
}
$filter_range = array_merge($ranges, $filter_range);
$filter_range = array_unique($filter_range);
if(!empty($filter_range))
{
sort($filter_range);
$cond = implode(', ', $filter_range);
if(strpos($cond, ', ') === false)
{
$cond = (int)$cond;
if($is_not)
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?',
'value' => $cond,
);
}
else
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?',
'value' => $cond,
);
}
}
else
{
if($is_not)
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' NOT IN ('. $cond .')',
'value' => '',
);
}
else
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' IN ('. $cond .')',
'value' => '',
);
}
}
}
if(isset($table)) unset($table);
if(isset($cond)) unset($cond);
if(isset($filter_range)) unset($filter_range);
return $condition;
}
/**
*
* @param type $filter_value
* @param type $column
* @param type $parameters
* @param type $var_table_name
* @return string
* @final
*/
final public function filterBetween($filter_value, $column, $parameters = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(is_array($column))
{
$key = $column['key'];
$_column = $column['column'];
$column = '';
$column = $_column;
}
else
{
$column = (string)$column;
}
if(!$key) $key = $column;
$min = $filter_value['min'];
$min = (int)$min;
$max = $filter_value['max'];
$max = (int)$max;
$condition = array();
$parameters = $this->prefilterArray($parameters);
if($max < $min)
{
$_max = $min;
$min = $max;
$max = $_max;
unset($_max);
}
if(($max - $min) < 25)
{
$total = $min + $max;
$total = $total / 2;
$total = @round($total);
$min = $total - 25;
$max = $total + 25;
if(isset($total)) unset($total);
}
$table = $this->getTable($var_table_name);
if(!$column || !$table->isColumnExists($column))
{
throw new App_Module_Exception('Column name not set or not exists');
}
if(!is_null($filter_value['min']))
{
$condition[] = array(
'condition' => '('. self::PLACEHOLDER_TABLENAME .'.'. $column .' >= ?)',
'value' => $min,
);
}
if(!is_null($filter_value['max']))
{
$condition[] = array(
'condition' => '('. self::PLACEHOLDER_TABLENAME .'.'. $column .' <= ?)',
'value' => $max,
);
}
if(isset($table)) unset($table);
if(empty($condition)) $condition = null;
return $condition;
}
/**
*
* @param type $filter_value
* @param type $column
* @param type $parameters
* @param type $var_table_name
* @return type
* @final
*/
final public function filterDate($filter_value, $column, $parameters = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(is_array($column))
{
$key = $column['key'];
$_column = $column['column'];
$column = '';
$column = $_column;
}
else
{
$column = (string)$column;
}
if(!$key) $key = $column;
$filter_value = (string)$filter_value;
$table = $this->getTable($var_table_name);
$parameters = $this->prefilterArray($parameters);
$is_not = $parameters['apply_not'];
$is_not = ($is_not ? 1 : 0);
$is_datetime = $parameters['is_datetime'];
$is_datetime = ($is_datetime ? 1 : 0);
$condition = null;
if(!$column || !$table->isColumnExists($column))
{
throw new App_Module_Exception('Column name not set or not exists');
}
if($filter_value && $filter_value != 'Array')
{
$date = new Zend_Date($filter_value);
$date_format = self::DEFAULT_DATE;
if($is_datetime) $date_format = self::DEFAULT_DATETIME;
$filter_value = $date->get($date_format);
if($filter_value)
{
if($is_not)
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?',
'value' => $filter_value,
);
}
else
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?',
'value' => $filter_value,
);
}
}
}
if(isset($table)) unset($table);
if(isset($date)) unset($date);
return $condition;
}
/**
*
* @param type $filter_value
* @param type $column
* @param type $parameters
* @param type $var_table_name
* @return string
* @final
*/
final public function filterString($filter_value, $column, $parameters = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(is_array($column))
{
$key = $column['key'];
$_column = $column['column'];
$column = '';
$column = $_column;
}
else
{
$column = (string)$column;
}
if(!$key) $key = $column;
$filter_value = (string)$filter_value;
$filter_value = @trim($filter_value);
$table = $this->getTable($var_table_name);
$parameters = $this->prefilterArray($parameters);
$is_not = $parameters['apply_not'];
$is_not = ($is_not ? 1 : 0);
$condition = null;
if(!$column || !$table->isColumnExists($column))
{
throw new App_Module_Exception('Column name not set or not exists');
}
$r = array(
'%',
'\'',
'"',
'<',
'>',
'\\',
'/',
);
$filter_value = str_replace($r, '', $filter_value);
$filter_value = preg_replace("'\s+'", ' ', $filter_value);
$filter_value = htmlspecialchars($filter_value);
if($filter_value)
{
if($is_not)
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?',
'value' => $filter_value,
);
}
else
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?',
'value' => $filter_value,
);
}
}
return $condition;
}
/**
*
* @param type $filter_value
* @param type $column
* @param type $parameters
* @param type $var_table_name
* @return string
* @final
*/
final public function filterStringLike($filter_value, $column, $parameters = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(is_array($column))
{
$key = $column['key'];
$_column = $column['column'];
$column = '';
$column = $_column;
}
else
{
$column = (string)$column;
}
if(!$key) $key = $column;
$filter_value = (string)$filter_value;
$filter_value = @trim($filter_value);
$table = $this->getTable($var_table_name);
$parameters = $this->prefilterArray($parameters);
$is_not = $parameters['apply_not'];
$is_not = ($is_not ? 1 : 0);
$condition = null;
if(!$column || !$table->isColumnExists($column))
{
throw new App_Module_Exception('Column name not set or not exists');
}
$r = array(
'%',
'\'',
'"',
'<',
'>',
'\\',
'/',
);
$filter_value = str_replace($r, '', $filter_value);
$filter_value = preg_replace("'\s+'", ' ', $filter_value);
$filter_value = htmlspecialchars($filter_value);
if($filter_value)
{
if($is_not)
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' NOT LIKE ?',
'value' => '%'. $filter_value .'%',
);
}
else
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' LIKE ?',
'value' => '%'. $filter_value .'%',
);
}
}
if(isset($table)) unset($table);
return $condition;
}
/**
*
* @param type $filter_value
* @param type $column
* @param type $parameters
* @param type $var_table_name
* @return string
* @final
*/
final public function filterUrl($filter_value, $column, $parameters = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(is_array($column))
{
$key = $column['key'];
$_column = $column['column'];
$column = '';
$column = $_column;
}
else
{
$column = (string)$column;
}
if(!$key) $key = $column;
$filter_value = (string)$filter_value;
$filter_value = $this->prefilterUrl($filter_value);
$parameters = $this->prefilterArray($parameters);
$is_not = $parameters['apply_not'];
$is_not = ($is_not ? 1 : 0);
$table = $this->getTable($var_table_name);
$condition = null;
if(!$column || !$table->isColumnExists($column))
{
throw new App_Module_Exception('Column name not set or not exists');
}
if($filter_value)
{
if($is_not)
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' != ?',
'value' => $filter_value,
);
}
else
{
$condition = array(
'condition' => self::PLACEHOLDER_TABLENAME .'.'. $column .' = ?',
'value' => $filter_value,
);
}
}
if(isset($table)) unset($table);
if(isset($parameters)) unset($parameters);
return $condition;
}
/**
* Apply order and limit, also change current page
*
* @param $select SELECT object
* @param $order Apply order rule
* @param $limit Limit amount of results
* @param $page Current page
* @param $var_table_name Which table should be used
* @return SELECT object with ORDER BY and LIMIT applied
* @see self::DEFAULT_INSTANCE_SELECT
* @final
*/
final public function applyOrderAndLimit($select, $order = null, $limit = null, $page = null, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$order = $this->_replacePlaceholders($order, $var_table_name);
$select->order($order);
$limit = (int)$limit;
if($limit > 0)
{
$select->limitPage($page, $limit);
}
return $select;
}
/**
* Join related tables to self::DEFAULT_INSTANCE_SELECT object
*
* @param $select SELECT object
* @param $select_fields Select additional fields or not
* @param $var_table_name Which table should be used
* @return SELECT object with joined tables. Keep in mind, that you can't update or delete result row, unless you set 'setReadOnly' to 'false'
* @see self::DEFAULT_INSTANCE_SELECT
*/
public function joinRelatedTables($select, $select_fields = true, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$select = $this->prefilterSelect($select, $var_table_name);
return $select;
}
/**
* Prefilter ID, convert it into integer and checking that it's more than 0.
*
* @param $id ID to prefilter
* @return Result ID as integer
* @throws If result ID equal or less that 0
* @final
*/
final public function prefilterId($id)
{
if(!is_numeric($id)) $id = null;
$id = (int)$id;
if($id <= 0)
{
throw new App_Module_Exception('ID required for operation', $this->getExceptionCode(55));
}
return $id;
}
/**
* Prefilter WHERE conditions, trying to validate all incorrect input
*
* @param $where WHERE conditions to prefilter
* @return Prefiltered array with correct WHERE conditions and correct structure
* @final
*/
final public function prefilterWhere($where)
{
$where = $this->prefilterArray($where);
if(!$this->isMultiArray($where))
{
$where = array();
}
// All WHERE must have 'condition' (but don't need to have 'value')
foreach($where as $k => $where_arr)
{
// Use case: Someone passed array without associative keys, but with numeric. So we assume, that 0 => 'condition' and 1 => 'value'
if(!$where_arr['condition'] && isset($where_arr[0]))
{
$where_arr['condition'] = $where_arr[0];
unset($where_arr[0]);
}
if(!$where_arr['value'] && isset($where_arr[1]))
{
$where_arr['value'] = $where_arr[1];
unset($where_arr[1]);
}
if(!$where_arr['condition']) unset($where[$k]);
// Someone can pass conditions as array and only one value. We must be sure, that condition key properly placed
if(is_array($where_arr['condition'])) $where[$k]['condition'] = @array_values($where_arr['condition']);
// In case Zend will change something in the future and start requiring value to every WHERE
if(!isset($where_arr['value'])) $where[$k]['value'] = '';
}
$where = $this->prefilterArray($where);
return $where;
}
/**
* Making any input into array
*
* @param $array Input, which should be prefiltered
* @param $unique_only Check for unique values in array or not
* @return Prefiltered value
* @final
*/
final public function prefilterArray($array, $unique_only = false)
{
if(!$array || is_object($array) || is_resource($array)) $array = array();
if(!is_array($array)) $array = array($array);
if($unique_only) $array = array_unique($array);
return $array;
}
final public function prefilterUrl($url, $protocol = 'http')
{
$_protocols = array(
'http',
'https',
);
if(!in_array($protocol, $_protocols)) $protocol = 'http';
$url = str_replace('php://', '', $url);
if($url)
{
if(strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) $url = $protocol .'://'. $url;
$url = mb_strtolower($url);
}
return $url;
}
/**
* Checks if array is multidimensional
*
* @param $a Array to check
* @param $is_strict Should all inner values be array or not
* @return
*/
final public function isMultiArray($a, $is_strict = false)
{
if(!is_array($a)) return false;
foreach($a as $v)
{
if(!$is_strict)
{
if(is_array($v)) return true;
}
else
{
if(!is_array($v)) return false;
}
}
return ($is_strict ? true : false);
}
/**
*
* @param $row Row to check
* @param $instanceof Instance of which object it should be
* @return
* @final
* @see self::DEFAULT_INSTANCE_ROW
*/
final public function prefilterRow($row, $instanceof = self::DEFAULT_INSTANCE_ROW)
{
$instanceof = (string)$instanceof;
if(!$instanceof)
{
$instanceof = self::DEFAULT_INSTANCE_ROW;
}
if($instanceof == self::DEFAULT_INSTANCE_ROW)
{
if($this->isObjectAndInstance($row, $instanceof))
{
try
{
if($row->isColumnExists('role'))
{
$instanceof = $row->getRowClassFromTable($row->get_role());
}
else
{
$instanceof = $row->getRowClassFromTable();
}
}
catch(Zend_Db_Table_Exception $e)
{
$instanceof = self::DEFAULT_INSTANCE_ROW;
}
}
}
if(!$instanceof) $instanceof = self::DEFAULT_INSTANCE_ROW;
if(!$this->isObjectAndInstance($row, $instanceof))
{
throw new App_Module_Exception_NotObject('Row is empty, not object or not instance of '. $instanceof, $this->getExceptionCode(58));
}
return $row;
}
/**
* Checks SELECT object. If SELECT object is not instance of self::DEFAULT_INSTANCE_SELECT , new SELECT object will be created
*
* @param $select SELECT object
* @param $var_table_name Which table should be used
* @return
* @see self::DEFAULT_INSTANCE_SELECT
* @final
*/
final public function prefilterSelect($select, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$var_table_name = $this->prefilterVarTableName($var_table_name);
if(!$this->isObjectAndInstance($select, self::DEFAULT_INSTANCE_SELECT))
{
$select = $this->prepareSelect(array(), $var_table_name);
}
return $select;
}
/**
* Replace placeholders in $haystack with values (for example, replace self::PLACEHOLDER_TABLENAME with $var_table_name table name
*
* @param $haystack Haystack with values, which should be replaced
* @param $var_table_name Which table should be used
* @return
* @see self::PLACEHOLDER_TABLENAME
* @final
*/
final protected function _replacePlaceholders($haystack, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$table_name = $this->getTableName($var_table_name);
$r = array(
self::PLACEHOLDER_TABLENAME => $table_name,
);
if(is_array($haystack))
{
foreach($haystack as $k => $value)
{
if(!is_string($value)) continue;
$haystack[$k] = str_replace(array_keys($r), array_values($r), $value);
}
}
else
{
$haystack = (string)$haystack;
$haystack = str_replace(array_keys($r), array_values($r), $haystack);
}
return $haystack;
}
/**
* Return pure SQL code from prepared SELECT object
*
* @param $where Array with WHERE conditions to apply
* @param $filter Array with columns to filter via prepareFilter()
* @param $var_table_name Which table to use
* @return Prepared SQL with WHERE and filter conditions applied
*/
final protected function _getSelectAsString($where = array(), $filter = array(), $rules = array(), $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$select = $this->prepareSelect($where, $var_table_name);
if(is_string($rules)) $var_table_name = $rules;
if(isset($filter['rules']))
{
$rules = $filter['rules'];
$filter = $filter['filter'];
}
$conditions = $this->applyFilterRules($filter, $rules, $var_table_name);
$conditions = $this->prefilterWhere($conditions);
if(!empty($conditions))
{
$select = $this->applyWhere($select, $conditions, $var_table_name);
}
$select = $this->prepareFilter($select, $filter, $var_table_name);
$sql = $select->__toString();
if(isset($select)) unset($select);
return $sql;
}
/**
* Applies password hashing algorythm, including salt (if passed as argument). You can change positioning rule
*
* @param $password Password to hash
* @param $salt Salt to apply
* @param $pos_rule Position rule. You can use:
* #PASS# (full password string),
* #SALT# (full salt string),
* #PA# (half password string),
* #SS# (other half password string),
* #SA# (half salt string),
* #LT# (other half salt string)
* @return
* @throws App_Module_Exception_DataRequired If $password is not a valid string
* @final
*/
final public function applyPasswordHashing($password, $salt = null, $pos_rule = '#PASS##SALT#')
{
if(!$this->isValidString($password)) throw new App_Module_Exception_DataRequired('Password required for generation');
if(!$this->isValidString($pos_rule)) $pos_rule = '#PASS##SALT#';
$pass_half = substr($password, 0, round(strlen($password) / 2));
$pass_half2 = substr($password, round(strlen($password) / 2), strlen($password));
$salt_half = '';
$salt_half2 = '';
if($salt)
{
$salt = (string)$salt;
$salt_half = substr($salt, 0, round(strlen($salt) / 2));
$salt_half2 = substr($salt, round(strlen($salt) / 2), strlen($salt));
}
$r = array(
'#PASS#' => $password,
'#SALT#' => $salt,
'#PA#' => $pass_half,
'#SS#' => $pass_half2,
'#SA#' => $salt_half,
'#LT#' => $salt_half2,
);
$password = str_replace(array_keys($r), array_values($r), $pos_rule);
if(function_exists('hash'))
{
$password = hash('sha256', $password);
$password = hash('whirlpool', $password);
}
return $password;
}
/**
* Return current user row
*
* @return Current user row
* @see self::DEFAULT_INSTANCE_ROW
* @final
*/
final public function getActor()
{
return $this->_actor;
}
/**
* Set current actor
*
* @param $user_row Current user row
* @return <$this> Current object, so you could chain calls
* @see self::DEFAULT_INSTANCE_ROW
* @final
*/
final public function setActor($user_row)
{
if(!$this->isObjectAndInstance($user_row, self::DEFAULT_INSTANCE_USER_ROW))
{
throw new App_Module_Exception('User row must be instance of '. self::DEFAULT_INSTANCE_USER_ROW, $this->getExceptionCode(59));
}
$this->_actor = $user_row;
return $this;
}
/**
* Return configuration array or configuration object (based on your settings)
*
* @return Configuration array or configuration object
* @final
*/
final public function getConfig()
{
if(Zend_Registry::isRegistered('Zend_Config'))
{
return Zend_Registry::get('Zend_Config');
}
return null;
}
/**
* Return Log object
*
* @return Zend_Log object, if logs initialized or NULL if not
* @final
*/
final public function getLog()
{
if(Zend_Registry::isRegistered('Zend_Log'))
{
return Zend_Registry::get('Zend_Log');
}
return null;
}
/**
* Write data in log file via log adapter
*
* @param $message Message to write in log
* @param $priority Priority of message
* @param $extras Extra data to write
* @return Log object if logs initialized and no error occured or NULL if logs not initialized or any error catched
* @final
*/
final public function writeLog($message, $priority = self::LOG_INFO, $extras = array())
{
$log = null;
try
{
$log = $this->getLog();
if($log)
{
$log->log($message, $priority, $extras);
}
}
catch(Zend_Log_Exception $e)
{
return null;
}
return $log;
}
/**
* Format code into 10-chars integer
*
* @param $code Event code to format
* @return Formatted exception code or NULL if self::_EXCEPTION_CODE is not present
* @see self::_EXCEPTION_CODE
* @final
*/
final public function getExceptionCode($code)
{
$base = self::_EXCEPTION_CODE;
$code = (string)$code;
$length = strlen($code);
if(!$code)
{
return 0;
}
if($length > 5)
{
$_exception_code .= '00002';
throw new App_Module_Exception_WrongData('Incorrect code length. It can\'t be more than 5 characters', $_exception_code);
}
if($length != 5)
{
while($length < 5)
{
$code = '0'. $code;
$length++;
}
}
return $base . $code;
}
/**
* Format date in correct way
*
* @param $date Date to format
* @param $is_datetime Is datetime format (self::DEFAULT_DATETIME) or just date (self::DEFAULT_DATE)
* @return Formatted date
* @final
*/
final public function prepareDate($date, $is_datetime = false)
{
$result = null;
if($date)
{
$date_object = new Zend_Date($date);
if($is_datetime)
{
$result = $date_object->get(self::DEFAULT_DATETIME);
}
else
{
$result = $date_object->get(self::DEFAULT_DATE);
}
}
return $result;
}
/**
* Return Translate object
*
* @return
* @final
*/
final public function getTranslate()
{
try
{
return new Zend_Translate();
}
catch(Zend_Translate_Exception $e)
{
return null;
}
}
/**
* Abstract method for data loading. Useful if you must load some related data
*
* @param $array_or_object Array, which should be loaded with data
* @param $level How many data should be loaded
* @param $var_table_name Which table to use
* @return Array with loaded data
*/
public function loadData($array_or_object, $level = 3, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
$level = (int)$level;
if(!$level) $level = 3;
$array = array();
if($this->isObjectAndInstance($array_or_object, self::DEFAULT_INSTANCE_ROWSET_PAGINATE))
{
foreach($array_or_object as $obj)
{
$array[$obj->get_id()] = $obj->getData(($level > 3 ? true : false));
}
}
elseif(is_array($array_or_object))
{
if(@isset($array_or_object['records']))
{
$array = $array_or_object['records'];
}
else
{
$array = $array_or_object;
}
}
return $array;
}
/**
* Prepare Zend_Db_Expr with replaced placeholders
*
* @param $expression Expression to prepare
* @param $var_table_name Which table to use
* @return
* @final
* @see Zend_Db_Expr
*/
final public function prepareDbExpression($expression, $var_table_name = self::DEFAULT_VAR_TABLE_NAME)
{
if(!is_string($expression) || !$expression)
{
throw new App_Module_Exception('Wrong data passed as expression');
}
$expression = $this->_replacePlaceholders($expression, $var_table_name);
return new Zend_Db_Expr($expression);
}
/**
* Check is passed variable $object not empty, is object and instance of $instanceof
*
* @param $object Object to check
* @param $instancename Instance of which object $object should be. Can be object (class name will be used), string or array
* @return If $instancename is array, will be returned instance class name or false, else true or false will be returned
*/
public function isObjectAndInstance($object, $instancename)
{
if(is_object($instancename)) $instancename = get_class($instancename);
if(is_resource($instancename)) throw new App_Module_Exception_WrongData('Instance name can\'t be a resource');
if(is_array($instancename))
{
if(empty($instancename)) throw new App_Module_Exception_WrongData('Instance name passed as empty array');
foreach($instancename as $instance)
{
if($object && is_object($object) && ($object instanceof $instance))
{
return $instance;
}
}
return false;
}
$instancename = (string)$instancename;
if(!$instancename) return false;
if($object && is_object($object) && ($object instanceof $instancename))
{
return true;
}
return false;
}
/**
* Is debug enabled or not
*
* @return
*/
public function isDebug()
{
return ($this->_is_debug ? true : false);
}
}