classes/Gems/Util/UtilAbstract.php
<?php
/**
*
* @package Gems
* @subpackage UtilAbstract
* @author Matijs de Jong <mjong@magnafacta.nl>
* @copyright Copyright (c) 2015 Erasmus MC
* @license New BSD License
*/
namespace Gems\Util;
/**
* Abstract utility class containing caching and sql loading function
*
* @package Gems
* @subpackage UtilAbstract
* @copyright Copyright (c) 2015 Erasmus MC
* @license New BSD License
* @since Class available since version 1.7.2 24-sep-2015 11:37:10
*/
class UtilAbstract extends \MUtil_Translate_TranslateableAbstract
{
/**
*
* @var \Zend_Cache_Core
*/
protected $cache;
/**
*
* @var \Zend_Db_Adapter_Abstract
*/
protected $db;
/**
* @var \Zend_Locale
*/
protected $locale;
/**
*
* @var \Gems_Project_ProjectSettings
*/
protected $project;
/**
*
* @var \MUtil_Registry_Source
*/
protected $source;
/**
* Returns a callable if a method is called as a variable
*
* @param string $name
* @return \MUtil_Lazy_Call
*/
public function __get($name)
{
if (method_exists($this, $name)) {
// Return a callable
return \MUtil_Lazy::call(array($this, $name));
}
throw new \Gems_Exception_Coding("Unknown method '$name' requested as callable.");
}
/**
* Utility function for loading a complete query from cache into objects
*
* @param string $cacheId The class is prepended to this id
* @param object $object The object to put the data in
* @param mixed $sql string or \Zend_Db_Select
* @param array $binds sql paramters
* @param mixed $tags atring or array of strings
* @return array
*/
protected function _getObjectsAllCached($cacheId, $object, $sql, $binds = null, $tags = array())
{
$output = array();
$rows = $this->_getSelectAllCached($cacheId, $sql, $binds, $tags);
if ($rows) {
$this->source->applySource($object);
foreach ($rows as $row) {
$tmp = clone $object;
$tmp->exchangeArray($row);
$output[] = $tmp;
}
}
return $output;
}
/**
* Utility function for loading a complete query from cache
*
* @param string $cacheId The class is prepended to this id
* @param mixed $sql string or \Zend_Db_Select
* @param array $binds sql paramters
* @param mixed $tags atring or array of strings
* @param boolean $natSort Perform a natsort over the output
* @return array
*/
protected function _getSelectAllCached($cacheId, $sql, $binds = array(), $tags = array(), $natSort = false)
{
$cacheId = strtr(get_class($this) . '_a_' . $cacheId, '\\/', '__');
$result = $this->cache->load($cacheId);
if ($result) {
return $result;
}
try {
$result = $this->db->fetchAll($sql, (array) $binds);
if ($natSort) {
natsort($result);
}
$this->cache->save($result, $cacheId, (array) $tags);
} catch (\Zend_Db_Statement_Mysqli_Exception $e) {
error_log($e->getMessage());
$result = array();
}
return $result;
}
/**
* Utility function for loading a single column from cache
*
* @param string $cacheId The class is prepended to this id
* @param mixed $sql string or \Zend_Db_Select
* @param array $binds sql paramters
* @param mixed $tags atring or array of strings
* @param boolean $natSort Perform a natsort over the output
* @return array With a column ofr values
*/
protected function _getSelectColCached($cacheId, $sql, $binds = array(), $tags = array(), $natSort = false)
{
$cacheId = strtr(get_class($this) . '_a_' . $cacheId, '\\/', '__');
$result = $this->cache->load($cacheId);
if ($result) {
return $result;
}
try {
$result = $this->db->fetchCol($sql, (array) $binds);
if ($natSort) {
natsort($result);
}
$this->cache->save($result, $cacheId, (array) $tags);
} catch (\Zend_Db_Statement_Mysqli_Exception $e) {
error_log($e->getMessage());
$result = [];
}
return $result;
}
/**
* Utility function for loading a query paired from cache
*
* @param string $cacheId The class is prepended to this id
* @param mixed $sql string or \Zend_Db_Select
* @param array $binds sql paramters
* @param mixed $tags a string or array of strings
* @param string Optional function to sort on, only known functions will do
* @return array
*/
protected function _getSelectPairsCached($cacheId, $sql, $binds = array(), $tags = array(), $sort = null)
{
$cacheId = strtr(get_class($this) . '_p_' . $cacheId, '\\/', '__');
$result = $this->cache->load($cacheId);
if ($result) {
return $result;
}
try {
$result = $this->db->fetchPairs($sql, (array) $binds);
if ($result && $sort) {
$this->_sortResult($result, $sort);
}
$this->cache->save($result, $cacheId, (array) $tags);
} catch (\Zend_Db_Statement_Mysqli_Exception $e) {
error_log($e->getMessage());
$result = array();
}
return $result;
}
/**
* Utility function for loading a query from cache
*
* @param string $cacheId The class is prepended to this id
* @param mixed $sql string or \Zend_Db_Select
* @param callable $function The function called with each row to form the result
* @param array $binds sql paramters
* @param mixed $tags string or array of strings
* @param string Optional function to sort on, only known functions will do
* @return array
*/
protected function _getSelectPairsProcessedCached($cacheId, $sql, $function, $binds = array(), $tags = array(), $sort = null)
{
$cacheId = get_class($this) . '_' . $cacheId;
$result = false; //$this->cache->load($cacheId);
if ($result) {
return $result;
}
try {
$result = $this->db->fetchPairs($sql, (array) $binds);
if ($result) {
foreach ($result as $id => & $value) {
$value = call_user_func($function, $value);
}
if ($sort) {
$this->_sortResult($result, $sort);
}
}
$this->cache->save($result, $cacheId, (array) $tags);
} catch (\Zend_Db_Statement_Mysqli_Exception $e) {
error_log($e->getMessage());
$result = array();
}
return $result;
}
/**
* Utility function for loading a query from cache
*
* @param string $cacheId The class is prepended to this id
* @param mixed $sql string or \Zend_Db_Select
* @param callable $function The function called with each row to form the result
* @param string $keyField The field containing the key for each row
* @param mixed $tags string or array of strings
* @param string Optional function to sort on, only known functions will do
* @return array
*/
protected function _getSelectProcessedCached($cacheId, $sql, $function, $keyField, $tags = array(), $sort = null)
{
$cacheId = get_class($this) . '_' . $cacheId;
$result = false; //$this->cache->load($cacheId);
if ($result) {
return $result;
}
$result = array();
try {
$rows = $this->db->fetchAll($sql);
if ($rows) {
foreach ($rows as $row) {
if (! isset($result[$row[$keyField]])) {
$result[$row[$keyField]] = call_user_func($function, $row);
}
}
if ($sort) {
$this->_sortResult($result, $sort);
}
}
$this->cache->save($result, $cacheId, (array) $tags);
} catch (\Zend_Db_Statement_Mysqli_Exception $e) {
error_log($e->getMessage());
}
return $result;
}
/**
* Utility function for loading a translated paired from cache
*
* @param string $table
* @param string $key
* @param string $label
* @param mixed $tags a string or array of strings
* @param string $where Input for $select->where()
* @param string Optional function to sort on, only known functions will do
* @return array
* @throws \Zend_Cache_Exception
*/
protected function _getTranslatedPairsCached($table, $key, $label, $tags = array(), $where = null, $sort = null)
{
$lang = $this->locale->getLanguage();
$cacheId = $this->cleanupForCacheId("__trans $table $key $label $where ");
$cacheLang = $cacheId . $this->cleanupForCacheId($lang . "_");
// \MUtil_Echo::track($cacheId, $cacheLang);
$result = $this->cache->load($cacheLang);
if ($result) {
return $result;
}
$result = $this->cache->load($cacheId);
if (! $result) {
$select = $this->db->select();
$select->from($table, [$key, $label]);
if ($where) {
$select->where($where);
}
try {
$result = $this->db->fetchPairs($select);
$this->cache->save($result, $cacheId, (array) $tags);
} catch (\Zend_Exception $e) {
// Do not save on an exception
error_log($e->getMessage());
return [];
}
}
if ($result && $this->project->translateDatabaseFields() && ($lang != $this->project->getLocaleDefault())) {
$tSelect = $this->db->select();
$tSelect->from('gems__translations', ['gtrs_keys', 'gtrs_translation'])
->where('gtrs_table = ?', $table)
->where('gtrs_field = ?', $label)
->where('gtrs_iso_lang = ?', $lang)
->where('LENGTH(gtrs_translation) > 0');
$translations = $this->db->fetchPairs($tSelect);
// \MUtil_Echo::track($tSelect->__toString(), $translations);
if ($translations) {
foreach ($result as $item => $value) {
if (isset($translations[$item])) {
// Set value to the translation
$result[$item] = $translations[$item];
}
}
}
}
if ($result && $sort) {
$this->_sortResult($result, $sort);
}
// \MUtil_Echo::track($result);
// Save the translated version
$this->cache->save($result, $cacheLang, (array) $tags);
return $result ?: [];
}
/**
* Sort the array using the specified sort function
*
* @param array $result
* @param callable $sort Sort function
*/
protected function _sortResult(array &$result, $sort = 'asort')
{
// Sorting
switch ($sort) {
case 'asort':
asort($result);
break;
case 'ksort':
ksort($result);
break;
case 'natsort':
natsort($result);
break;
default:
$sort($result);
}
}
/**
* Cleans up everything to a save cacheId
*
* @param string $cacheId
* @return string
*/
public static function cleanupForCacheId($cacheId)
{
return preg_replace('([^a-zA-Z0-9_])', '_', $cacheId);
}
}