function generateArchive($themeName, $userThemeName = '', $includeThemler = true)
{
    register_shutdown_function('fatalErrorShutdownHandler');
    $themeDir = FilesHelper::normalizePath(getThemeDir($themeName));
    if (!file_exists($themeDir)) {
        die('Error : No Theme Folder');
    }
    $userThemeName = $userThemeName ? $userThemeName : $themeName;
    $uniqid = uniqid();
    $base_upload_dir = get_base_upload_dir() . '/' . $uniqid;
    $user_template_dir = $base_upload_dir . '/' . $userThemeName;
    FilesHelper::copyRecursive($themeDir, $user_template_dir);
    if (!$includeThemler) {
        $dirs = array('export', 'project');
        clearDirs($user_template_dir, $dirs);
    }
    $previewThemeDir = FilesHelper::normalizePath(getThemeDir($themeName . _PREVIEW_SUFFIX_));
    $archiveName = 'theme_' . uniqid(time()) . '.zip';
    $archiveFile = $base_upload_dir . '/' . $archiveName;
    $archive = new PclZip($archiveFile);
    add_version_folders($archive, $base_upload_dir, $user_template_dir, $previewThemeDir, $userThemeName, $includeThemler);
    add_files_to_archive_root($archive, $base_upload_dir, $user_template_dir, $previewThemeDir, $userThemeName);
    // Temporary fix to support Prestashop Cloud Install
    deleteFromArchive($archive, 'modules/designer/override/controllers/admin/AdminLoginController.php');
    if (is_readable($archiveFile)) {
        $archiveContent = array('ext' => 'zip', 'content' => base64_encode(FilesHelper::readFile($archiveFile)));
        FilesHelper::removeDir($base_upload_dir, true);
        return $archiveContent;
    }
    die('Archive file: ' . $archiveFile . ' is not readable');
}
function getThemeArchive($themeName, $userThemeName, $includeThemler)
{
    $themeDir = FilesHelper::normalizePath(getThemeDir($themeName));
    if (!file_exists($themeDir)) {
        die('Error : No Theme Folder');
    }
    $userThemeName = $userThemeName ? $userThemeName : $themeName;
    $base_upload_dir = get_base_upload_dir();
    $user_template_dir = $base_upload_dir . '/' . $userThemeName;
    FilesHelper::copyRecursive($themeDir, $user_template_dir);
    if (!$includeThemler) {
        $dirs = array('export', 'project');
        clearDirs($user_template_dir, $dirs);
    }
    $previewThemeDir = FilesHelper::normalizePath(getThemeDir($themeName . _PREVIEW_SUFFIX_));
    $archive_name = 'theme_' . uniqid(time()) . '.zip';
    $archive_file = $base_upload_dir . '/' . $archive_name;
    $archive = new PclZip($archive_file);
    add_version_folders($archive, $base_upload_dir, $user_template_dir, $previewThemeDir, $userThemeName, $includeThemler);
    add_files_to_archive_root($archive, $base_upload_dir, $user_template_dir, $previewThemeDir, $userThemeName);
    // Temporary fix to support Prestashop Cloud Install
    deleteFromArchive($archive, 'modules/designer/override/controllers/admin/AdminLoginController.php');
    FilesHelper::removeDir($user_template_dir, true);
    return $archive_file;
}
 public function renderForms($themeName)
 {
     $themeDir = FilesHelper::normalizePath(getThemeDir($themeName));
     $form = array();
     $this->_renderTemplatesForm($form, $themeDir, $themeName);
     $this->_renderSlidersForms($form, $themeDir, $themeName);
     return $form;
 }
 public function getThemeTemplates($themeName)
 {
     $path = FilesHelper::normalizePath(getThemeDir($themeName . _PREVIEW_SUFFIX_)) . '/templates/templates.php';
     if (file_exists($path)) {
         // TODO: Maybe we have to store all html and parse them after each update or export operation for backward
         require_once $path;
     } else {
         $templates = getTemplates();
         // backward with old themes which do not have templates.php file but plugin is already updated
     }
     $context = Context::getContext();
     $link = $context->link;
     $controllers = getTemplateControllers();
     $previewParam = 'theme_name=' . $themeName;
     $result = array();
     foreach ($templates as $type => $template) {
         $controller = $controllers[$type];
         $method = 'get' . $controller . 'Link';
         if (method_exists($link, $method)) {
             $lower = strtolower($controller);
             $item = Designer::getFirstItem($lower);
             if ($item > 0) {
                 $baseUrl = $link->{$method}($item);
                 $pos = strpos($baseUrl, '?');
                 if ($pos !== FALSE) {
                     // HACK: preview parameter must be first in URL in Debug mode
                     $mainPart = substr($baseUrl, 0, $pos);
                     $params = substr($baseUrl, $pos + 1);
                     $templateUrl = $mainPart . '?' . $previewParam . '&' . $params;
                 } else {
                     $templateUrl = $baseUrl . '?' . $previewParam;
                 }
             } else {
                 $templateUrl = $link->getPageLink('index') . '?' . $previewParam . '&missingContent=' . $lower;
             }
         } else {
             $templateUrl = $link->getPageLink($controller);
             if (strpos($templateUrl, $previewParam) === FALSE) {
                 // can be set in some case from Dispatcher.php
                 $templateUrl .= (strpos($templateUrl, '?') !== FALSE ? '&' : '?') . $previewParam;
             }
         }
         if (is_array($template)) {
             // updated theme with templates.php file
             foreach ($template as $t) {
                 $result[$t['name']] = $templateUrl . '&template=' . $type . '_' . $t['id'];
                 // format as {templateName_id.tpl}
             }
         } else {
             // backward with old themes which do not have templates.php file but plugin is already updated
             $result[$type] = $templateUrl;
         }
     }
     return $result;
 }
