<?php
/**
* Class View
* Provides functionality for managing templates, layouts, and breadcrumb navigation.
* Integrates with the Twig templating engine.
*/
namespace TULGAR\Core;
use App\Helpers\Notification;
use App\Model\T601_LANG;
use App\Model\T800_NOTIFICATIONS;
use /**
* Represents a custom Exception specific to the application.
*
* This Exception can be used to handle errors related to specific
* domain logic or conditions within the application. It extends
* the base Exception class, so it inherits all standard Exception
* functionality while allowing customization for unique error cases.
*/
Exception;
use Mavera\Auth;
use /**
* The Mavera\Menu class is used to represent and manage menu structures
* within the application. It provides functionalities to create, manipulate,
* and retrieve menu-related data.
*
* This class allows building hierarchical menus, managing menu items, and
* performing relevant operations for dynamic or static menu structures.
*
* @package Mavera
*/
Mavera\Menu;
use /**
* The Mavera\Globals class provides a mechanism to manage global variables in a structured way.
* It allows setting, retrieving, and checking the existence of global data.
*
* This class provides utility methods to handle globally scoped data in a controlled manner
* to avoid polluting the global namespace.
*
* Methods in this class are designed to simplify access to application-wide state
* or shared data without directly using PHP's global variables.
*/
Mavera\Globals;
use /**
* Class Language
*
* Represents a utility class for handling multiple languages and localization-related functionality.
* This class may include methods for translating text, formatting, and managing language-specific settings.
*
* It is a part of the Mavera namespace and is designed to facilitate language-specific behaviors across
* different parts of an application.
*/
Mavera\Language;
use Mavera\ORM;
use /**
* The Router class is responsible for handling and managing the routing of
* HTTP requests in the application. It maps URI patterns to specific
* callback functions or controller methods and facilitates the forwarding
* of requests based on their defined routes.
*
* It supports various HTTP methods (e.g., GET, POST, PUT, DELETE) and provides
* functionalities to add new routes, define route middleware, and execute the
* appropriate logic for incoming requests.
*
* This class is an essential part of the application's request/response lifecycle,
* helping to determine what action should be taken based on the requested URI.
*/
Mavera\Router;
use Mavera\Session;
use /**
* TULGAR\Addons\Framework
*
* This class provides a framework for managing addons within the TULGAR system.
* It is responsible for handling the registration, initialization, activation,
* deactivation, and lifecycle operations of addons.
*
* The Framework class serves as the base for defining and managing specific
* functionalities or additional capabilities implemented as addons. Addons can
* extend this class and utilize its features to integrate with the broader system.
*
* Key responsibilities include:
* - Providing a structure for addon creation.
* - Allowing addons to register custom hooks or filters.
* - Managing the loading and unloading of addons dynamically.
* - Ensuring lifecycle integrity and compatibility checks during activation or deactivation.
*
* It is expected that subclasses will override specific methods to perform
* behavior particular to their function or application. The base class handles
* the foundational interactions to simplify addon development and maintenance.
*/
TULGAR\Addons\Framework;
use /**
* Represents the Twig template rendering environment.
*
* Twig\Environment, aliased as TwigEnv, is the central class in Twig templating.
* This environment is responsible for managing everything related to templates,
* including loading, rendering, caching, and handling global functions or filters.
*
* TwigEnv supports custom extensions, functions, and filters, helping to extend
* the default functionality of the templating engine. It is highly extensible and
* efficient, commonly used for rendering output in various content-driven and
* dynamic applications.
*/
Twig\Environment as TwigEnv;
use /**
* Exception class that is thrown when a template cannot be loaded.
*
* Twig\Error\LoaderError is part of the Twig template engine and is used
* to indicate an issue related to locating or loading a template file.
*
* Typical causes of this error include unavailable or non-existent
* template files, incorrect template paths, or issues related to the
* registered template loader.
*
* This exception allows developers to debug and diagnose template
* loading issues within the Twig environment.
*
* It extends the built-in Twig\Error\Error class, which serves as
* the base class for all Twig-related exceptions.
*/
Twig\Error\LoaderError;
use /**
* Class RuntimeError
*
* Represents an error that occurs during the execution of a Twig template.
* Runtime errors are typically caused by issues such as incorrect usage
* of template tags, filters, functions, or runtime exceptions thrown by
* the application logic while rendering the template.
*
* This exception extends the base Twig error hierarchy, making it easier
* to handle template errors specifically within an application.
*
* Extends:
* - Twig\Error\Error
*
* Common scenarios in which this error might occur include:
* - Failed variable or method access due to null or undefined values.
* - Invalid arguments passed to custom filters or functions.
* - Uncaught exceptions from application logic used inside the template.
*/
Twig\Error\RuntimeError;
use /**
* Class SyntaxError
*
* Represents a syntax error in a Twig template.
* It is thrown when there is an issue with the structure
* or parsing of Twig template code. This exception typically
* occurs during compiling templates or processing expressions
* if invalid syntax is detected.
*
* The error provides contextual information such as the
* problematic line number and the template name to aid
* in debugging.
*
* Methods of this class allow for retrieving detailed information
* about the errors for better troubleshooting and to improve the
* visibility of what caused the issue in a given template.
*/
Twig\Error\SyntaxError;
use /**
* The FilesystemLoader class from the Twig library is responsible for loading
* template files from the filesystem. It provides methods to locate and retrieve
* template files based on a given template name and configured path(s).
*
* This loader is commonly used to integrate Twig templates in applications
* where templates are stored on disk.
*
* Use this loader to specify the directory or directories where Twig should look
* for template files when rendering views.
*/
Twig\Loader\FilesystemLoader as TwigLoader;
use /**
* Creates a new TwigFunction instance.
*
* A TwigFunction is used to define a custom function in a Twig template.
* These functions can be called directly within the template for additional
* functionality that may not be covered by Twig's built-in functions.
*
* @param string $name The name of the function that will be used in the template.
* @param callable|null $callable A valid PHP callable that will be executed when the function is invoked.
* @param array $options Optional options for the function:
* - 'needs_environment' (bool): If true, the calling Twig environment will be passed as the first argument.
* - 'needs_context' (bool): If true, the calling context will be passed as the second argument.
* - 'is_variadic' (bool): If true, allows additional arguments to be passed to the function.
* - 'deprecated' (string|true): Marks the function as deprecated with an optional deprecation message.
* - 'alternative' (string): Specifies an alternative function to use if the function is deprecated.
*/
Twig\TwigFunction;
use function App\Helpers\createSymbol;
use function App\Helpers\money;
/**
* Class View
*
* This class is responsible for managing the rendering of templates using the Twig template engine.
* It provides methods to configure the rendering engine and set up layout and breadcrumb data for templates.
*/
class View
{
static TwigLoader $loader;
static TwigEnv $twig;
private static array $BreadCrumbArray = [];
private static string $BreadcrumbTitle = "";
private static string $layout = 'Main';
private static string $layout_prefix = '';
/**
* @param TwigLoader $loader
* @return no-return
* @throws Exception
*/
public static function SetEngine(TwigLoader $loader): void
{
self::$loader = $loader;
self::$twig = new TwigEnv(self::$loader, [
#'cache' => VIEW_BASE . "/Cache"
]);
self::$layout = "Metronic9/Main";
self::$twig->addFunction(new TwigFunction('asset', function ($path, $site = true) {
if ($site) {
$asset_route = '';
switch (explode('/', self::$layout)[0]) {
case 'Metronic8':
$asset_route = 'admin/';
break;
}
return ASSETS . $asset_route . $path;
} else {
return $path;
}
}));
self::$twig->addFunction(new TwigFunction('jsFileExists', function ($file) {
return (bool)Framework::File_Control(BASE . "Storage/Public/" . Router::$URL . "/js/custom-pages/" . $file . ".js");
}));
self::$twig->addFunction(new TwigFunction('createSymbol', function ($name, $max = 2) {
return createSymbol($name, $max);
}));
self::$twig->addFunction(new TwigFunction('url', function ($url, $site = true) {
return SITE_URL . ($site ? (strtolower(Router::$URL) == 'admin' ? strtolower(Router::$URL) . '/' : '') : '') . $url;
}));
self::$twig->addFunction(new TwigFunction('urlNotify', function ($url) {
return SITE_URL . $url;
}));
self::$twig->addFunction(new TwigFunction('route', function () {
return Router::$URL;
}));
self::$twig->addFunction(new \Twig\TwigFunction('uqPretty', function ($uq, $first = 8, $last = 4) {
return substr($uq, 0, $first) . '...' . substr($uq, strlen($uq) - $last);
}));
self::$twig->addFilter(new \Twig\TwigFilter('truncateClean', function ($text, $length = 150, $append = '...') {
$cleanText = html_entity_decode(strip_tags($text ?? ''), ENT_QUOTES | ENT_HTML5, 'UTF-8');
if (mb_strlen($cleanText, 'UTF-8') > $length) {
return mb_substr($cleanText, 0, $length, 'UTF-8') . $append;
}
return $cleanText;
}));
self::$twig->addFunction(new TwigFunction('langText', function ($keys = '', array $replaces = []) {
return sprintf(Language::Keys($keys), ...$replaces);
}));
self::$twig->addFunction(new TwigFunction('text', function ($text = '', array $replaces = []) {
return Language::Text($text);
}));
self::$twig->addFunction(new TwigFunction('money', function ($money, $max = 2) {
return money($money, $max);
}));
self::$twig->addFunction(new TwigFunction('toWords', function ($number) {
return \App\Helpers\NumberHelper::toTurkishWords($number);
}));
}
/**
* @param $title
* @return void
*/
static function SetBreadcrumbTitle($title): void
{
self::$BreadcrumbTitle = $title;
}
/**
* @param $array
* @return void
*/
static function SetBreadcrumbArray($array): void
{
self::$BreadCrumbArray = $array;
}
static function SetLayout($layout): void
{
self::$layout = $layout;
}
/**
* Render the template file. (Twig)
*
* @param $file
* @param array $data
* @param null $layout
* @return boolean
* @throws LoaderError
* @throws RuntimeError
* @throws SyntaxError
*/
static function Render($file, array $data = array(), $layout = null): bool
{
if (strtolower(Router::$URL) == "admin") {
$academyMode = isset($_COOKIE['cst_admin_mode']) && $_COOKIE['cst_admin_mode'] === 'academy';
$userUq = \Mavera\Auth::User('T100_UQ');
$isFullAdmin = \App\Model\T101_ADMINS::Fetch(\Mavera\ORM::Build(\Mavera\ORM::Equal('T101_User_UQ', $userUq)));
$isAcademyAdmin = !$isFullAdmin;
self::$twig->addGlobal('academy_mode', $academyMode);
self::$twig->addGlobal('is_academy_admin', $isAcademyAdmin);
self::$twig->addGlobal('sidemenu', Menu::Get());
self::$twig->addGlobal("breadcrumb_title", self::$BreadcrumbTitle);
self::$twig->addGlobal("breadcrumb_array", self::$BreadCrumbArray);
}
if (Auth::IsLoggedIn()) {
self::$twig->addGlobal('user', Auth::GetUser());
$tmpNotify = Notification::GetNotifications(Auth::User('T100_UQ'));
$totalUnread = 0;
/**
* @var T800_NOTIFICATIONS $value
*/
foreach ($tmpNotify as $key => $value) {
if ($value->T800_Viewed == 0) {
$totalUnread++;
}
}
self::$twig->addGlobal('totalUnread', $totalUnread);
self::$twig->addGlobal('_notifications', $tmpNotify);
self::$twig->addGlobal('_notificationsUnread', $totalUnread);
$languages = T601_LANG::FetchAll();
self::$twig->addGlobal('languages', $languages);
$lng = T601_LANG::Fetch(ORM::Build(ORM::And(
ORM::Equal('T601_Key', Auth::User('T100_Language'))
)));
self::$twig->addGlobal('__lng', $lng);
}
self::$twig->addGlobal("pageTitle", isset($data["title"]) ? ($data["title"] . " - " . Globals::Get("TITLE")) : Globals::Get("TITLE"));
self::$twig->addGlobal("globals", Globals::Get_All());
$template = self::$twig->load("Pages/" . $file . ".twig");
if (strtolower(Router::$URL) == "admin") {
self::SetLayout('Metronic8/Main');
}
if ($layout !== null) {
self::SetLayout($layout);
}
$data['layout'] = self::$twig->load('Layouts/' . self::$layout_prefix . '/' . self::$layout . '.twig');
$data['___layout'] = self::$layout_prefix;
$data['pageName'] = $file;
$data['csrf_code'] =Session::get('csrf');
echo $template->render($data);
return true;
}
}