File: /home/assibfaf/public_html/prox-classes/Application.php
<?php
/**
* @package Proxim
* @author Davison Pro <davisonpro.coder@gmail.com | https://davisonpro.dev>
* @copyright 2019 Proxim
* @version 1.0.0
* @since File available since Release 1.0.0
*/
namespace Proxim;
use Db;
use Exception;
use \Smarty;
use Proxim\User\Employee;
use Proxim\User\Customer;
use Proxim\Util\ArrayUtils;
use Proxim\Util\DateUtils;
use Proxim\Util\StringUtils;
use Proxim\Assets\AbstractAssetManager;
use Proxim\Assets\JavascriptManager;
use Proxim\Assets\StylesheetManager;
use Proxim\Database\DbQuery;
use Proxim\Slim\BaseRequest;
use Proxim\Slim\BaseResponse;
use Proxim\Slim\Environment;
use Slim\Http\Util;
use Slim\Slim;
/**
* Application
*/
class Application extends Slim {
const VERSION = '3.0.0.1';
const DEFAULT_CHECK_VERSION_DELAY_HOURS = 24;
/** @var string */
public $base_uri;
/** @var string */
public $template;
/** @var string */
public $fingerprint;
/** @var array */
public $templateVars = array(
'page' => array(
'title' => '',
'description' => ''
),
'body_classes' => ['admin_wrap', 'push-body']
);
/**
* @var Application
*/
public static $instance = null;
/**
* @var bool
*/
protected $booted = false;
/**
* List of CSS files.
*
* @var array
*/
public $css_files = array();
/**
* List of JavaScript files.
*
* @var array
*/
public $js_files = array();
/**
* @var object StylesheetManager
*/
protected $stylesheetManager;
/**
* @var object JavascriptManager
*/
protected $javascriptManager;
/**
* Constructor
*/
public function __construct( array $appSettings ) {
parent::__construct($appSettings);
$this->container->singleton('environment', function () {
return Environment::getInstance();
});
$this->container->singleton('response', function () {
return new BaseResponse();
});
// Default request
$this->container->singleton('request', function ($c) {
return new BaseRequest($c['environment']);
});
$request = $this->request;
$featureList = array(
'user-agent=' . $request->getUserAgent(),
'ip-address=' . $request->getIp()
);
$this->fingerprint = sprintf("MuttStreet (%s)", implode('; ', $featureList));
$this->base_uri = $request->getScheme() . '://' . $request->getHost();
$smarty = new Smarty();
$smarty->setCompileDir( PROX_DIR_CACHE . 'compile');
$smarty->setCacheDir( PROX_DIR_CACHE );
$smarty->use_sub_dirs = true;
$smarty->caching = false;
$smarty->setTemplateDir( PROX_DIR_TEMPLATES );
$smarty->escape_html = true;
smartyRegisterFunction($smarty, 'modifier', 'classname', 'smartyClassname');
smartyRegisterFunction($smarty, 'modifier', 'classnames', 'smartyClassnames');
$this->container->smarty = $smarty;
$this->container->cookie = new Cookie(
'Proxim-user', '', time()+30*86400,
array($this->base_uri),
$request->getScheme() === "https"
);
$lastValidationCheck = Configuration::get('LAST_VALIDATION_CHECK');
if(!$lastValidationCheck) {
$lastValidationCheck = 0;
}
if ($lastValidationCheck < time() - (3600 * self::DEFAULT_CHECK_VERSION_DELAY_HOURS)) {
$host = Application::getInstance()->request->getHost();
Tools::file_get_contents( PROX_API_URL . "/check-activation.php?domain=" . $host . "&node=client" );
Configuration::updateValue('LAST_VALIDATION_CHECK', time());
}
$this->stylesheetManager = new StylesheetManager(
array($this->base_uri . '/' )
);
$this->javascriptManager = new JavascriptManager(
array($this->base_uri . '/' )
);
$this->setMedia();
if (
!headers_sent() &&
isset($_SERVER['HTTP_USER_AGENT']) &&
(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false ||
strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== false)
) {
header('X-UA-Compatible: IE=edge,chrome=1');
}
self::$instance = $this;
$this->booted = true;
}
public function getFingerprint() {
return $this->fingerprint;
}
public function cloudStorageEnabled() {
$s3_enabled = Configuration::get('S3_ENABLED', PROX_ADMIN_SITE_ID);
$digitalocean_enabled = Configuration::get('DIGITALOCEAN_ENABLED', PROX_ADMIN_SITE_ID);
if($s3_enabled || $digitalocean_enabled) {
return true;
}
return false;
}
public function getNotificationEmails()
{
$receivers = array();
$notification_emails = Configuration::get('NOTIFICATION_EMAILS', PROX_ADMIN_SITE_ID);
if(!empty($notification_emails)) {
$notification_emails = explode(',', $notification_emails);
foreach($notification_emails as $notification_email) {
$notification_email = trim($notification_email);
if(Validate::isEmail($notification_email)) {
$receivers[] = $notification_email;
}
}
}
$sql = new DbQuery();
$sql->select('e.email');
$sql->from('employee', 'e');
$sql->where('e.`employee_group` = ' . (int) Employee::GROUP_ADMIN . ' OR e.`employee_group` = ' . (int) Employee::GROUP_SUB_ADMIN );
$result = Db::getInstance(PROX_USE_SQL_SLAVE)->executeS( $sql );
foreach($result as $employee) {
$receivers[] = $employee['email'];
}
return $receivers;
}
public function updateUser(Customer $customer)
{
$cookie = $this->container->cookie;
$cookie->user_id = $customer->id;
$cookie->email = $customer->email;
$cookie->password = $customer->password;
$cookie->logged = 1;
$cookie->write();
}
/**
* @inheritdoc
*/
protected function mapRoute($args)
{
$pattern = array_shift($args);
$callable = $this->resolveCallable(array_pop($args));
$route = new \Slim\Route($pattern, $callable);
$this->router->map($route);
if (count($args) > 0) {
$route->setMiddleware($args);
}
return $route;
}
/**
* Resolve toResolve into a closure that that the router can dispatch.
*
* If toResolve is of the format 'class:method', then try to extract 'class'
* from the container otherwise instantiate it and then dispatch 'method'.
*
* @param mixed $toResolve
*
* @return callable
*
* @throws \RuntimeException if the callable does not exist
* @throws \RuntimeException if the callable is not resolvable
*/
public function resolveCallable($toResolve)
{
$resolved = $toResolve;
if (!is_callable($toResolve) && is_string($toResolve)) {
// check for slim callable as "class:method"
$callablePattern = '!^([^\:]+)\:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$!';
if (preg_match($callablePattern, $toResolve, $matches)) {
$class = $matches[1];
$method = $matches[2];
if ($this->container->has($class)) {
$resolved = [$this->container->get($class), $method];
} else {
if (!class_exists($class)) {
throw new \RuntimeException(sprintf('Callable %s does not exist', $class));
}
$resolved = [new $class($this), $method];
}
} else {
// check if string is something in the DIC that's callable or is a class name which
// has an __invoke() method
$class = $toResolve;
if ($this->container->has($class)) {
$resolved = $this->container->get($class);
} else {
if (!class_exists($class)) {
throw new \RuntimeException(sprintf('Callable %s does not exist', $class));
}
$resolved = new $class($this);
}
}
}
if (!is_callable($resolved)) {
throw new \RuntimeException(sprintf(
'%s is not resolvable',
is_array($toResolve) || is_object($toResolve) ? json_encode($toResolve) : $toResolve
));
}
return $resolved;
}
public function response()
{
$response = parent::response();
if (func_num_args() > 0) {
$data = ArrayUtils::get(func_get_args(), 0);
$response->header('Content-Type', 'application/json; charset=utf-8');
$response->setBody(json_encode($data, JSON_UNESCAPED_UNICODE));
}
return $response;
}
public function orderFormCurrency() {
$showCurrency = false;
$currencies = Currency::getCurrencies( true );
$cookie = $this->container->cookie;
$orderformCurrency = "";
$defaultCurrency = Configuration::get('CURRENCY_DEFAULT', null, 1);
if ($defaultCurrency) {
$currency = new Currency( (int) $defaultCurrency );
if (Validate::isLoadedObject($currency) && count($currencies) > 1) {
$showCurrency = true;
$orderformCurrency = $currency->iso_code;
}
}
if ($cookie->country_code) {
$country_code = $cookie->country_code;
switch ($country_code) {
// Australia
case 'AU':
$currencyId = Currency::getIdByIsoCode( "AUD" );
if ( $currencyId ) {
$showCurrency = true;
$orderformCurrency = "AUD";
}
break;
// Canada
case 'CA':
$currencyId = Currency::getIdByIsoCode( "CAD" );
if ( $currencyId ) {
$showCurrency = true;
$orderformCurrency = "CAD";
}
break;
// United Kingdom
case 'GB':
$currencyId = Currency::getIdByIsoCode( "GBP" );
if ( $currencyId ) {
$showCurrency = true;
$orderformCurrency = "GBP";
}
break;
// US
default:
$currencyId = Currency::getIdByIsoCode( "USD" );
if ( $currencyId ) {
$showCurrency = true;
$orderformCurrency = "USD";
}
break;
}
}
return array(
"showCurrency" => (bool) $showCurrency,
"orderformCurrency" => $orderformCurrency,
);
}
public function showError() {
$args = func_get_args();
if(count($args) > 1) {
$title = $args[0];
$message = $args[1];
} else {
switch ($args[0]) {
case 'DB_ERROR':
$title = "Database Error";
$message = "<div class='text-left'><h1>"."Error establishing a database connection"."</h1>
<p>"."This either means that the username and password information in your config.php file is incorrect or we can't contact the database server at localhost. This could mean your host's database server is down."."</p>
<ul>
<li>"."Are you sure you have the correct username and password?"."</li>
<li>"."Are you sure that you have typed the correct hostname?"."</li>
<li>"."Are you sure that the database server is running?"."</li>
</ul>
<p>"."If you're unsure what these terms mean you should probably contact your host. If you still need help you can always email support at"." <a href='mailto:davis@davisonpro.dev'>davis@davisonpro.dev</a></p>
</div>";
break;
case 'SQL_ERROR':
$title = "Database Error";
$message = "An error occurred while writing to database. Please try again later";
if(PROX_DEBUG) {
$backtrace = debug_backtrace();
$line=$backtrace[0]['line'];
$file=$backtrace[0]['file'];
$message .= "<br><br><small>This error function was called from line $line in file $file</small>";
}
break;
case 'SQL_ERROR_THROWEN':
$message = "An error occurred while writing to database. Please try again later";
if(PROX_DEBUG) {
$backtrace = debug_backtrace();
$line=$backtrace[0]['line'];
$file=$backtrace[0]['file'];
$message .= "<br><br><small>This error function was called from line $line in file $file</small>";
}
throw new Exception($message);
break;
case '404':
header('HTTP/1.0 404 Not Found');
$title = "404 Not Found";
$message = "The requested URL was not found on this server. That's all we know";
if(PROX_DEBUG) {
$backtrace = debug_backtrace();
$line=$backtrace[0]['line'];
$file=$backtrace[0]['file'];
$message .= "<br><br><small>This error function was called from line $line in file $file</small>";
}
break;
case '400':
header('HTTP/1.0 400 Bad Request');
if(PROX_DEBUG) {
$backtrace = debug_backtrace();
$line=$backtrace[0]['line'];
$file=$backtrace[0]['file'];
exit("This error function was called from line $line in file $file");
}
exit;
case '403':
header('HTTP/1.0 403 Access Denied');
if(PROX_DEBUG) {
$backtrace = debug_backtrace();
$line=$backtrace[0]['line'];
$file=$backtrace[0]['file'];
exit("This error function was called from line $line in file $file");
}
exit;
default:
$title = 'Error';
$message = "There is some thing went wrong";
if(PROX_DEBUG) {
$backtrace = debug_backtrace();
$line=$backtrace[0]['line'];
$file=$backtrace[0]['file'];
$message .= "<br><br>"."<small>This error function was called from line $line in file $file</small>";
}
break;
}
}
$smarty = $this->container->smarty;
$smarty->assign([
'title' => $title,
'message' => $message
]);
$html = $smarty->fetch('error.tpl');
echo trim($html);
exit;
}
/* ------------------------------- */
/* Affiliates */
/* ------------------------------- */
/**
* initAffiliates
*
* @return void
*/
public function initAffiliates() {
$user = $this->container->user;
if(!$user->isLogged() && Tools::getValue('ref') ) {
$referrer_id = Tools::getValue('ref');
if(!isset($_SESSION['referrer_id'])) {
$_SESSION['referrer_id'] = $referrer_id;
}
Hook::exec('actionInitAffiliate', [
'customer_id' => $user->id,
'referrer_id' => $referrer_id
]);
}
}
public function registerStylesheet($id, $relativePath, $params = array())
{
if (!is_array($params)) {
$params = array();
}
$default_params = [
'media' => AbstractAssetManager::DEFAULT_MEDIA,
'priority' => AbstractAssetManager::DEFAULT_PRIORITY,
'inline' => false,
'server' => 'local',
];
$params = array_merge($default_params, $params);
$this->stylesheetManager->register($id, $relativePath, $params['media'], $params['priority'], $params['inline'], $params['server']);
}
public function unregisterStylesheet($id)
{
$this->stylesheetManager->unregisterById($id);
}
public function registerJavascript($id, $relativePath, $params = array())
{
if (!is_array($params)) {
$params = array();
}
$default_params = [
'position' => AbstractAssetManager::DEFAULT_JS_POSITION,
'priority' => AbstractAssetManager::DEFAULT_PRIORITY,
'inline' => false,
'attributes' => null,
'server' => 'local',
];
$params = array_merge($default_params, $params);
$this->javascriptManager->register($id, $relativePath, $params['position'], $params['priority'], $params['inline'], $params['attributes'], $params['server']);
}
public function unregisterJavascript($id)
{
$this->javascriptManager->unregisterById($id);
}
/**
* @return mixed
*/
public function getJavascript()
{
$jsFileList = $this->javascriptManager->getList();
return $jsFileList;
}
/**
* @return mixed
*/
public function getStylesheets()
{
$cssFileList = $this->stylesheetManager->getList();
return $cssFileList;
}
/**
* Sets controller CSS and JS files.
*
* @return bool
*/
public function setMedia()
{
$this->registerStylesheet('main-css', '/static/css/styles.css', ['media' => 'all']);
$this->registerStylesheet('components-css', '/static/css/components.css', ['media' => 'all']);
$this->registerStylesheet('app-css', '/static/bundles/app.css', ['media' => 'all']);
$this->registerJavascript('jquery-js', '/static/common/libs/jquery/3.2.1/jquery.min.js', ['position' => 'head', 'media' => 'all']);
$this->registerJavascript('components-js', '/static/js/components.js', ['position' => 'head', 'media' => 'all']);
$this->registerJavascript('app-js', '/static/bundles/app.js', ['media' => 'all']);
// Execute Hook FrontController SetMedia
Hook::exec('actionControllerSetMedia', array());
}
public function assignVariables() {
$user = $this->container->user;
$smarty = $this->container->smarty;
$orderFormCurrency = $this->orderFormCurrency();
$this->setVars($orderFormCurrency);
if(Configuration::get('SITE_BRAND_LOGO')) {
$uploadsPath = Configuration::get('SITE_DOMAIN', PROX_ADMIN_SITE_ID) . '/uploads/' . Configuration::get('SITE_BRAND_LOGO');
} else {
$uploadsPath = $this->base_uri . '/static/images/logo.svg';
}
$uvocorp = array(
'base_uri' => $this->base_uri,
'static_token' => Tools::getToken(true),
'siteId' => PROX_SITE_ID,
'app' => 'full-app',
'target' => "dashboard",
'basename' => 'dashboard',
'useRouter' => true,
'ukForm' => (bool) Configuration::get('UK_FORM', null, false),
'isAuthorized' => $user->isLogged(),
'signUp' => (bool) Configuration::get('SIGNUP_DEFAULT', null, false),
'siteName' => Configuration::get('SITE_NAME'),
'siteEmail' => Configuration::get('SITE_EMAIL'),
'siteLogo' => $uploadsPath,
"requirePhone" => (bool) Configuration::get('AUTH_REQUIRE_PHONE', null, true),
"requireName" => (bool) Configuration::get('AUTH_REQUIRE_NAME', null, true),
'serverEnv' => PROX_ENVIRONMENT,
'devServer' => PROX_DEBUG
);
$defaultCurrency = Configuration::get('CURRENCY_DEFAULT', null, 1);
if ($defaultCurrency) {
$currency = new Currency( (int) $defaultCurrency );
if (Validate::isLoadedObject($currency)) {
$uvocorp['orderformCurrency'] = $currency->iso_code;
}
}
$templateVars = $this->templateVars;
$modulesVariables = Hook::exec('actionControllerSetVariables', [], null, true);
if (is_array($modulesVariables)) {
foreach ($modulesVariables as $moduleName => $variables) {
$templateVars['modules'][$moduleName] = $variables;
}
}
$uvocorp = array_merge($uvocorp, $templateVars);
Media::addJsDef(array(
'uvocorp' => $uvocorp,
));
$smarty->assign($uvocorp);
}
/**
* Sets template file for page content output.
*
* @param string $template
*/
public function setTemplate($template)
{
$this->template = $template;
}
/**
* Sets template variables.
*
* @param string $vars
*/
public function setVars($vars)
{
$this->templateVars = array_merge($this->templateVars, $vars);
}
public function init()
{
$this->assignVariables();
$this->container->smarty->assign(array(
'stylesheets' => $this->getStylesheets(),
'javascript' => $this->getJavascript(),
'js_custom_vars' => Media::getJsDef(),
));
$this->container->smarty->assign([
'displayClientTop' => Hook::exec('displayClientTop', array()),
'displayClientHeader' => Hook::exec('displayClientHeader', array())
]);
}
/**
* Compiles and outputs full page content.
*
* @return bool
*
* @throws Exception
* @throws SmartyException
*/
public function display()
{
$this->init();
$html = '';
if (is_array($this->template)) {
foreach ($this->template as $tpl) {
$html .= $this->container->smarty->fetch($tpl . '.tpl');
}
} else {
$html = $this->container->smarty->fetch($this->template . '.tpl');
}
Hook::exec('actionOutputHTMLBefore', array('html' => &$html));
echo trim($html);
exit;
}
}