Files
drmaterac.pl/modules/pagecache/controllers/admin/AdminPageCacheDatasController.php
2025-03-21 20:24:43 +01:00

735 lines
30 KiB
PHP

<?php
/**
* Page Cache Ultimate, Page Cache standard and Speed pack are powered by Jpresta (jpresta . com)
*
* @author Jpresta
* @copyright Jpresta
* @license See the license of this module in file LICENSE.txt, thank you.
*/
use JPresta\SpeedPack\JprestaUtils;
if (!defined('_PS_VERSION_')) {exit;}
include_once(dirname(__FILE__) . '/../../pagecache.php');
class AdminPageCacheDatasController extends ModuleAdminController
{
public $php_self = null;
public function init()
{
if (!isset(Context::getContext()->link)) {
/* Link should be initialized in the context but sometimes it is not */
$https_link = (Tools::usingSecureMode() && Configuration::get('PS_SSL_ENABLED')) ? 'https://' : 'http://';
Context::getContext()->link = new Link($https_link, $https_link);
}
// avoid useless treatments
}
public function initHeader()
{
// avoid useless treatments
}
public function setMedia($isNewTheme = false)
{
// avoid useless treatments
}
public function initContent()
{
if (Tools::getIsset('url') && Tools::getIsset('id_context')) {
die(
Context::getContext()->smarty->fetch(_PS_MODULE_DIR_ . '/pagecache/views/templates/admin/get-content-tab-datas_cache.tpl')
. $this->module->getCache(Tools::getValue('id_shop'))->get(Tools::getValue('url'), PageCacheDAO::getContextKeyById(Tools::getValue('id_context')))
);
}
header('Access-Control-Allow-Origin: *');
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
header('Cache-Control: max-age=300, private');
}
header('Content-type: application/json');
if ($_SERVER['REQUEST_METHOD'] === 'GET' && Tools::getValue('type') === 'contexts') {
self::displayContextsDatas();
}
elseif ($_SERVER['REQUEST_METHOD'] === 'GET' && Tools::getValue('type') === 'ttfb') {
$this->displayTTFBDatas();
}
// DB table to use
$table = _DB_PREFIX_.PageCacheDAO::TABLE;
// Array of database columns which should be read and sent back to DataTables.
// The `db` parameter represents the column name in the database, while the `dt`
// parameter represents the DataTables column identifier. In this case simple
// indexes
$columns = array(
array('db' => 'url', 'dt' => 0, 'formatter' => function ($s, $row) {
return self::formatURL($s, $row);
}),
array('db' => 'cache_key', 'dt' => -1),
array('db' => 'id_shop', 'dt' => -1),
array('db' => 'id_context', 'dt' => 1, 'formatter' => function ($id_context) {
return self::formatContext(PageCacheDAO::getContextById((int)$id_context));
}),
array('db' => 'id_controller', 'dt' => 2, 'formatter' => function ($id_controller) {
return self::formatController($id_controller);
}),
array('db' => 'id_object', 'dt' => 3),
array('db' => 'last_gen', 'dt' => 4, 'formatter' => function ($d, $row) {
return self::formatLastGenerated($d, $row);
}),
array('db' => 'deleted', 'dt' => 5,'formatter' => function ($deleted) {
return self::formatDeleted($deleted);
}),
array('db' => 'count_hit', 'dt' => 6, 'formatter' => function ($s, $row) {
return self::formatHit($s, $row);
}),
array('db' => 'count_missed', 'dt' => -1),
);
if ($_SERVER['REQUEST_METHOD'] === 'POST' && Tools::getIsset('clear')) {
$searchUrl = trim($_POST['columns'][0]['search']['value']);
$searchContext = trim($_POST['columns'][1]['search']['value']);
$searchCtrl = (int) $_POST['columns'][2]['search']['value'];
$searchId = (int) $_POST['columns'][3]['search']['value'];
if ($searchCtrl || $searchId || $searchUrl || $searchContext) {
// Clear cache of filtered rows
self::simpleClear($_POST, $table, $columns);
}
else {
// Clear all
$this->module->clearCache('manually called from stats');
}
die(json_encode([]));
}
else {
$result = self::simple($_GET, $table, $columns);
die(json_encode($result));
}
}
private static function displayContextsDatas()
{
$data = [];
$pageSize = Tools::getValue('length', 10);
$start = Tools::getValue('start', 0);
$searchQuery = Tools::getValue('search', '');
$searchQuery = $searchQuery['value'];
if ($searchQuery && strpos($searchQuery, '=')!== false) {
$searchVals = explode(',', $searchQuery);
$whereClauses = [];
foreach ($searchVals as $searchVal) {
list($key, $val) = explode('=', $searchVal);
if ((int) $val > 0 && $key === 'id_lang') {
$whereClauses[] = 'id_lang=' . (int)$val;
} else if ((int) $val > 0 && $key === 'id_cur') {
$whereClauses[] = 'id_currency=' . (int)$val;
} else if ((int) $val > 0 && $key === 'id_country') {
$whereClauses[] = 'id_country=' . (int)$val;
} else if ($key === 'id_specs') {
if ((int) $val > 0) {
$whereClauses[] = 'id_specifics=' . (int)$val;
}
else if ($val === 'null') {
$whereClauses[] = 'id_specifics IS NULL';
}
} else if ((int) $val > 0 && $key === 'id_device') {
$whereClauses[] = 'id_device=' . (int)$val;
} else if ($key === 'id_group') {
if ((int) $val > 0) {
$whereClauses[] = 'id_fake_customer=' . (int)$val;
}
else if ($val === '0') {
$whereClauses[] = 'id_fake_customer IS NULL';
}
}
}
}
$select = 'SELECT *, count_hit_server + count_hit_static + count_hit_browser + count_hit_bfcache as count_hit,
count_hit_server + count_hit_static + count_hit_browser + count_hit_bfcache + count_missed as count_visit,
(count_hit_server + count_hit_static + count_hit_browser + count_hit_bfcache) * 100 / (count_hit_server + count_hit_static + count_hit_browser + count_hit_bfcache + count_missed) as hit_rate';
$selectTotal = 'SELECT count(*) as total_ctx, sum(count_hit_server + count_hit_static + count_hit_browser + count_hit_bfcache + count_missed) as total_visit_count, sum(count_bot) as total_bot_count';
$from = ' FROM `' . _DB_PREFIX_ . PageCacheDAO::TABLE_CONTEXTS . '`';
$whereClauses[] = 'id_shop=' . (int) Shop::getContextShopID();
$where = ' WHERE ' . implode(' AND ', $whereClauses);
$limit = " LIMIT $pageSize OFFSET $start";
$orders = Tools::getValue('order', []);
if (count($orders) === 1) {
$order = $orders[0];
$orderDir = $order['dir'];
switch ($order['column']) {
case 3:
$orderCol = 'hit_rate';
break;
case 4:
$orderCol = 'count_bot';
break;
case 2:
default:
$orderCol = 'count_visit';
break;
}
$orderBy = ' ORDER BY ' . $orderCol . ' ' . $orderDir;
}
else {
$orderBy = ' ORDER BY count_visit desc';
}
$total_ctx = 0;
$total_visit_count = 0;
$total_bot_count = 0;
$rows = JprestaUtils::dbSelectRows($select . $from . $where . $orderBy . $limit);
$rowsTotal = JprestaUtils::dbSelectRows($selectTotal . $from . $where);
if (count($rowsTotal) > 0) {
$total_ctx = (int) $rowsTotal[0]['total_ctx'];
$total_visit_count = (int) $rowsTotal[0]['total_visit_count'];
$total_bot_count = (int) $rowsTotal[0]['total_bot_count'];
}
if (count($rows) > 0) {
foreach ($rows as $row) {
$statsContext = PageCacheDAO::getStatsByContext($row['id']);
$data[] = (object) [
0 => $row['context_key'],
1 => self::formatContext($row),
2 => !$total_visit_count ? 0 : $row['count_visit'] . ' (' . round($row['count_visit'] * 100 / $total_visit_count, 2) . '%)',
3 => self::formatHit((int) $row['count_hit'], $row),
4 => !$total_bot_count ? 0 : $row['count_bot'] . ' (' . round($row['count_bot'] * 100 / $total_bot_count, 2) . '%)',
5 => !$statsContext['count'] ? '0/0 (0%)' : $statsContext['count_deleted'] . '/' . $statsContext['count'] . ' ('.round($statsContext['count_deleted'] * 100 / $statsContext['count'], 2).'%)'
];
}
}
$recordsTotal = $recordsFiltered = $total_ctx;
$datas = [
'data' => $data,
'recordsFiltered' => $recordsFiltered,
'recordsTotal' => $recordsTotal
];
die(json_encode($datas));
}
private function displayTTFBDatas()
{
$controller = Tools::getValue('controller_name');
$id_controller = PageCache::getManagedControllerId($controller);
$whereClause = 'WHERE id_shop=' . (int) Shop::getContextShopID();
if ($id_controller) {
$whereClause .= ' AND id_controller=' . (int) $id_controller;
}
$whereClause .= ' AND date_add >= CURRENT_DATE() - interval 13 DAY';
$query = 'SELECT UNIX_TIMESTAMP(day_add) AS day,
ROUND(AVG(ttfb_ms_hit_server)) AS ttfb_ms_hit_server,
ROUND(AVG(ttfb_ms_hit_static)) AS ttfb_ms_hit_static,
ROUND(AVG(ttfb_ms_hit_browser)) AS ttfb_ms_hit_browser,
ROUND(AVG(ttfb_ms_hit_bfcache)) AS ttfb_ms_hit_bfcache,
ROUND(AVG(ttfb_ms_missed)) AS ttfb_ms_missed
FROM `' . _DB_PREFIX_ . PageCacheDAO::TABLE_PERFS . '` '.$whereClause.' GROUP BY day_add ORDER BY day_add ASC;';
$rows = JprestaUtils::dbSelectRows($query);
$missed = $server = $static = $browser = $bf = [];
foreach ($rows as $row) {
$missed[] = ['x' => (int)$row['day'], 'y' => $row['ttfb_ms_missed']];
$server[] = ['x' => (int)$row['day'], 'y' => $row['ttfb_ms_hit_server']];
$static[] = ['x' => (int)$row['day'], 'y' => $row['ttfb_ms_hit_static']];
$browser[] = ['x' => (int)$row['day'], 'y' => $row['ttfb_ms_hit_browser']];
$bf[] = ['x' => (int)$row['day'], 'y' => $row['ttfb_ms_hit_bfcache']];
}
$datas = [
[
'values' => $missed,
'key' => $this->module->l('Cache not available'),
'color' => '#ce720b'
],
[
'values' => $server,
'key' => $this->module->l('Server cache'),
'color' => '#007e00'
],
[
'values' => $static,
'key' => $this->module->l('Static cache'),
'color' => '#00bd00'
],
[
'values' => $browser,
'key' => $this->module->l('Browser cache'),
'color' => '#00da00'
],
[
'values' => $bf,
'key' => $this->module->l('Back/forward cache'),
'color' => '#00ff00'
],
];
$query = 'SELECT date_format(MIN(day_add), \'%Y-%m-%d\') AS start_date,
SUM(1) AS total_count
FROM `' . _DB_PREFIX_ . PageCacheDAO::TABLE_PERFS . '` '.$whereClause;
$rows = JprestaUtils::dbSelectRows($query);
$start_date = 0;
$total_count = 0;
if (count($rows) > 0) {
$start_date = $rows[0]['start_date'];
$total_count = (int)$rows[0]['total_count'];
}
die(json_encode(['datas' => $datas, 'start_date' => $start_date, 'total_count' => $total_count]));
}
private static function formatController($id_controller) {
return PageCache::getManagedControllerNameById($id_controller);
}
private static function formatHit($count_hit, $row) {
$smarty = Context::getContext()->smarty;
$smarty->assign('count_hit', (int) $count_hit);
$smarty->assign('count_missed', (int) $row['count_missed']);
$smarty->assign('count_percent', round((((int) $count_hit * 100) / max(1, ((int) $count_hit + (int) $row['count_missed']))),1));
return $smarty->fetch(_PS_MODULE_DIR_ . '/pagecache/views/templates/admin/get-content-tab-datas_hit.tpl');
}
private static function formatDeleted($deleted) {
$smarty = Context::getContext()->smarty;
$smarty->assign('deleted', $deleted);
$smarty->assign('isPs17', Tools::version_compare(_PS_VERSION_, '1.6', '>'));
return $smarty->fetch(_PS_MODULE_DIR_ . '/pagecache/views/templates/admin/get-content-tab-datas_deleted.tpl');
}
private static function formatLastGenerated($d, $row) {
$lastGen = strtotime($d);
$cache_ttl = 60 * ((int)Configuration::get('pagecache_'.PageCache::getManagedControllerNameById($row['id_controller']).'_timeout'));
$age = time() - $lastGen;
$ttl = $cache_ttl - $age;
if ($cache_ttl <= 0) {
$percent = 0;
}
elseif ($cache_ttl <= $age) {
$percent = 100;
}
else {
$percent = $age * 100 / $cache_ttl;
}
$color = '#ccc';
if ($percent >= 100) {
$color = 'red';
}
else if ($percent >= 95) {
$color = 'orange';
}
$smarty = Context::getContext()->smarty;
$smarty->assign('lastGen', strtotime($d));
if ($cache_ttl == -60) {
$ttl_msg = 'forever';
}
elseif ($ttl <= 0) {
$ttl_msg = 'dead';
}
else {
$ttl_msg = self::getNiceDuration($ttl);
}
$smarty->assign('age', self::getNiceDuration($age));
$smarty->assign('last_gen', date('Y-m-d H:i:s', strtotime($d)));
$smarty->assign('ttl_msg', $ttl_msg);
$smarty->assign('color', $color);
$smarty->assign('percent', $percent);
return $smarty->fetch(_PS_MODULE_DIR_ . '/pagecache/views/templates/admin/get-content-tab-datas_lastgen.tpl');
}
private static function formatURL($url, $row) {
$smarty = Context::getContext()->smarty;
$smarty->clearAssign('flag_lang');
$smarty->clearAssign('flag_currency');
$smarty->clearAssign('flag_country');
$smarty->clearAssign('flag_device');
$smarty->clearAssign('flag_group');
$smarty->clearAssign('flag_tax_manager');
$smarty->clearAssign('flag_specifics');
$smarty->clearAssign('flag_specifics_more');
$smarty->clearAssign('flag_v_css');
$smarty->clearAssign('flag_v_js');
$smarty->clearAssign('url_cached');
if (!empty($row['id_lang'])) {
$smarty->assign('flag_lang', $row['id_lang']);
}
if (!empty($row['id_currency'])) {
$currency = new Currency($row['id_currency']);
$smarty->assign('flag_currency', $currency->sign);
}
if (!empty($row['id_country'])) {
$country = new Country($row['id_country']);
$smarty->assign('flag_country', $country->iso_code);
}
if (!empty($row['id_device'])) {
if ($row['id_device'] == PageCache::DEVICE_COMPUTER) {
$smarty->assign('flag_device', 'desktop');
}
elseif ($row['id_device'] == PageCache::DEVICE_TABLET) {
$smarty->assign('flag_device', 'tablet');
}
elseif ($row['id_device'] == PageCache::DEVICE_MOBILE) {
$smarty->assign('flag_device', 'mobile');
}
}
if (!empty($row['id_fake_customer'])) {
$jCustomer = new JprestaCustomer((int)$row['id_fake_customer']);
$smarty->assign('flag_group', $jCustomer->getLabel() . ' (#'.$row['id_fake_customer'].')');
}
if (!empty($row['id_tax_csz'])) {
$tax_manager_json = PageCacheDAO::getDetailsById($row['id_tax_csz']);
$smarty->assign('flag_tax_manager', $row['id_tax_csz']);
$smarty->assign('flag_tax_manager_more', JprestaUtilsTaxManager::toPrettyString($tax_manager_json));
}
if (!empty($row['id_specifics'])) {
$specifics = PageCacheDAO::getDetailsById($row['id_specifics']);
$jscks = new JprestaCacheKeySpecifics($specifics);
$smarty->assign('flag_specifics', $row['id_specifics']);
$smarty->assign('flag_specifics_more', $jscks->toPrettyString());
}
if (!empty($row['v_css'])) {
$smarty->assign('flag_v_css', $row['v_css']);
}
if (!empty($row['v_js'])) {
$smarty->assign('flag_v_js', $row['v_js']);
}
$smarty->assign('url', $url);
if (array_key_exists('deleted', $row) && !$row['deleted'] && $row['cache_key']) {
$cacheLink =
Context::getContext()->link->getAdminLink(
'AdminPageCacheDatas',
true,
array(),
array('url' => $url, 'id_context' => $row['id_context']));
if (Tools::version_compare(_PS_VERSION_, '1.7', '<')) {
$cacheLink .= '&url=' . urlencode($url) . '&id_context=' . (int) $row['id_context'];
}
$smarty->assign('url_cached', $cacheLink);
}
$smarty->assign('isPs17', Tools::version_compare(_PS_VERSION_, '1.6', '>'));
return $smarty->fetch(_PS_MODULE_DIR_ . '/pagecache/views/templates/admin/get-content-tab-datas_url.tpl');
}
public static function formatContext($contextRow) {
$smarty = Context::getContext()->smarty;
$smarty->clearAssign('flag_lang');
$smarty->clearAssign('flag_currency');
$smarty->clearAssign('flag_country');
$smarty->clearAssign('flag_device');
$smarty->clearAssign('flag_group');
$smarty->clearAssign('flag_tax_manager');
$smarty->clearAssign('flag_specifics');
$smarty->clearAssign('flag_specifics_more');
$smarty->clearAssign('flag_v_css');
$smarty->clearAssign('flag_v_js');
$smarty->assign('id_context', $contextRow['id']);
if (!empty($contextRow['id_lang'])) {
$smarty->assign('flag_lang', $contextRow['id_lang']);
}
if (!empty($contextRow['id_currency'])) {
$currency = new Currency($contextRow['id_currency']);
$smarty->assign('flag_currency', $currency->sign);
}
if (!empty($contextRow['id_country'])) {
$country = new Country($contextRow['id_country']);
$smarty->assign('flag_country', $country->iso_code);
}
if (!empty($contextRow['id_device'])) {
if ($contextRow['id_device'] == PageCache::DEVICE_COMPUTER) {
$smarty->assign('flag_device', 'desktop');
}
elseif ($contextRow['id_device'] == PageCache::DEVICE_TABLET) {
$smarty->assign('flag_device', 'tablet');
}
elseif ($contextRow['id_device'] == PageCache::DEVICE_MOBILE) {
$smarty->assign('flag_device', 'mobile');
}
}
if (!empty($contextRow['id_fake_customer'])) {
$jCustomer = new JprestaCustomer((int)$contextRow['id_fake_customer']);
$smarty->assign('flag_group', $jCustomer->getLabel() . ' (#'.$contextRow['id_fake_customer'].')');
}
if (!empty($contextRow['id_tax_csz'])) {
$tax_manager_json = PageCacheDAO::getDetailsById($contextRow['id_tax_csz']);
$smarty->assign('flag_tax_manager', $contextRow['id_tax_csz']);
$smarty->assign('flag_tax_manager_more', JprestaUtilsTaxManager::toPrettyString($tax_manager_json));
}
if (!empty($contextRow['id_specifics'])) {
$specifics = PageCacheDAO::getDetailsById($contextRow['id_specifics']);
$jscks = new JprestaCacheKeySpecifics($specifics);
$smarty->assign('flag_specifics', $contextRow['id_specifics']);
$smarty->assign('flag_specifics_more', $jscks->toPrettyString());
}
if (!empty($contextRow['v_css'])) {
$smarty->assign('flag_v_css', $contextRow['v_css']);
}
if (!empty($contextRow['v_js'])) {
$smarty->assign('flag_v_js', $contextRow['v_js']);
}
$smarty->assign('isPs17', Tools::version_compare(_PS_VERSION_, '1.6', '>'));
return $smarty->fetch(_PS_MODULE_DIR_ . '/pagecache/views/templates/admin/get-content-tab-datas_context.tpl');
}
private static function getNiceDuration($durationInSeconds) {
$duration = '';
if ($durationInSeconds < 0) {
$duration = '-';
}
else {
$days = floor($durationInSeconds / 86400);
$durationInSeconds -= $days * 86400;
$hours = floor($durationInSeconds / 3600);
$durationInSeconds -= $hours * 3600;
$minutes = floor($durationInSeconds / 60);
$seconds = $durationInSeconds - $minutes * 60;
if ($days > 0) {
$duration .= $days . ' days';
}
if ($hours > 0) {
$duration .= ' ' . $hours . ' hours';
}
if ($minutes > 0) {
$duration .= ' ' . $minutes . ' minutes';
}
if ($seconds > 0) {
$duration .= ' ' . $seconds . ' seconds';
}
}
return $duration;
}
/**
* Create the data output array for the DataTables rows
*
* @param array $columns Column information array
* @param array $data Data from the SQL get
* @return array Formatted data in a row based format
*/
private static function data_output($columns, $data)
{
$out = array();
for ($i = 0, $ien = count($data); $i < $ien; $i++) {
$row = array();
for ($j = 0, $jen = count($columns); $j < $jen; $j++) {
$column = $columns[$j];
// Is there a formatter?
if (isset($column['formatter'])) {
$row[$column['dt']] = $column['formatter']($data[$i][$column['db']], $data[$i]);
} else {
$row[$column['dt']] = $data[$i][$columns[$j]['db']];
}
}
$out[] = $row;
}
return $out;
}
/**
* Paging
*
* Construct the LIMIT clause for server-side processing SQL query
*
* @param array $request Data sent to server by DataTables
* @return string SQL limit clause
*/
private static function limit($request)
{
$limit = '';
if (isset($request['start']) && $request['length'] != -1) {
$limit = "LIMIT " . ((int)$request['start']) . ", " . ((int)$request['length']);
}
return $limit;
}
/**
* Ordering
*
* Construct the ORDER BY clause for server-side processing SQL query
*
* @param array $request Data sent to server by DataTables
* @param array $columns Column information array
* @return string SQL order by clause
*/
private static function order($request, $columns)
{
$order = '';
if (isset($request['order']) && count($request['order'])) {
$orderBy = array();
$dtColumns = self::pluck($columns, 'dt');
for ($i = 0, $ien = count($request['order']); $i < $ien; $i++) {
// Convert the column index into the column data property
$columnIdx = (int)($request['order'][$i]['column']);
$requestColumn = $request['columns'][$columnIdx];
$columnIdx = array_search($requestColumn['data'], $dtColumns);
$column = $columns[$columnIdx];
if ($requestColumn['orderable'] == 'true') {
$dir = $request['order'][$i]['dir'] === 'asc' ?
'ASC' :
'DESC';
if ($column['db']=='count_hit') {
// Special case
$orderBy[] = 'count_hit+count_missed ' . $dir;
}
else {
$orderBy[] = '`' . $column['db'] . '` ' . $dir;
}
}
}
if (count($orderBy)) {
$order = 'ORDER BY ' . implode(', ', $orderBy);
}
}
return $order;
}
/**
* Searching / Filtering
*
* Construct the WHERE clause for server-side processing SQL query.
*
* NOTE this does not match the built-in DataTables filtering which does it
* word by word on any field. It's possible to do here performance on large
* databases would be very poor
*
* @param array $request Data sent to server by DataTables
* @param array $columns Column information array
* @return string SQL where clause
*/
private static function filter ( $request, $columns )
{
$columnSearch = array();
$dtColumns = self::pluck( $columns, 'dt' );
// Individual column filtering
if ( isset( $request['columns'] ) ) {
for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) {
$requestColumn = $request['columns'][$i];
$columnIdx = array_search( $requestColumn['data'], $dtColumns );
$column = $columns[ $columnIdx ];
$str = $requestColumn['search']['value'];
if ( $requestColumn['searchable'] == 'true' && $str != '' ) {
if(!empty($column['db'])){
if ($column['db'] === 'url') {
$columnSearch[] = "`" . $column['db'] . "` LIKE '%" . $str . "%'";
}
else {
$columnSearch[] = "`" . $column['db'] . "` = '" . $str . "'";
}
}
}
}
}
// Combine the filters into a single string
$where = 'id_shop IN (' . implode(',', Shop::getContextListShopID()) . ')';
if ( count( $columnSearch ) ) {
$where = $where === '' ?
implode(' AND ', $columnSearch) :
$where .' AND '. implode(' AND ', $columnSearch);
}
if ( $where !== '' ) {
$where = 'WHERE '.$where;
}
return $where;
}
/**
* Perform the SQL queries needed for an server-side processing requested,
* utilising the helper functions of this class, limit(), order() and
* filter() among others. The returned array is ready to be encoded as JSON
* in response to an SSP request, or can be modified if needed before
* sending back to the client.
*
* @param array $request Data sent to server by DataTables
* @param string $table SQL table to query
* @param array $columns Column information array
* @return array Server-side processing response array
*/
private static function simple($request, $table, $columns)
{
// Build the SQL query string from the request
$limit = self::limit($request);
$order = self::order($request, $columns);
$where = self::filter( $request, $columns);
// Main query to actually get the data
try {
$data = JprestaUtils::dbSelectRows("SELECT `" . implode("`, `", self::pluck($columns, 'db')) . "`
FROM `$table`
$where
$order
$limit"
);
// Data set length after filtering
// Total data set length
$recordsFiltered = $recordsTotal = JprestaUtils::dbGetValue("SELECT COUNT(*) FROM `$table` $where");
} catch (Exception $e) {
die($e->getMessage());
}
/*
* Output
*/
return array(
"draw" => isset ($request['draw']) ? (int)$request['draw'] : 0,
"recordsTotal" => (int)$recordsTotal,
"recordsFiltered" => (int)$recordsFiltered,
"data" => self::data_output($columns, $data)
);
}
private static function simpleClear($request, $table, $columns)
{
// Build the SQL query string from the request
$where = self::filter($request, $columns);
// Main query to actually get the data
try {
$rows = JprestaUtils::dbSelectRows("SELECT * FROM `$table` as c $where AND deleted=0 LIMIT 1000");
PageCacheDAO::deleteCachedPages($rows, false);
} catch (Exception $e) {
die($e->getMessage());
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Internal methods
*/
/**
* Pull a particular property from each assoc. array in a numeric array,
* returning and array of the property values from each item.
*
* @param array $a Array to get data from
* @param string $prop Property to read
* @return array Array of property values
*/
private static function pluck($a, $prop)
{
$out = array();
for ($i = 0, $len = count($a); $i < $len; $i++) {
$out[] = $a[$i][$prop];
}
return $out;
}
}