/** * Outputs exception information * @return type */ public function output() { if (!defined('AJAX_REQUEST') && Ajax::validateRequest($_REQUEST)) { // Return valid JS in ajax requests if the 'fail' status was thrown before ajax initialization header('Content-type: application/json'); $message = json_encode(array('error' => $this->message)); if (!empty($_REQUEST['callback'])) { $message = $_REQUEST['callback'] . "(" . $message . ");"; } echo $message; exit; } elseif (defined('CONSOLE') || Debugger::isActive() || defined('DEVELOPMENT') && DEVELOPMENT) { echo $this->printDebug(defined('CONSOLE')); } else { $debug = "<!--\n" . $this->printDebug(true) . "\n-->"; Development::showStub(array('[title]' => 'Service unavailable', '[banner]' => 'Service<br/> unavailable', '[message]' => 'Sorry, service is temporarily unavailable.'), $debug); } }
/** * Dispathes the execution control to correct controller * * @return nothing */ function fn_dispatch($controller = '', $mode = '', $action = '', $dispatch_extra = '', $area = AREA) { Debugger::checkpoint('After init'); $auth = $_SESSION['auth']; $controller = empty($controller) ? Registry::get('runtime.controller') : $controller; $mode = empty($mode) ? Registry::get('runtime.mode') : $mode; $action = empty($action) ? Registry::get('runtime.action') : $action; $dispatch_extra = empty($dispatch_extra) ? Registry::get('runtime.dispatch_extra') : $dispatch_extra; fn_set_hook('before_dispatch', $controller, $mode, $action, $dispatch_extra, $area); $view = Registry::get('view'); $run_controllers = true; $external = false; $status = CONTROLLER_STATUS_NO_PAGE; // CSRF protection if (fn_is_csrf_protection_enabled($auth) && !fn_csrf_validate_request(array('server' => $_SERVER, 'request' => $_REQUEST, 'session' => $_SESSION, 'controller' => $controller, 'mode' => $mode, 'action' => $action, 'dispatch_extra' => $dispatch_extra, 'area' => $area, 'auth' => $auth))) { fn_set_notification('E', __('error'), __('text_csrf_attack')); fn_redirect(fn_url()); } // If $config['http_host'] was different from the domain name, there was redirection to $config['http_host'] value. if (strtolower(Registry::get('config.current_host')) != strtolower(REAL_HOST) && $_SERVER['REQUEST_METHOD'] == 'GET' && !defined('CONSOLE')) { if (!empty($_SERVER['REDIRECT_URL'])) { $qstring = $_SERVER['REDIRECT_URL']; } else { if (!empty($_SERVER['REQUEST_URI'])) { $qstring = $_SERVER['REQUEST_URI']; } else { $qstring = Registry::get('config.current_url'); } } $curent_path = Registry::get('config.current_path'); if (!empty($curent_path) && strpos($qstring, $curent_path) === 0) { $qstring = substr_replace($qstring, '', 0, fn_strlen($curent_path)); } fn_redirect(Registry::get('config.current_location') . $qstring, false, true); } $upload_max_filesize = Bootstrap::getIniParam('upload_max_filesize'); $post_max_size = Bootstrap::getIniParam('post_max_size'); if (!defined('AJAX_REQUEST') && isset($_SERVER['CONTENT_LENGTH']) && ($_SERVER['CONTENT_LENGTH'] > fn_return_bytes($upload_max_filesize) || $_SERVER['CONTENT_LENGTH'] > fn_return_bytes($post_max_size))) { $max_size = fn_return_bytes($upload_max_filesize) < fn_return_bytes($post_max_size) ? $upload_max_filesize : $post_max_size; fn_set_notification('E', __('error'), __('text_forbidden_uploaded_file_size', array('[size]' => $max_size))); fn_redirect($_SERVER['HTTP_REFERER']); } // If URL contains session ID, remove it if (!defined('AJAX_REQUEST') && !empty($_REQUEST[Session::getName()]) && $_SERVER['REQUEST_METHOD'] == 'GET') { fn_redirect(fn_query_remove(Registry::get('config.current_url'), Session::getName())); } // If demo mode is enabled, check permissions FIX ME - why did we need one more user login check? if ($area == 'A') { if (Registry::get('config.demo_mode') == true) { $run_controllers = fn_check_permissions($controller, $mode, 'demo'); if ($run_controllers == false) { fn_set_notification('W', __('demo_mode'), __('demo_mode_content_text'), 'K', 'demo_mode'); if (defined('AJAX_REQUEST')) { exit; } fn_delete_notification('changes_saved'); $status = CONTROLLER_STATUS_REDIRECT; $_REQUEST['redirect_url'] = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : fn_url(''); } } else { $run_controllers = fn_check_permissions($controller, $mode, 'admin', '', $_REQUEST); if ($run_controllers == false) { if (defined('AJAX_REQUEST')) { $_info = Debugger::isActive() || fn_is_development() ? ' ' . $controller . '.' . $mode : ''; fn_set_notification('W', __('warning'), __('access_denied') . $_info); exit; } $status = CONTROLLER_STATUS_DENIED; } } } if ($_SERVER['REQUEST_METHOD'] != 'POST' && !defined('AJAX_REQUEST')) { if ($area == 'A' && empty($_REQUEST['keep_location']) && !defined('CONSOLE')) { if (!defined('HTTPS') && Registry::get('settings.Security.secure_admin') == 'Y') { fn_redirect(Registry::get('config.https_location') . '/' . Registry::get('config.current_url')); } elseif (defined('HTTPS') && Registry::get('settings.Security.secure_admin') != 'Y') { fn_redirect(Registry::get('config.http_location') . '/' . Registry::get('config.current_url')); } } elseif ($area == 'C') { $secure_controllers = fn_get_secure_controllers(); // if we are not on https but controller is secure, redirect to https if (!defined('HTTPS') && (Registry::get('settings.Security.secure_storefront') == 'full' || isset($secure_controllers[$controller]) && $secure_controllers[$controller] == 'active')) { fn_redirect(Registry::get('config.https_location') . '/' . Registry::get('config.current_url'), false, true); } // if we are on https and the controller is insecure, redirect to http if (defined('HTTPS') && Registry::get('settings.Security.secure_storefront') != 'full' && !isset($secure_controllers[$controller]) && Registry::get('settings.Security.keep_https') != 'Y') { fn_redirect(Registry::get('config.http_location') . '/' . Registry::get('config.current_url'), false, true); } } } LastView::instance()->prepare($_REQUEST); $controllers_cascade = array(); $controllers_list = array('init'); if ($run_controllers == true) { $controllers_list[] = $controller; $controllers_list = array_unique($controllers_list); } foreach ($controllers_list as $ctrl) { $core_controllers = fn_init_core_controllers($ctrl); list($addon_controllers) = fn_init_addon_controllers($ctrl); if (empty($core_controllers) && empty($addon_controllers)) { //$controllers_cascade = array(); // FIXME: controllers_cascade contains INIT. We should not clear initiation code. $status = CONTROLLER_STATUS_NO_PAGE; $run_controllers = false; break; } if (count($core_controllers) + count($addon_controllers) > 1) { throw new DeveloperException('Duplicate controller ' . $controller . var_export(array_merge($core_controllers, $addon_controllers), true)); } $core_pre_controllers = fn_init_core_controllers($ctrl, GET_PRE_CONTROLLERS); $core_post_controllers = fn_init_core_controllers($ctrl, GET_POST_CONTROLLERS); list($addon_pre_controllers) = fn_init_addon_controllers($ctrl, GET_PRE_CONTROLLERS); list($addon_post_controllers, $addons) = fn_init_addon_controllers($ctrl, GET_POST_CONTROLLERS); // we put addon post-controller to the top of post-controller cascade if current addon serves this request if (count($addon_controllers)) { $addon_post_controllers = fn_reorder_post_controllers($addon_post_controllers, $addon_controllers[0]); } $controllers_cascade = array_merge($controllers_cascade, $addon_pre_controllers, $core_pre_controllers, $core_controllers, $addon_controllers, $core_post_controllers, $addon_post_controllers); if (empty($controllers_cascade)) { throw new DeveloperException("No controllers for: {$ctrl}"); } } if ($mode == 'add') { $tpl = 'update.tpl'; } elseif (strpos($mode, 'add_') === 0) { $tpl = str_replace('add_', 'update_', $mode) . '.tpl'; } else { $tpl = $mode . '.tpl'; } $view = Registry::get('view'); if ($view->templateExists('views/' . $controller . '/' . $tpl)) { // try to find template in base views $view->assign('content_tpl', 'views/' . $controller . '/' . $tpl); } elseif (defined('LOADED_ADDON_PATH') && $view->templateExists('addons/' . LOADED_ADDON_PATH . '/views/' . $controller . '/' . $tpl)) { // try to find template in addon views $view->assign('content_tpl', 'addons/' . LOADED_ADDON_PATH . '/views/' . $controller . '/' . $tpl); } elseif (!empty($addons)) { // try to find template in addon views that extend base views foreach ($addons as $addon => $_v) { if ($view->templateExists('addons/' . $addon . '/views/' . $controller . '/' . $tpl)) { $view->assign('content_tpl', 'addons/' . $addon . '/views/' . $controller . '/' . $tpl); break; } } } /** * Performs actions after template assignment and before controller run * * @param string $controller controller name * @param string $mode controller mode name * @param string $area current working area * @param array $controllers_cascade list of controllers to run */ fn_set_hook('dispatch_assign_template', $controller, $mode, $area, $controllers_cascade); foreach ($controllers_cascade as $item) { $_res = fn_run_controller($item, $controller, $mode, $action, $dispatch_extra); // 0 - status, 1 - url $url = !empty($_res[1]) ? $_res[1] : ''; $external = !empty($_res[2]) ? $_res[2] : false; $permanent = !empty($_res[3]) ? $_res[3] : false; // Status could be changed only if we allow to run controllers despite of init controller if ($run_controllers == true) { $status = !empty($_res[0]) ? $_res[0] : CONTROLLER_STATUS_OK; } if ($status == CONTROLLER_STATUS_OK && !empty($url)) { $redirect_url = $url; } elseif ($status == CONTROLLER_STATUS_REDIRECT && !empty($url)) { $redirect_url = $url; break; } elseif ($status == CONTROLLER_STATUS_DENIED || $status == CONTROLLER_STATUS_NO_PAGE) { break; } } LastView::instance()->init($_REQUEST); // In console mode, just stop here if (defined('CONSOLE')) { $notifications = fn_get_notifications(); $exit_code = 0; foreach ($notifications as $n) { fn_echo('[' . $n['title'] . '] ' . $n['message'] . "\n"); if ($n['type'] == 'E') { $exit_code = 1; } } exit($exit_code); } if (!empty($auth['this_login']) && Registry::ifGet($auth['this_login'], 'N') === 'Y') { fn_set_notification('E', __('error'), __(ACCOUNT_TYPE . LOGIN_STATUS_USER_DISABLED)); $status = CONTROLLER_STATUS_DENIED; } // [Block manager] // block manager is disabled for vendors. if (!(fn_allowed_for('MULTIVENDOR') && Registry::get('runtime.company_id') || fn_allowed_for('ULTIMATE') && !Registry::get('runtime.company_id'))) { if (fn_check_permissions('block_manager', 'manage', 'admin')) { $dynamic_object = SchemesManager::getDynamicObject($_REQUEST['dispatch'], $area, $_REQUEST); if (!empty($dynamic_object)) { if ($area == 'A' && Registry::get('runtime.mode') != 'add' && !empty($_REQUEST[$dynamic_object['key']])) { $object_id = $_REQUEST[$dynamic_object['key']]; $location = Location::instance()->get($dynamic_object['customer_dispatch'], $dynamic_object, CART_LANGUAGE); if (!empty($location) && $location['is_default'] != 1) { $params = array('dynamic_object' => array('object_type' => $dynamic_object['object_type'], 'object_id' => $object_id), $dynamic_object['key'] => $object_id, 'manage_url' => Registry::get('config.current_url')); Registry::set('navigation.tabs.blocks', array('title' => __('layouts'), 'href' => 'block_manager.manage_in_tab?' . http_build_query($params), 'ajax' => true)); } } } } } // [/Block manager] // Redirect if controller returned successful/redirect status only if (in_array($status, array(CONTROLLER_STATUS_OK, CONTROLLER_STATUS_REDIRECT)) && !empty($_REQUEST['redirect_url']) && !$external) { $redirect_url = $_REQUEST['redirect_url']; } // If controller returns "Redirect" status, check if redirect url exists if ($status == CONTROLLER_STATUS_REDIRECT && empty($redirect_url)) { $status = CONTROLLER_STATUS_NO_PAGE; } // In backend show "changes saved" notification if ($area == 'A' && $_SERVER['REQUEST_METHOD'] == 'POST' && in_array($status, array(CONTROLLER_STATUS_OK, CONTROLLER_STATUS_REDIRECT))) { if (strpos($mode, 'update') !== false && $mode != 'update_status' && $mode != 'update_mode' && !fn_notification_exists('extra', 'demo_mode') && !fn_notification_exists('type', 'E')) { fn_set_notification('N', __('notice'), __('text_changes_saved'), 'I', 'changes_saved'); } } // Attach params and redirect if needed if (in_array($status, array(CONTROLLER_STATUS_OK, CONTROLLER_STATUS_REDIRECT)) && !empty($redirect_url)) { if (!isset($_REQUEST['return_to_list'])) { $params = array('page', 'selected_section', 'active_tab'); $url_params = array(); foreach ($params as $param) { if (!empty($_REQUEST[$param])) { $url_params[$param] = $_REQUEST[$param]; } } if (!empty($url_params)) { $redirect_url = fn_link_attach($redirect_url, http_build_query($url_params)); } } if (!isset($external)) { $external = false; } if (!isset($permanent)) { $permanent = false; } fn_redirect($redirect_url, $external, $permanent); } if (!$view->getTemplateVars('content_tpl') && $status == CONTROLLER_STATUS_OK) { // FIXME $status = CONTROLLER_STATUS_NO_PAGE; } if ($status != CONTROLLER_STATUS_OK) { if ($status == CONTROLLER_STATUS_NO_PAGE) { if ($area == 'A' && empty($auth['user_id'])) { // If admin is not logged in redirect to login page from not found page fn_set_notification('W', __('page_not_found'), __('page_not_found_text')); fn_redirect("auth.login_form"); } header(' ', true, 404); } $view->assign('exception_status', $status); if ($area == 'A') { $view->assign('content_tpl', 'exception.tpl'); // for backend only } if ($status == CONTROLLER_STATUS_DENIED) { $view->assign('page_title', __('access_denied')); } elseif ($status == CONTROLLER_STATUS_NO_PAGE) { $view->assign('page_title', __('page_not_found')); } } fn_set_hook('dispatch_before_display'); Debugger::checkpoint('Before TPL'); // Pass current URL to ajax response only if we render whole page if (defined('AJAX_REQUEST') && Registry::get('runtime.root_template') == 'index.tpl') { Registry::get('ajax')->assign('current_url', fn_url(Registry::get('config.current_url'), $area, 'current')); } Registry::get('view')->display(Registry::get('runtime.root_template')); Debugger::checkpoint('After TPL'); Debugger::display(); fn_set_hook('complete'); if (defined('AJAX_REQUEST')) { // HHVM workaround. Destroy Ajax object manually if it has been created. $ajax = Registry::get('ajax'); $ajax = null; } exit; // stop execution }
use Tygh\Registry; // Register autoloader $this_dir = dirname(__FILE__); $classLoader = (require $this_dir . '/app/lib/vendor/autoload.php'); $classLoader->add('Tygh', $this_dir . '/app'); class_alias('\\Tygh\\Tygh', 'Tygh'); // Prepare environment and process request vars list($_REQUEST, $_SERVER, $_GET, $_POST) = Bootstrap::initEnv($_GET, $_POST, $_SERVER, $this_dir); // Get config data $config = (require DIR_ROOT . '/config.php'); if (isset($_REQUEST['version'])) { die(PRODUCT_NAME . ' <b>' . PRODUCT_VERSION . ' ' . (PRODUCT_STATUS != '' ? ' (' . PRODUCT_STATUS . ')' : '') . (PRODUCT_BUILD != '' ? ' ' . PRODUCT_BUILD : '') . '</b>'); } Debugger::init(false, $config); // Start debugger log Debugger::checkpoint('Before init'); // Callback: verifies if https works if (isset($_REQUEST['check_https'])) { die(defined('HTTPS') ? 'OK' : ''); } // Check if software is installed if ($config['db_host'] == '%DB_HOST%') { die(PRODUCT_NAME . ' is <b>not installed</b>. Please click here to start the installation process: <a href="install/">[install]</a>'); } // Load core functions $fn_list = array('fn.database.php', 'fn.users.php', 'fn.catalog.php', 'fn.cms.php', 'fn.cart.php', 'fn.locations.php', 'fn.common.php', 'fn.fs.php', 'fn.images.php', 'fn.init.php', 'fn.control.php', 'fn.search.php', 'fn.promotions.php', 'fn.log.php', 'fn.companies.php', 'fn.addons.php'); $fn_list[] = 'fn.' . strtolower(PRODUCT_EDITION) . '.php'; foreach ($fn_list as $file) { require $config['dir']['functions'] . $file; } Registry::set('config', $config);
/** * Gets cached data * * @param string $key key name * @param string $cache_level indicates the cache dependencies on controller, language, user group, etc * * @return mixed cached data if exist, NULL otherwise */ private static function _getCache($key, $cache_level = NULL) { $time_start = microtime(true); $data = self::$_cache->get($key, $cache_level); Debugger::set_cache_query($key . '::' . $cache_level, microtime(true) - $time_start); return $data !== false && !empty($data[0]) ? $data[0] : NULL; }
/** * Connects to the Redis server * @return boolean true on success, false - otherwise */ protected function connect() { $this->r = new \Redis(); Debugger::checkpoint('Session: before redis connect'); if ($this->r->connect($this->config['redis_server']) == true) { $this->r->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_PHP); Debugger::checkpoint('Session: after redis connect'); return true; } return false; }
/** * Renders block content * * @static * * @param array $block Block data for rendering content * @param array $params Parameters of rendering: * * use_cache - Whether to use cache * * parse_js - Whether to move inline JS of the block to the bottom of the page * * @return string HTML code of rendered block content */ public static function renderBlockContent($block, $params = array()) { $default_params = array('use_cache' => true, 'parse_js' => true); $params = array_merge($default_params, $params); // Do not render block if it disabled in the frontend if (isset($block['is_disabled']) && $block['is_disabled']) { return ''; } $smarty = \Tygh::$app['view']; $smarty_original_vars = $smarty->getTemplateVars(); $display_this_block = true; self::_assignBlockSettingsToTemplate($block); // Assign block data from DB $smarty->assign('block', $block); $theme_path = self::getCustomerThemePath(); $block_schema = SchemesManager::getBlockScheme($block['type'], array()); $grid_id = empty($block['grid_id']) ? 0 : $block['grid_id']; $cache_key = "block_content_{$block['block_id']}_{$block['snapping_id']}_{$block['type']}_{$grid_id}"; if (!empty($block['object_id']) && !empty($block['object_type'])) { $cache_key .= "_{$block['object_id']}_{$block['object_type']}"; } $cache_this_block = $params['use_cache'] && self::allowCache(); if ($cache_this_block && isset($block['content']['items']['filling']) && isset($block_schema['content']['items']['fillings'][$block['content']['items']['filling']]['disable_cache'])) { $cache_this_block = !$block_schema['content']['items']['fillings'][$block['content']['items']['filling']]['disable_cache']; } /** * Determines flags for Cache * * @param array $block Block data * @param string $cache_key Generated name of cache * @param array $block_schema Block schema * @param bool $cache_this_block Flag to register cache * @param bool $display_this_block Flag to display block */ fn_set_hook('render_block_register_cache', $block, $cache_key, $block_schema, $cache_this_block, $display_this_block); if ($cache_this_block) { // We need an extra data to cache Inline JavaScript $smarty->assign('block_cache_name', $cache_key); // Check whether cache was registered successfully $cache_this_block = self::registerBlockCacheIfNeeded($cache_key, $block_schema, $block); } else { $smarty->clearAssign('block_cache_name'); } $smarty->assign('block_rendering', true); $smarty->assign('block_parse_js', $params['parse_js']); // We should load only when cache record exists $load_block_from_cache = $cache_this_block && Registry::isExist($cache_key); $block_content = ''; // Block content is found at cache and should be loaded out of there if ($load_block_from_cache) { $cached_content = Registry::get($cache_key); $block_content = $cached_content['content']; if (!empty($cached_content['javascript'])) { $repeat = false; $smarty->loadPlugin('smarty_block_inline_script'); smarty_block_inline_script(array(), $cached_content['javascript'], $smarty, $repeat); } Debugger::blockFoundAtCache($block['block_id']); } else { if ($block['type'] == Block::TYPE_MAIN) { $block_content = self::_renderMainContent(); } else { $title = $block['name']; if (Registry::get('runtime.customization_mode.live_editor')) { $le_block_types = fn_get_schema('customization', 'live_editor_block_types'); if (!empty($le_block_types[$block['type']]) && !empty($le_block_types[$block['type']]['name'])) { $title = sprintf('<span data-ca-live-editor-obj="block:name:%s">%s</span>', $block['block_id'], $title); } } $smarty->assign('title', $title); if (!empty($block_schema['content'])) { $all_values_are_empty = true; foreach ($block_schema['content'] as $template_variable => $field) { /** * Actions before render any variable of block content * * @param string $template_variable name of current block content variable * @param array $field Scheme of this content variable from block scheme content section * @param array $block_schema block scheme * @param array $block Block data */ fn_set_hook('render_block_content_pre', $template_variable, $field, $block_schema, $block); $value = self::getValue($template_variable, $field, $block_schema, $block); if ($all_values_are_empty && !empty($value)) { $all_values_are_empty = false; } $smarty->assign($template_variable, $value); } // We shouldn't display block which content variables are all empty $display_this_block = $display_this_block && !$all_values_are_empty; } // Assign block data from scheme $smarty->assign('block_scheme', $block_schema); if ($display_this_block && file_exists($theme_path . $block['properties']['template'])) { $block_content = $smarty->fetch($block['properties']['template']); } } if (!empty($block['wrapper']) && file_exists($theme_path . $block['wrapper']) && $display_this_block) { $smarty->assign('content', $block_content); if ($block['type'] == Block::TYPE_MAIN) { $smarty->assign('title', !empty(\Smarty::$_smarty_vars['capture']['mainbox_title']) ? \Smarty::$_smarty_vars['capture']['mainbox_title'] : '', false); } $block_content = $smarty->fetch($block['wrapper']); } else { $smarty->assign('content', $block_content); $block_content = $smarty->fetch('views/block_manager/render/block.tpl'); } fn_set_hook('render_block_content_after', $block_schema, $block, $block_content); // Save block contents to cache if ($cache_this_block && $display_this_block) { $cached_content = Registry::get($cache_key); $cached_content['content'] = $block_content; Registry::set($cache_key, $cached_content); } } $wrap_id = $smarty->getTemplateVars('block_wrap'); $smarty->clearAllAssign(); $smarty->assign($smarty_original_vars); // restore original vars \Smarty::$_smarty_vars['capture']['title'] = null; if ($display_this_block == true) { if (!empty($wrap_id)) { $block_content = '<div id="' . $wrap_id . '">' . $block_content . '<!--' . $wrap_id . '--></div>'; } return trim($block_content); } else { return ''; } }
Registry::get('view')->assign('data', $data['logging']); Registry::get('view')->assign('debugger_hash', $_REQUEST['debugger_hash']); Registry::get('view')->display('views/debugger/components/logging_tab.tpl'); } exit; } elseif ($mode == 'templates') { if (!empty($data['templates'])) { $data['templates']['tpls'] = Debugger::parseTplsList($data['templates']['tpls'], 0); Registry::get('view')->assign('data', $data['templates']); Registry::get('view')->assign('debugger_hash', $_REQUEST['debugger_hash']); Registry::get('view')->display('views/debugger/components/templates_tab.tpl'); } exit; } elseif ($mode == 'blocks') { if (!empty($data['blocks'])) { $blocks_rendered = array_filter($data['blocks'], function ($block) { return !$block['render_performance']['found_at_cache']; }); $blocks_from_cache = array_filter($data['blocks'], function ($block) { return $block['render_performance']['found_at_cache']; }); Registry::get('view')->assign('blocks_rendered', $blocks_rendered); Registry::get('view')->assign('blocks_from_cache', $blocks_from_cache); Registry::get('view')->assign('debugger_hash', $_REQUEST['debugger_hash']); Registry::get('view')->display('views/debugger/components/blocks_tab.tpl'); } exit; } elseif ($mode == 'quit') { Debugger::quit(); return array(CONTROLLER_STATUS_REDIRECT, fn_query_remove($_REQUEST['redirect_url'], Registry::get('config.debugger_token'))); }
/** * Merges css and less files * * @param array $files Array with style files * @param string $styles Style code * @param string $prepend_prefix Prepend prefix * @param array $params additional params */ function fn_merge_styles($files, $styles = '', $prepend_prefix = '', $params = array(), $area = AREA) { $prefix = !empty($prepend_prefix) ? 'embedded' : 'standalone'; $make_rtl = false; if (fn_is_rtl_language()) { $prefix .= '-rtl'; $make_rtl = true; } $output = ''; $less_output = ''; $less_reflection = array(); $compiled_less = ''; $compiled_css = ''; $relative_path = fn_get_theme_path('[relative]/[theme]/css', $area); $hashes = array(); $names = array_map(function ($v) { return !empty($v['relative']) ? $v['relative'] : false; }, $files); // Check file changes if (Development::isEnabled('compile_check') || Debugger::isActive()) { $dir_root = Registry::get('config.dir.root'); foreach ($names as $index => $name) { if (file_exists($dir_root . '/' . $name)) { $hashes[] = $name . filemtime($dir_root . '/' . $name); } } } $hashes[] = md5(implode('|', $names)); $hashes[] = md5($styles); if ($area == 'C') { $hashes[] = Registry::get('runtime.layout.layout_id'); $hashes[] = Registry::get('runtime.layout.style_id'); } arsort($hashes); $hash = md5(implode(',', $hashes) . PRODUCT_VERSION) . fn_get_storage_data('cache_id'); $filename = $prefix . '.' . $hash . '.css'; $theme_manifest = Themes::factory(fn_get_theme_path('[theme]', 'C'))->getManifest(); if (!Storage::instance('assets')->isExist($relative_path . '/' . $filename)) { Debugger::checkpoint('Before styles compilation'); foreach ($files as $src) { $m_prefix = ''; $m_suffix = ''; if (!empty($src['media'])) { $m_prefix = "\n@media " . $src['media'] . " {\n"; $m_suffix = "\n}\n"; } if (strpos($src['file'], '.css') !== false) { $output .= "\n" . $m_prefix . fn_get_contents($src['file']) . $m_suffix; } elseif ($area != 'C' || empty($theme_manifest['converted_to_css'])) { $less_output_chunk = ''; if (file_exists($src['file'])) { if ($area == 'C' && (empty($theme_manifest['parent_theme']) || $theme_manifest['parent_theme'] == 'basic')) { $less_output_chunk = "\n" . $m_prefix . fn_get_contents($src['file']) . $m_suffix; } else { $less_output_chunk = "\n" . $m_prefix . '@import "' . str_replace($relative_path . '/', '', $src['relative']) . '";' . $m_suffix; } } if (!empty($params['reflect_less'])) { if (preg_match('{/addons/([^/]+)/}is', $src['relative'], $m)) { $less_reflection['output']['addons'][$m[1]] .= $less_output_chunk; } else { $less_reflection['output']['main'] .= $less_output_chunk; } } $less_output .= $less_output_chunk; } } $header = str_replace('[files]', implode("\n", $names), Registry::get('config.js_css_cache_msg')); if (!empty($styles)) { $less_output .= $styles; } // Prepend all styles with prefix if (!empty($prepend_prefix)) { $less_output = $output . "\n" . $less_output; $output = ''; } if (!empty($output)) { $compiled_css = Less::parseUrls($output, Storage::instance('assets')->getAbsolutePath($relative_path), fn_get_theme_path('[themes]/[theme]/media', $area)); } if (!empty($theme_manifest['converted_to_css']) && $area == 'C') { $theme_css_path = fn_get_theme_path('[themes]/[theme]', $area) . '/css'; $pcl_filepath = $theme_css_path . '/' . Themes::$compiled_less_filename; if (file_exists($pcl_filepath)) { $compiled_css .= fn_get_contents($pcl_filepath); } list($installed_addons) = fn_get_addons(array('type' => 'active')); foreach ($installed_addons as $addon) { $addon_pcl_filpath = $theme_css_path . "/addons/{$addon['addon']}/" . Themes::$compiled_less_filename; if (file_exists($pcl_filepath)) { $compiled_css .= fn_get_contents($addon_pcl_filpath); } } } if (!empty($less_output)) { $less = new Less(); if (!empty($params['compressed'])) { $less->setFormatter('compressed'); } $less->setImportDir($relative_path); try { $compiled_less = $less->customCompile($less_output, Storage::instance('assets')->getAbsolutePath($relative_path), array(), $prepend_prefix, $area); } catch (Exception $e) { $skip_save = true; $shift = 4; $message = '<div style="border: 2px solid red; padding: 5px;">LESS ' . $e->getMessage(); if (preg_match("/line: (\\d+)/", $message, $m)) { $lo = explode("\n", $less_output); $message .= '<br /><br /><pre>' . implode("\n", array_splice($lo, intval($m[1]) - $shift, $shift * 2)) . '</pre>'; } $message .= '</div>'; fn_set_notification('E', __('error'), $message); } } if (empty($skip_save)) { $compiled_content = $compiled_css . "\n" . $compiled_less; // Move all @import links to the Top of the file. if (preg_match_all('/@import url.*?;/', $compiled_content, $imports)) { $compiled_content = preg_replace('/@import url.*?;/', '', $compiled_content); foreach ($imports[0] as $import_link) { $compiled_content = $import_link . "\n" . $compiled_content; } } if ($make_rtl) { $compiled_content = \CSSJanus::transform($compiled_content); $compiled_content = "body {\ndirection: rtl;\n}\n" . $compiled_content; } Storage::instance('assets')->put($relative_path . '/' . $filename, array('contents' => $header . $compiled_content, 'compress' => false, 'caching' => true)); if (!empty($params['use_scheme'])) { fn_put_contents(fn_get_cache_path(false) . 'theme_editor/' . $filename, $output . '#LESS#' . $less_output); } if (!empty($params['reflect_less'])) { $less_reflection['import_dirs'] = array($relative_path); fn_put_contents(fn_get_cache_path(false) . 'less_reflection.json', json_encode($less_reflection)); } } Debugger::checkpoint('After styles compilation'); } $url = Storage::instance('assets')->getUrl($relative_path . '/' . $filename); return $url; }
/** * Generates error notification * * @param string $action Action thae was happen * @param string $reason Reason, why the error notification must be showed * @param string $table Table name (optional) * @return bool Always true */ private function _generateError($action, $reason, $table = '') { $message = str_replace("[reason]", $reason, $action); if (!empty($table)) { $message = str_replace("[table]", $table, $message); } fn_log_event('settings', 'error', $message); if (Debugger::isActive() || fn_is_development()) { fn_set_notification('E', __('error'), $message); } return true; }
/** * Parse query and replace placeholders with data * * @param string $query unparsed query * @param array $data data for placeholders * @return string parsed query */ public static function process($pattern, $data = array(), $replace = true) { // Replace table prefixes if ($replace) { $pattern = str_replace('?:', self::$_table_prefix, $pattern); } if (!empty($data) && preg_match_all("/\\?(i|s|l|d|a|n|u|e|m|p|w|f)+/", $pattern, $m)) { $offset = 0; foreach ($m[0] as $k => $ph) { if ($ph == '?u' || $ph == '?e') { $table_pattern = '\\?\\:'; if ($replace) { $table_pattern = self::$_table_prefix; } if (preg_match("/^(UPDATE|INSERT INTO|REPLACE INTO|DELETE FROM) " . $table_pattern . "(\\w+) /", $pattern, $m)) { $data[$k] = self::checkTableFields($data[$k], $m[2]); if (empty($data[$k])) { return false; } } } if ($ph == '?i') { // integer $pattern = self::_strReplace($ph, self::_intVal($data[$k]), $pattern, $offset); // Trick to convert int's and longint's } elseif ($ph == '?s') { // string $pattern = self::_strReplace($ph, "'" . self::$_db->escape($data[$k]) . "'", $pattern, $offset); } elseif ($ph == '?l') { // string for LIKE operator $pattern = self::_strReplace($ph, "'" . self::$_db->escape(str_replace("\\", "\\\\", $data[$k])) . "'", $pattern, $offset); } elseif ($ph == '?d') { // float $pattern = self::_strReplace($ph, sprintf('%01.2f', $data[$k]), $pattern, $offset); } elseif ($ph == '?a') { // array FIXME: add trim $data[$k] = !is_array($data[$k]) ? array($data[$k]) : $data[$k]; if (!empty($data[$k])) { $pattern = self::_strReplace($ph, implode(', ', self::_filterData($data[$k], true)), $pattern, $offset); } else { if (Debugger::isActive() || defined('DEVELOPMENT')) { trigger_error('Empty array was passed into SQL statement IN()', E_USER_DEPRECATED); } $pattern = self::_strReplace($ph, 'NULL', $pattern, $offset); } } elseif ($ph == '?n') { // array of integer FIXME: add trim $data[$k] = !is_array($data[$k]) ? array($data[$k]) : $data[$k]; $pattern = self::_strReplace($ph, !empty($data[$k]) ? implode(', ', array_map(array('self', '_intVal'), $data[$k])) : "''", $pattern, $offset); } elseif ($ph == '?u' || $ph == '?w') { // update/condition with and $clue = $ph == '?u' ? ', ' : ' AND '; $q = implode($clue, self::_filterData($data[$k], false)); $pattern = self::_strReplace($ph, $q, $pattern, $offset); } elseif ($ph == '?e') { // insert $filtered = self::_filterData($data[$k], true); $pattern = self::_strReplace($ph, "(" . implode(', ', array_keys($filtered)) . ") VALUES (" . implode(', ', array_values($filtered)) . ")", $pattern, $offset); } elseif ($ph == '?m') { // insert multi $values = array(); foreach ($data[$k] as $value) { $filtered = self::_filterData($value, true); $values[] = "(" . implode(', ', array_values($filtered)) . ")"; } $pattern = self::_strReplace($ph, "(" . implode(', ', array_keys($filtered)) . ") VALUES " . implode(', ', $values), $pattern, $offset); } elseif ($ph == '?f') { // field/table/database name $pattern = self::_strReplace($ph, self::_field($data[$k]), $pattern, $offset); } elseif ($ph == '?p') { // prepared statement $pattern = self::_strReplace($ph, self::_tablePrefixReplace('?:', self::$_table_prefix, $data[$k]), $pattern, $offset); } } } return $pattern; }
/** * Run init functions * * @param array $request $_REQUEST global variable * @return bool always true */ function fn_init(&$request) { $stack = Registry::get('init_stack'); // Cleanup stack Registry::set('init_stack', array()); foreach ($stack as $function_data) { $function = array_shift($function_data); if (!is_callable($function)) { continue; } $result = call_user_func_array($function, $function_data); $status = !empty($result[0]) ? $result[0] : INIT_STATUS_OK; $url = !empty($result[1]) ? $result[1] : ''; $message = !empty($result[2]) ? $result[2] : ''; $permanent = !empty($result[3]) ? $result[3] : ''; if ($status == INIT_STATUS_OK && !empty($url)) { $redirect_url = $url; } elseif ($status == INIT_STATUS_REDIRECT && !empty($url)) { $redirect_url = $url; break; } elseif ($status == INIT_STATUS_FAIL) { if (empty($message)) { $message = 'Initialization failed in <b>' . (is_array($function) ? implode('::', $function) : $function) . '</b> function'; } throw new InitException($message); } } if (!empty($redirect_url)) { if (!defined('CART_LANGUAGE')) { fn_init_language($request); // we need CART_LANGUAGE in fn_url function that called in fn_redirect } fn_redirect($redirect_url, true, !empty($permanent)); } $stack = Registry::get('init_stack'); if (!empty($stack)) { // New init functions were added to stack. Execute them fn_init($request); } Debugger::init(true); return true; }
continue; } $result = call_user_func_array($function, $function_data); $status = !empty($result[0]) ? $result[0] : INIT_STATUS_OK; $url = !empty($result[1]) ? $result[1] : ''; $message = !empty($result[2]) ? $result[2] : ''; if ($status == INIT_STATUS_OK && !empty($url)) { $redirect_url = $url; } elseif ($status == INIT_STATUS_REDIRECT && !empty($url)) { $redirect_url = $url; break; } elseif ($status == INIT_STATUS_FAIL) { if (empty($message)) { $message = 'Initiation failed in <b>' . (is_array($function) ? implode('::', $function) : $function) . '</b> function'; } die($message); } } /* if (!empty($redirect_url)) { if (!defined('CART_LANGUAGE')) { fn_init_language($request); // we need CART_LANGUAGE in fn_url function that called in fn_redirect } fn_redirect($redirect_url); } */ $stack = Registry::get('init_stack'); if (!empty($stack)) { // New init functions were added to stack. Execute them fn_init($request); } Debugger::init(true);
/** * Renders current location * @return string HTML code of rendered location */ public function render() { if (!empty($this->_location)) { $this->_view->assign('containers', array('top_panel' => $this->_renderContainer($this->_containers['TOP_PANEL']), 'header' => $this->_renderContainer($this->_containers['HEADER']), 'content' => $this->_renderContainer($this->_containers['CONTENT']), 'footer' => $this->_renderContainer($this->_containers['FOOTER']))); Debugger::checkpoint('End render location'); return $this->_view->fetch($this->_theme . 'location.tpl'); } else { return ''; } }
/** * Parse query and replace placeholders with data * * @param string $query unparsed query * @param array $data data for placeholders * @return string parsed query */ public function process($pattern, $data = array(), $replace = true) { // Replace table prefixes if ($replace) { $pattern = str_replace('?:', $this->table_prefix, $pattern); } if (!empty($data) && preg_match_all("/\\?(i|s|l|d|a|n|u|e|m|p|w|f)+/", $pattern, $m)) { $offset = 0; foreach ($m[0] as $k => $ph) { if ($ph == '?u' || $ph == '?e') { $table_pattern = '\\?\\:'; if ($replace) { $table_pattern = $this->table_prefix; } if (preg_match("/^(UPDATE|INSERT INTO|REPLACE INTO|DELETE FROM) " . $table_pattern . "(\\w+) /", $pattern, $m)) { $data[$k] = $this->checkTableFields($data[$k], $m[2]); if (empty($data[$k])) { return false; } } } switch ($ph) { // integer case '?i': $pattern = $this->strReplace($ph, $this->intVal($data[$k]), $pattern, $offset); // Trick to convert int's and longint's break; // string // string case '?s': $pattern = $this->strReplace($ph, "'" . $this->db->escape($data[$k]) . "'", $pattern, $offset); break; // string for LIKE operator // string for LIKE operator case '?l': $pattern = $this->strReplace($ph, "'" . $this->db->escape(str_replace("\\", "\\\\", $data[$k])) . "'", $pattern, $offset); break; // float // float case '?d': if ($data[$k] == INF) { $data[$k] = PHP_INT_MAX; } $pattern = $this->strReplace($ph, sprintf('%01.2f', $data[$k]), $pattern, $offset); break; // array of string // @FIXME: add trim // array of string // @FIXME: add trim case '?a': $data[$k] = is_array($data[$k]) ? $data[$k] : array($data[$k]); if (!empty($data[$k])) { $pattern = $this->strReplace($ph, implode(', ', $this->filterData($data[$k], true, true)), $pattern, $offset); } else { if (Debugger::isActive() || fn_is_development()) { trigger_error('Empty array was passed into SQL statement IN()', E_USER_DEPRECATED); } $pattern = $this->strReplace($ph, 'NULL', $pattern, $offset); } break; // array of integer // FIXME: add trim // array of integer // FIXME: add trim case '?n': $data[$k] = is_array($data[$k]) ? $data[$k] : array($data[$k]); $pattern = $this->strReplace($ph, !empty($data[$k]) ? implode(', ', array_map(array('self', 'intVal'), $data[$k])) : "''", $pattern, $offset); break; // update // update case '?u': $clue = $ph == '?u' ? ', ' : ' AND '; $q = implode($clue, $this->filterData($data[$k], false)); $pattern = $this->strReplace($ph, $q, $pattern, $offset); break; //condition with and //condition with and case '?w': $q = $this->buildConditions($data[$k]); $pattern = $this->strReplace($ph, $q, $pattern, $offset); break; // insert // insert case '?e': $filtered = $this->filterData($data[$k], true); $pattern = $this->strReplace($ph, "(" . implode(', ', array_keys($filtered)) . ") VALUES (" . implode(', ', array_values($filtered)) . ")", $pattern, $offset); break; // insert multi // insert multi case '?m': $values = array(); foreach ($data[$k] as $value) { $filtered = $this->filterData($value, true); $values[] = "(" . implode(', ', array_values($filtered)) . ")"; } $pattern = $this->strReplace($ph, "(" . implode(', ', array_keys($filtered)) . ") VALUES " . implode(', ', $values), $pattern, $offset); break; // field/table/database name // field/table/database name case '?f': $pattern = $this->strReplace($ph, $this->field($data[$k]), $pattern, $offset); break; // prepared statement // prepared statement case '?p': $pattern = $this->strReplace($ph, $this->tablePrefixReplace('?:', $this->table_prefix, $data[$k]), $pattern, $offset); break; } } } return $pattern; }