pos/is4c-nf/lib/AjaxCallback.php
<?php
/*******************************************************************************
Copyright 2015 Whole Foods Co-op
This file is part of IT CORE.
IT CORE is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
IT CORE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
in the file license.txt along with IT CORE; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************************/
namespace COREPOS\pos\lib;
use COREPOS\pos\lib\LaneLogger;
use COREPOS\pos\lib\LocalStorage\WrappedStorage;
use \AutoLoader;
use \ReflectionClass;
use COREPOS\common\mvc\FormValueContainer;
/**
@class AjaxCallback
*/
class AjaxCallback
{
protected $encoding = 'json';
protected static $logger;
protected $session;
protected $form;
public function __construct($session, $form)
{
$this->session = $session;
$this->form = $form;
}
public function getEncoding()
{
return $this->encoding;
}
public function ajax()
{
}
// @hintable
public static function unitTest($class)
{
self::executeCallback($class);
}
public static function run()
{
register_shutdown_function(array('COREPOS\\pos\\lib\\AjaxCallback', 'ajaxFatal'));
$callback_class = get_called_class();
$file = filter_input(INPUT_SERVER, 'SCRIPT_FILENAME');
// nb. if FastCGI is in use, the above may return null, in
// which case we must provide a fallback
if (!$file) {
$file = $_SERVER['SCRIPT_FILENAME'];
}
$nsClass = AutoLoader::fileToFullClass($file);
self::$logger = new LaneLogger();
if ($callback_class === $nsClass || basename($file) === $callback_class . '.php') {
ini_set('display_errors', 'off');
/**
timing calls is off by default. uncomment start
and end calls to collect data
*/
self::perfStart();
self::executeCallback($callback_class);
self::perfEnd($callback_class);
} else {
self::$logger->error("$callback_class is not correct for the file $file");
}
}
// @hintable
private static function executeCallback($callback_class)
{
$obj = new $callback_class(new WrappedStorage(), new FormValueContainer());
ob_start();
$output = $obj->ajax();
$extra_output = ob_get_clean();
if (strlen($extra_output) > 0) {
self::$logger->debug("Extra AJAX output: {$extra_output}");
}
switch ($obj->getEncoding()) {
case 'json':
echo json_encode($output);
break;
case 'plain':
default:
echo $output;
break;
}
}
protected static $elapsed = null;
protected static function perfStart()
{
self::$elapsed = microtime(true);
}
protected static function perfEnd($callback_class)
{
/**
* Some AJAX handlers might close the current session in
* which case we can't record a performance figure
*/
if (substr($callback_class, -13) != 'AjaxPollScale' && session_status() == PHP_SESSION_ACTIVE) {
$timer = sprintf('%.4f', microtime(true) - self::$elapsed);
$session = new WrappedStorage();
$perf = $session->get('perfLog');
if (!is_array($perf)) {
$perf = array();
}
if (count($perf) > 10) {
array_shift($perf);
}
$form = new FormValueContainer();
$input = $form->tryGet('input', false);
if ($input === false) {
$input = $form->tryGet('reginput');
}
array_push($perf, array('action'=>$callback_class, 'time'=>$timer, 'input'=>$input));
$session->set('perfLog', $perf);
}
}
/**
Output valid JSON when a fatal error occurs. Logging
is handled by COREPOS\common\ErrorHandler. This response
lets calling javascript code notify the user that something
went wrong.
*/
public static function ajaxFatal()
{
$error = error_get_last();
if ($error != null) {
if ($error["type"] == E_ERROR
|| $error['type'] == E_PARSE
|| $error['type'] == E_CORE_ERROR
|| $error['type'] == E_COMPILE_ERROR) {
$msg = "{$error['message']} ({$error['file']} line {$error['line']})";
$json = array('error' => $msg);
echo json_encode($json);
}
}
}
}