Exception:Array
(
[message] => call_user_func(): Argument #1 ($callback) must be a valid callback, cannot access protected method Vvveb\Controller\Content\Category::language()
[file] => /home/www/vvveb/www/system/core/frontcontroller.php
[line_no] => 222
[line] => $template = call_user_func([$controller, $actionName]); // <==
[lines] => Array
(
[0] => }
[1] =>
[2] => $controller->view->template($template . '.html'); //default html that can be overwritten
[3] =>
[4] => //list($template) = Event :: trigger($controllerClass, "$actionName:before", $template);
[5] =>
[6] => //$controller->view->template($template . '.html'); //default html
[7] => $template = call_user_func([$controller, $actionName]); // <==
[8] =>
[9] => list($template, $controller, $actionName) = Event::trigger(__CLASS__, __FUNCTION__, $template, $controller, $actionName);
[10] => $responseType = $response->getType();
[11] => $controller->view->setType($responseType);
[12] =>
[13] => if ($template === false) {
)
[trace] => #0 /home/www/vvveb/www/system/core/frontcontroller.php(223): call_user_func()
#1 /home/www/vvveb/www/system/core/frontcontroller.php(295): Vvveb\System\Core\FrontController::call()
#2 /home/www/vvveb/www/system/core/frontcontroller.php(368): Vvveb\System\Core\FrontController::redirect()
#3 /home/www/vvveb/www/system/core/startup.php(415): Vvveb\System\Core\FrontController::dispatch()
#4 /home/www/vvveb/www/index.php(102): Vvveb\System\Core\start()
#5 /home/www/vvveb/www/index.php(146): Vvveb\saveCache()
#6 /home/www/vvveb/www/public/index.php(28): include('...')
#7 {main}
[code] => Array
(
[0] =>
[2] => /**
[3] => * Vvveb
[4] => *
[5] => * Copyright (C) 2022 Ziadin Givan
[6] => *
[7] => * This program is free software: you can redistribute it and/or modify
[8] => * it under the terms of the GNU Affero General Public License as
[9] => * published by the Free Software Foundation, either version 3 of the
[10] => * License, or (at your option) any later version.
[11] => *
[12] => * This program is distributed in the hope that it will be useful,
[13] => * but WITHOUT ANY WARRANTY; without even the implied warranty of
[14] => * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
[15] => * GNU Affero General Public License for more details.
[16] => *
[17] => * You should have received a copy of the GNU Affero General Public License
[18] => * along with this program. If not, see .
[19] => *
[20] => */
[21] =>
[22] => namespace Vvveb\System\Core;
[23] =>
[24] => use function Vvveb\__;
[25] => use Vvveb\System\Event;
[26] => use Vvveb\System\PageCache;
[27] => use Vvveb\System\Routes;
[28] => use Vvveb\System\Session;
[29] =>
[30] => #[\AllowDynamicProperties]
[31] => class FrontController {
[32] => /**
[33] => * Standard Controller constructor.
[34] => */
[35] => static private $moduleName;
[36] =>
[37] => static private $actionName;
[38] =>
[39] => static private $status = 200;
[40] =>
[41] => /**
[42] => * Returns current controller name.
[43] => *
[44] => * @return string
[45] => */
[46] => static function getModuleName() {
[47] => return self :: $moduleName;
[48] => }
[49] =>
[50] => /**
[51] => * Returns current controller name.
[52] => *
[53] => * @return string
[54] => */
[55] => static function getActionName() {
[56] => return self :: $actionName;
[57] => }
[58] =>
[59] => /**
[60] => * Returns current status.
[61] => *
[62] => * @return string
[63] => */
[64] => static function getStatus() {
[65] => return self :: $status;
[66] => }
[67] =>
[68] => static function setStatus($status) {
[69] => return self :: $status = $status;
[70] => }
[71] =>
[72] => static private function callAction($controller, $action = 'index') {
[73] => if ($statusCode !== 200) {
[74] => header(' ', true, $statusCode);
[75] => }
[76] =>
[77] => if (include_once DIR_APP . DS . 'controller' . DS . "$controller.php") {
[78] => $controller = 'Vvveb\Controller\\' . $controller;
[79] => self :: $moduleName = $moduleName = $controller;
[80] => $controller = 'Vvveb\Controller\\' . $controller;
[81] => }
[82] => }
[83] =>
[84] => static function notFound($service = false, $message = false, $statusCode = 404) {
[85] => self :: $status = $statusCode;
[86] =>
[87] => $file = DIR_APP . DS . 'controller' . DS . "error$statusCode.php";
[88] => if (file_exists($file)) {
[89] => $controller = 'Vvveb\Controller\Error' . $statusCode;
[90] => self :: $moduleName = $moduleName = 'error' . $statusCode;
[91] => $controller = 'Vvveb\Controller\Error' . $statusCode;
[92] => //http_response_code($statusCode);
[93] => $view = View::getInstance();
[94] => if (is_array($message)) {
[95] => $view->set($message);
[96] => } else {
[97] => $view->message = $message;
[98] => }
[99] => self :: call($controller, 'index', $file);
[100] => PageCache::getInstance()->cleanUp();
[101] => die();
[102] => return;
[103] => } else {
[104] => //header(' ', true, $statusCode);
[105] => PageCache::getInstance()->cleanUp();
[106] =>
[107] => http_response_code($statusCode);
[108] => die("Http error $statusCode");
[109] => }
[110] => }
[111] =>
[112] => static function closeConnections() {
[113] => if (function_exists('fastcgi_finish_request')) {
[114] => //fastcgi_finish_request();
[115] => }
[116] => /*
[117] => if (defined('DB_ENGINE') && ($instance = \Vvveb\System\Db::getInstance())) {
[118] => $instance->close();
[119] => }*/
[120] => }
[121] =>
[122] => /**
[123] => * Inject dependencies.
[124] => *
[125] => * @param string $controller
[126] => */
[127] => static function di(&$controller) {
[128] => $controller->request = Request::getInstance();
[129] => $controller->response = Response::getInstance();
[130] => $controller->view = View::getInstance();
[131] => $controller->session = Session::getInstance();
[132] => }
[133] =>
[134] => /**
[135] => * Initializes the controller class and calls the action.
[136] => *
[137] => * @param string $controllerClass
[138] => * @param string $actionName
[139] => * @param string $file
[140] => */
[141] => static function call($controllerClass, $actionName, $file = false) {
[142] => if ((! @include_once(DIR_APP . DS . 'controller' . DS . 'base.php')) ||
[143] => (! file_exists($file) || ! @include_once($file))) {
[144] => $message = [
[145] => 'message' => __('Controller file not found!'),
[146] => 'file' => $file,
[147] => ];
[148] =>
[149] => return self :: notFound(false, $message);
[150] => }
[151] =>
[152] => // We check if the controller's class really exists
[153] => $controller = false;
[154] =>
[155] => if (class_exists($controllerClass , false)) {// if the controller does not exist route to controller main
[156] => $controller = new $controllerClass();
[157] =>
[158] => if (! $controller || ! method_exists($controller , $actionName) || $actionName == 'init') {
[159] => $message = [
[160] => 'message' => __('Method does not exist!'),
[161] => 'file' => "$controllerClass :: $actionName",
[162] => ];
[163] =>
[164] => return self :: notFound(false, $message);
[165] => }
[166] => } else {
[167] => $message = [
[168] => 'message' => __('Controller does not exist!'),
[169] => 'file' => $controllerClass,
[170] => ];
[171] =>
[172] => return self :: notFound(false, $message);
[173] => }
[174] =>
[175] => self :: di($controller);
[176] =>
[177] => if (method_exists($controller, 'init')) {
[178] => $return = $controller->init();
[179] =>
[180] => if ($return) {
[181] => $actionName = $return;
[182] =>
[183] => if (! method_exists($controller , $actionName)) {
[184] => $message = [
[185] => 'message' => __('Method does not exist!'),
[186] => 'file' => "$controllerClass :: $actionName",
[187] => ];
[188] =>
[189] => return self :: notFound(false, $message);
[190] => }
[191] => }
[192] => }
[193] =>
[194] => $response = Response::getInstance();
[195] => $template = str_replace('/', DS, strtolower(self :: $moduleName));
[196] => $theme = $controller->view->getTheme();
[197] => $path = DIR_THEME . $theme . DS;
[198] => $isPlugin = strncmp($template, 'plugins/', 8) === 0;
[199] =>
[200] => if ($actionName && $actionName != 'index') {
[201] => if ($isPlugin) {
[202] => $t = str_replace('plugins' . DS, '', $template);
[203] => $p = strpos($t, DS);
[204] => $pluginName = substr($t, 0, $p);
[205] => $nameSpace = substr($t, $p + 1);
[206] =>
[207] => $html = DIR_PLUGINS . $pluginName . DS . 'public' . DS . APP . DS . $nameSpace . DS . strtolower($actionName) . '.html';
[208] => } else {
[209] => $html = $path . $template . DS . strtolower($actionName) . '.html';
[210] => }
[211] =>
[212] => if (is_file($html)) {
[213] => $template .= DS . strtolower($actionName);
[214] => }
[215] => }
[216] =>
[217] => $controller->view->template($template . '.html'); //default html that can be overwritten
[218] =>
[219] => //list($template) = Event :: trigger($controllerClass, "$actionName:before", $template);
[220] =>
[221] => //$controller->view->template($template . '.html'); //default html
[222] => $template = call_user_func([$controller, $actionName]); // <==
[223] =>
[224] => list($template, $controller, $actionName) = Event::trigger(__CLASS__, __FUNCTION__, $template, $controller, $actionName);
[225] => $responseType = $response->getType();
[226] => $controller->view->setType($responseType);
[227] =>
[228] => if ($template === false) {
[229] => $controller->view->template(false);
[230] => } else {
[231] => if (is_array($template)) {
[232] => $response->output($template);
[233] => //echo json_encode($template);
[234] => } else {
[235] => if ($template) {
[236] => $controller->view->template($template);
[237] => }
[238] => }
[239] => }
[240] =>
[241] => $response->setStatus(self :: $status);
[242] => $return = $response->output();
[243] => self :: closeConnections();
[244] =>
[245] => return $return;
[246] => }
[247] =>
[248] => /**
[249] => * Redirect or direct to a action or default controller action and parameters
[250] => * it has the ability to http redirect to the specified action
[251] => * internally used to direct to action.
[252] => *
[253] => * @param string $moduleName
[254] => * @param string $actionName
[255] => * @param array $parameters
[256] => * @param bool $httpRedirect
[257] => * @return bool
[258] => */
[259] => static function redirect($moduleName , $actionName = 'index') {
[260] => self :: $moduleName = $moduleName;
[261] => self :: $actionName = $actionName;
[262] =>
[263] => if (is_dir(DIR_APP . DS . 'controller' . DS . strtolower($moduleName))) {
[264] => self :: $moduleName = $moduleName .= '/Index';
[265] => }
[266] =>
[267] => $dir = strtolower(str_replace('/', DS, $moduleName));
[268] =>
[269] => $className = \Vvveb\dashesToCamelCase(str_replace(['/', DS], '\\', $moduleName));
[270] => $controllerClass = 'Vvveb\Controller\\' . $className;
[271] =>
[272] => //change file paths for plugins
[273] => if (strpos($moduleName, 'Plugins/') === 0) {
[274] => $dir = str_replace('plugins' . DS, '', $dir);
[275] => $p = strpos($dir, DS);
[276] => $pluginName = $dir;
[277] => $nameSpace = 'index';
[278] =>
[279] => if ($p !== false) {
[280] => $pluginName = substr($dir, 0, $p);
[281] => $nameSpace = substr($dir, $p + 1);
[282] => }
[283] => //$className = str_replace('Plugins\\', '', $className);
[284] => $file = DIR_PLUGINS . $pluginName . DS . APP .
[285] => DS . 'controller' . DS . "$nameSpace.php";
[286] => $pluginName = \Vvveb\dashesToCamelCase($pluginName);
[287] => //insert Controller namespace
[288] => $className = str_replace('Plugins\\' . $pluginName, $pluginName . '\Controller', $className);
[289] => $controllerClass = 'Vvveb\Plugins\\' . $className;
[290] => } else {
[291] => $file = DIR_APP . 'controller' . DS . $dir . '.php';
[292] => }
[293] =>
[294] => return self :: call($controllerClass, $actionName, $file);
[295] => }
[296] =>
[297] => static public function getRoute() {
[298] => return $_GET['route'] ?? '';
[299] => }
[300] =>
[301] => static public function getModule() {
[302] => return $_GET['module'] ?? '';
[303] => }
[304] =>
[305] => static public function dispatch(&$site = []) {
[306] => $module = $_GET['module'] ?? $_POST['module'] ?? null;
[307] => $action = $_GET['action'] ?? $_POST['action'] ?? null;
[308] => $_REQUEST = array_merge($_GET, $_REQUEST);
[309] =>
[310] => //subdirectory support
[311] => /*
[312] => $subdir = \Vvveb\pregMatch('@(.+)/index.php@',$_SERVER['SCRIPT_NAME'], 1);
[313] => $subdir = str_replace(['/public', '/admin'], '', $subdir);
[314] => define('V_SUBDIR_INSTALL', $subdir);
[315] => */
[316] =>
[317] => //remove GET parameters to allow correct matching,
[318] => $uri = SITE_URI ?? $_SERVER['REQUEST_URI'] ?? '/';
[319] => $uri = preg_replace('/\?.*$/', '', $uri);
[320] =>
[321] => $route = false;
[322] => $routesSiteId = null;
[323] => if (isset($site['route'])) {
[324] => $routesSiteId = $site['site_id'];
[325] => }
[326] =>
[327] => if (! $module && (APP != 'admin' && APP != 'install' && (Routes::init(APP, $routesSiteId) && $route = Routes::match($uri)))) {
[328] => $_GET = array_merge($route, $_GET);
[329] => } else {
[330] => $module = $module ?? ((APP == 'install' || APP == 'admin') ? 'index' : false);
[331] =>
[332] => if (! $module && APP == 'app') {
[333] => return self::notFound(false, ['message' => 'No route!']);
[334] => }
[335] => }
[336] =>
[337] => if ($route) {
[338] => if (preg_match('@(^.+?)/(\w+$)@', $_GET['module'], $routeMatch)) {
[339] => $module = $routeMatch[1];
[340] => $action = $action ?? $routeMatch[2];
[341] => } else {
[342] => $module = trim($_GET['module'], '/');
[343] => }
[344] => }
[345] =>
[346] => if (empty($action)) {
[347] => $action = 'index';
[348] => }
[349] => //santize inputs
[350] => if (($module && ! preg_match('@^[a-zA-Z_/0-9\-]{4,70}$@', $module)) ||
[351] => ($action && ! preg_match('@^[a-zA-Z_/0-9\-]{3,70}$@', $action))) {
[352] => return self::notFound(false, ['message' => 'Invalid request!'], 500);
[353] => }
[354] =>
[355] => $path = $module;
[356] =>
[357] => $module = ucfirst($module);
[358] => $path = '';
[359] =>
[360] => array_map(function ($value) use (&$path) {
[361] => if ($path) {
[362] => $path .= '/';
[363] => }
[364] => $path .= ucfirst($value);
[365] => }, explode('/', $module));
[366] =>
[367] => return self :: redirect($path, $action);
[368] => }
[369] => }
)
)