Exemple #5
0
function getCSSURL()
{
    global $BASE_URL;
    return "{$BASE_URL}/" . getThemeDir() . "/style.css";
}
 protected function _getApplicableTemplateDir($template)
 {
     require_once dirname(__FILE__) . '../../../../modules/designerpreview/defines.inc.php';
     return $this->_isTemplateOverloaded($template) ? getThemeDir() : _PS_MODULE_DIR_ . $this->name . '/';
 }
 public static function exec($hook_name, $hook_args = array(), $id_module = null, $array_return = false, $check_exceptions = true)
 {
     require_once dirname(__FILE__) . '../../../modules/designerpreview/defines.inc.php';
     static $disable_non_native_modules = null;
     if ($disable_non_native_modules === null) {
         $disable_non_native_modules = (bool) Configuration::get('PS_DISABLE_NON_NATIVE_MODULE');
     }
     // Check arguments validity
     if ($id_module && !is_numeric($id_module) || !Validate::isHookName($hook_name)) {
         throw new PrestaShopException('Invalid id_module or hook_name');
     }
     // If no modules associated to hook_name or recompatible hook name, we stop the function
     if (!($module_list = Hook::getHookModuleExecList($hook_name))) {
         return '';
     }
     // Check if hook exists
     if (!($id_hook = Hook::getIdByName($hook_name))) {
         return false;
     }
     // Store list of executed hooks on this page
     Hook::$executed_hooks[$id_hook] = $hook_name;
     $live_edit = false;
     $context = Context::getContext();
     if (!isset($hook_args['cookie']) || !$hook_args['cookie']) {
         $hook_args['cookie'] = $context->cookie;
     }
     if (!isset($hook_args['cart']) || !$hook_args['cart']) {
         $hook_args['cart'] = $context->cart;
     }
     $retro_hook_name = Hook::getRetroHookName($hook_name);
     // Look on modules list
     $altern = 0;
     $output = '';
     if ($disable_non_native_modules && !isset(Hook::$native_module)) {
         Hook::$native_module = Module::getNativeModuleList();
     }
     $callableHooks = array('displayLeftColumn', 'displayRightColumn', 'displayFooter', 'displayTop', 'displayHome', 'displayNavigationBar');
     $isDesignerHook = isset($hook_args) && isset($hook_args['designer_hook']);
     // Billion Themler layoutPosition only
     $source_hook_name = $hook_name;
     if (isset($hook_args) && isset($hook_args['blockId'])) {
         // both Prestashop hooks and Designer layoutPosition
         $blockId = $hook_args['blockId'];
         $context->smarty->assign('blockId', $blockId);
         file_put_contents(getThemeDir() . '/includes/' . $hook_name . '.tpl', "{assign var=blockId value={$blockId} scope='parent'}");
         // for blocklayered-ajax
     }
     $count = getModulesCount($hook_name, $module_list);
     foreach ($module_list as $index => $array) {
         // Check errors
         if ($id_module && $id_module != $array['id_module']) {
             continue;
         }
         if ((bool) $disable_non_native_modules && Hook::$native_module && count(Hook::$native_module) && !in_array($array['module'], self::$native_module)) {
             continue;
         }
         if (!($moduleInstance = Module::getInstanceByName($array['module']))) {
             continue;
         }
         // Check permissions
         if ($check_exceptions) {
             $exceptions = $moduleInstance->getExceptions($array['id_hook']);
             $controller = Dispatcher::getInstance()->getController();
             if (in_array($controller, $exceptions)) {
                 continue;
             }
             //retro compat of controller names
             $matching_name = array('authentication' => 'auth', 'compare' => 'products-comparison');
             if (isset($matching_name[$controller]) && in_array($matching_name[$controller], $exceptions)) {
                 continue;
             }
             if (Validate::isLoadedObject($context->employee) && !$moduleInstance->getPermission('view', $context->employee)) {
                 continue;
             }
         }
         $hook_callable = false;
         $hook_retro_callable = false;
         // Check whether Billion Themler hook is
         if ($isDesignerHook) {
             foreach ($callableHooks as $name) {
                 $hook_name = $name;
                 $retro_hook_name = Hook::getRetroHookName($hook_name);
                 $hook_callable = is_callable(array($moduleInstance, 'hook' . $hook_name));
                 $hook_retro_callable = is_callable(array($moduleInstance, 'hook' . $retro_hook_name));
                 // modules in layoutPosition Billion Themler hook can be called from $callableHooks (displayLeftColumn etc.)
                 // so we save callable hook name as $hook_name variable and write its output to layoutPosition hook
                 if ($hook_callable || $hook_retro_callable) {
                     break;
                 }
                 // goes to Module::preCall line
             }
         } else {
             // Check which / if method is callable as usual
             $hook_callable = is_callable(array($moduleInstance, 'hook' . $hook_name));
             $hook_retro_callable = is_callable(array($moduleInstance, 'hook' . $retro_hook_name));
         }
         if (($hook_callable || $hook_retro_callable) && Module::preCall($moduleInstance->name)) {
             $hook_args['altern'] = ++$altern;
             // Call hook method
             if ($hook_callable) {
                 $display = $moduleInstance->{'hook' . $hook_name}($hook_args);
             } else {
                 if ($hook_retro_callable) {
                     $display = $moduleInstance->{'hook' . $retro_hook_name}($hook_args);
                 }
             }
             // Billion Themler edit - $array['live_edit'] defines if module can be moved
             // displayTop and displayFooter hooks can be moved too in Billion Themler but it has live_edit = 0 in DB.hook table
             if (!$array_return && Tools::getValue('theme_name') && ($array['live_edit'] || $hook_name == 'displayTop' || $hook_name == 'displayFooter' || $hook_name == 'displayNavigationBar')) {
                 $display = wrapThemlerEdit($display, $moduleInstance, $array['id_hook']);
             }
             $display = addBootstrapColumn($display, $moduleInstance, $hook_name, $count, $index);
             // Live edit
             if (!$array_return && $array['live_edit'] && Tools::isSubmit('live_edit') && Tools::getValue('ad') && Tools::getValue('liveToken') == Tools::getAdminToken('AdminModulesPositions' . (int) Tab::getIdFromClassName('AdminModulesPositions') . (int) Tools::getValue('id_employee'))) {
                 // We should used in Live Edit mode native PrestaShop hooks only not Billion Themler ones
                 // That's why we remember $source_hook_name and check it
                 if ($isDesignerHook && !in_array($source_hook_name, $callableHooks)) {
                     $output .= $display;
                 } else {
                     $live_edit = true;
                     $output .= self::wrapLiveEdit($display, $moduleInstance, $array['id_hook']);
                 }
             } else {
                 if ($array_return) {
                     $output[$moduleInstance->name] = $display;
                 } else {
                     $output .= $display;
                 }
             }
         }
     }
     if ($array_return) {
         return $output;
     } else {
         return ($live_edit ? '<script type="text/javascript">hooks_list.push(\'' . $hook_name . '\'); </script>
             <div id="' . $hook_name . '" class="dndHook" style="min-height:50px">' : '') . $output . ($live_edit ? '</div>' : '');
         // Return html string
     }
 }
 public function setTemplate($default_template)
 {
     require_once dirname(__FILE__) . '../../../../modules/designerpreview/defines.inc.php';
     $preview_template = str_replace(_PS_THEME_DIR_, getThemeDir(), $default_template);
     parent::setTemplate($preview_template);
 }
 /**
  * Combine Compress and Cache (ccc) JS calls
  *
  * @param array js_files
  * @return array processed js_files
  */
 public static function cccJS($js_files)
 {
     require_once dirname(__FILE__) . '../../../modules/designerpreview/defines.inc.php';
     //inits
     $compressed_js_files_not_found = array();
     $js_files_infos = array();
     $js_files_date = 0;
     $compressed_js_filename = '';
     $js_external_files = array();
     $protocol_link = Tools::getCurrentUrlProtocolPrefix();
     // get js files infos
     foreach ($js_files as $filename) {
         $expr = explode(':', $filename);
         if ($expr[0] == 'http') {
             $js_external_files[] = $filename;
         } else {
             $infos = array();
             $infos['uri'] = $filename;
             $url_data = parse_url($filename);
             $infos['path'] = _PS_ROOT_DIR_ . Tools::str_replace_once(__PS_BASE_URI__, '/', $url_data['path']);
             $js_files_infos[] = $infos;
             $js_files_date = max(file_exists($infos['path']) ? filemtime($infos['path']) : 0, $js_files_date);
             $compressed_js_filename .= $filename;
         }
     }
     // get compressed js file infos
     $compressed_js_filename = md5($compressed_js_filename);
     $compressed_js_path = getThemeDir() . 'cache/' . $compressed_js_filename . '.js';
     $compressed_js_file_date = file_exists($compressed_js_path) ? filemtime($compressed_js_path) : 0;
     // aggregate and compress js files content, write new caches files
     if ($js_files_date > $compressed_js_file_date) {
         $content = '';
         foreach ($js_files_infos as $file_infos) {
             if (file_exists($file_infos['path'])) {
                 $content .= file_get_contents($file_infos['path']) . ';';
             } else {
                 $compressed_js_files_not_found[] = $file_infos['path'];
             }
         }
         $content = Media::packJS($content);
         if (!empty($compressed_js_files_not_found)) {
             $content = '/* WARNING ! file(s) not found : "' . implode(',', $compressed_js_files_not_found) . '" */' . "\n" . $content;
         }
         file_put_contents($compressed_js_path, $content);
         chmod($compressed_js_path, 0777);
     }
     // rebuild the original js_files array
     $url = str_replace(_PS_ROOT_DIR_ . '/', __PS_BASE_URI__, $compressed_js_path);
     return array_merge(array($protocol_link . Tools::getMediaServer($url) . $url), $js_external_files);
 }
function getTemplateVars()
{
    $vars = array();
    $controllers = getTemplateControllers();
    foreach (Theme::getAvailable(false) as $themeName) {
        $themeDir = getThemeDir($themeName);
        $path = $themeDir . '/templates/templates.php';
        if (file_exists($path)) {
            require_once $path;
        }
        foreach ($controllers as $type => $controller) {
            $name = getTemplateName($themeName, $type);
            $value = Configuration::get($name, false);
            if (!$value && isset($templates)) {
                // template settings has not been saved to database yet or it's preview theme
                foreach ($templates[$type] as $t) {
                    if (isset($t['name']) && $t['name'] == $type) {
                        $value = $type . '_' . $t['id'];
                    }
                }
            }
            if ($value) {
                $c = strtolower($controller);
                $vars[$themeName][$c] = $value;
            }
        }
    }
    return $vars;
}
function uploadFile($themeName, $filename, $tmp_path)
{
    $themeDir = FilesHelper::normalizePath(getThemeDir($themeName));
    $previewThemeDir = FilesHelper::normalizePath(getThemeDir($themeName . _PREVIEW_SUFFIX_));
    $base_dir = $previewThemeDir . '/img';
    $base_path = $base_dir . '/' . $filename;
    FilesHelper::deleteFile($base_path);
    FilesHelper::createDir($base_dir);
    FilesHelper::renameFile($tmp_path, $base_path);
    $changed_files = getPreviewChangedFiles($themeDir);
    $changed_files[] = $base_path;
    setPreviewChangedFiles($themeDir, $previewThemeDir, $changed_files);
    return array('status' => 'done', 'url' => Designer::getBaseUrlWithLastSlash() . 'themes/' . $themeName . '_preview/img/' . $filename);
}
 public static function cccJS($js_files)
 {
     require_once dirname(__FILE__) . '../../../modules/designerpreview/defines.inc.php';
     $theme_dir = getThemeDir();
     //inits
     $compressed_js_files_not_found = array();
     $js_files_infos = array();
     $js_files_date = 0;
     $compressed_js_filename = '';
     $js_external_files = array();
     $protocol_link = Tools::getCurrentUrlProtocolPrefix();
     $cache_path = $theme_dir . 'cache/';
     // get js files infos
     foreach ($js_files as $filename) {
         if (Validate::isAbsoluteUrl($filename)) {
             $js_external_files[] = $filename;
         } else {
             $infos = array();
             $infos['uri'] = $filename;
             $url_data = parse_url($filename);
             $infos['path'] = _PS_ROOT_DIR_ . Tools::str_replace_once(__PS_BASE_URI__, '/', $url_data['path']);
             $js_files_infos[] = $infos;
             $js_files_date = max(file_exists($infos['path']) ? @filemtime($infos['path']) : 0, $js_files_date);
             $compressed_js_filename .= $filename;
         }
     }
     // get compressed js file infos
     $compressed_js_filename = md5($compressed_js_filename);
     $version = (int) Configuration::get('PS_CCCJS_VERSION');
     $compressed_js_path = $cache_path . 'v_' . $version . '_' . $compressed_js_filename . '.js';
     $compressed_js_file_date = file_exists($compressed_js_path) ? @filemtime($compressed_js_path) : 0;
     // aggregate and compress js files content, write new caches files
     if ($js_files_date > $compressed_js_file_date) {
         if ($compressed_js_file_date) {
             Configuration::updateValue('PS_CCCJS_VERSION', ++$version);
         }
         $compressed_js_path = $cache_path . 'v_' . $version . '_' . $compressed_js_filename . '.js';
         $content = '';
         foreach ($js_files_infos as $file_infos) {
             if (file_exists($file_infos['path'])) {
                 $tmp_content = file_get_contents($file_infos['path']);
                 if (preg_match('@\\.(min|pack)\\.[^/]+$@', $file_infos['path'], $matches)) {
                     $content .= preg_replace('/\\/\\/@\\ssourceMappingURL\\=[_a-zA-Z0-9-.]+\\.' . $matches[1] . '\\.map\\s+/', '', $tmp_content);
                 } else {
                     $content .= Media::packJS($tmp_content);
                 }
             } else {
                 $compressed_js_files_not_found[] = $file_infos['path'];
             }
         }
         if (!empty($compressed_js_files_not_found)) {
             $content = '/* WARNING ! file(s) not found : "' . implode(',', $compressed_js_files_not_found) . '" */' . "\n" . $content;
         }
         file_put_contents($compressed_js_path, $content);
         chmod($compressed_js_path, 0777);
     }
     // rebuild the original js_files array
     $url = str_replace(_PS_ROOT_DIR_ . '/', __PS_BASE_URI__, $compressed_js_path);
     return array_merge(array($protocol_link . Tools::getMediaServer($url) . $url), $js_external_files);
 }
 public function canRename($newThemeName)
 {
     $result = $this->validate($newThemeName);
     if ($result['message']) {
         return $result;
     }
     if (file_exists(FilesHelper::normalizePath(getThemeDir($newThemeName)))) {
         $result['message'] = 'Theme with such name already exists';
     }
     return $result;
 }
 private function _checkPermissions($themeName)
 {
     $themeDir = FilesHelper::normalizePath(getThemeDir($themeName));
     $previewDir = $themeDir . _PREVIEW_SUFFIX_;
     $dirs = array(_PS_OVERRIDE_DIR_, _PS_DOWNLOAD_DIR_, _PS_MODULE_DIR_, _PS_UPLOAD_DIR_, $themeDir, $previewDir);
     foreach ($dirs as $dir) {
         $rootOnly = strpos($dir, '/themes/') === FALSE;
         // check themes subdirectories only
         $check = FilesHelper::checkFiles($dir, true, true, $rootOnly);
     }
     return true;
 }