示例#1
0
 /**
  * This method installs language values stored at so-named "Crowdin-pack directory".
  * The directory should have the following structure:
  *
  * /
  *  /core.po - Core language values. Required.
  *  /editions - Stores edition-specific *.po files. Optional.
  *    /mve.po - Multivendor-specific file.
  *  /addons - Stores add-ons' *.po files. Optional.
  *    /banners.po
  *    /bestsellers.po
  *    /{addon name}.po
  *
  * This methods collects relevant *.po files from given directory and executes {@see Tygh\Languages\Languages::installLanguagePack()} method for each one.
  * "Relevant" means that only installed addons' po-files would be installed as well as mve.po will be installed only for Multivendor edition.
  *
  * @see Tygh\Languages\Languages::installLanguagePack()
  *
  * @param string $path   Path to directory that contains .po files (i.e. PO-pack directory)
  * @param array  $params Parameters passed to {@see Tygh\Languages\Languages::installLanguagePack()} function.
  *
  * @return bool|int (bool) false on failure, (bool) true on success or (int) ID of newly created language (if it was created successfully).
  */
 public static function installCrowdinPack($path, $params)
 {
     $path = rtrim($path, '\\/') . '/';
     $lang_meta = self::getLangPacksMeta($path, 'core.po', true);
     if (empty($lang_meta)) {
         $result = false;
     } else {
         fn_copy($path, Registry::get('config.dir.lang_packs') . $lang_meta['lang_code'] . '/');
         $path = Registry::get('config.dir.lang_packs') . $lang_meta['lang_code'] . '/';
         $result = self::installLanguagePack($path . 'core.po', $params);
     }
     if ($result) {
         $po_files_list = array();
         if (fn_allowed_for('MULTIVENDOR') && file_exists($path . 'editions/mve.po')) {
             $po_files_list[] = $path . 'editions/mve.po';
         }
         list($addons) = fn_get_addons(array('type' => 'installed'));
         foreach ($addons as $addon_id => $addon) {
             if (file_exists($path . 'addons/' . $addon_id . '.po')) {
                 $po_files_list[] = $path . 'addons/' . $addon_id . '.po';
             }
         }
         $params['reinstall'] = true;
         foreach ($po_files_list as $po_file) {
             $minor_result = self::installLanguagePack($po_file, $params);
             if (!$minor_result) {
                 $result = false;
                 break;
             }
         }
     }
     return $result;
 }
示例#2
0
/**
 * 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;
}
示例#3
0
 /**
  * Get theme CSS files list
  *
  * @return array CSS files list
  */
 public function getCssFilesList()
 {
     $from = $this->theme_path . '/css';
     $exclude = array('addons', self::$less_backup_dirname, self::$css_backup_dirname);
     $css_files = fn_get_dir_contents($from, false, true, '.css', '', true, $exclude);
     list($active_addons) = fn_get_addons(array('type' => 'active'));
     foreach ($active_addons as $addon_name => $addon) {
         $css_files = array_merge($css_files, fn_get_dir_contents($from . "/addons/{$addon_name}", false, true, '.css', "addons/{$addon_name}/", true));
     }
     return $css_files;
 }
示例#4
0
 public static function installCrowdinPack($path, $params)
 {
     $path = fn_remove_trailing_slash($path) . '/';
     if (file_exists($path . 'core.po') && is_dir($path . 'addons') && is_dir($path . 'editions')) {
         $lang_meta = self::getLangPacksMeta($path, 'core.po', true);
         if (empty($lang_meta['lang_code'])) {
             $result = false;
             fn_set_notification('E', __('error'), __('broken_po_pack'));
         } else {
             fn_copy($path, Registry::get('config.dir.lang_packs') . $lang_meta['lang_code'] . '/');
             $path = Registry::get('config.dir.lang_packs') . $lang_meta['lang_code'] . '/';
             $result = self::installLanguagePack($path . 'core.po', $params);
         }
         if ($result) {
             $po_files_list = array();
             if (fn_allowed_for('MULTIVENDOR') && file_exists($path . 'editions/mve.po')) {
                 $po_files_list[] = $path . 'editions/mve.po';
             }
             list($addons) = fn_get_addons(array('type' => 'installed'));
             foreach ($addons as $addon_id => $addon) {
                 if (file_exists($path . 'addons/' . $addon_id . '.po')) {
                     $po_files_list[] = $path . 'addons/' . $addon_id . '.po';
                 }
             }
             foreach ($po_files_list as $po_file) {
                 $result = self::installLanguagePack($po_file, array('reinstall' => true));
                 if (!$result) {
                     break;
                 }
             }
         }
     } else {
         fn_set_notification('E', __('error'), __('broken_po_pack'));
         return false;
     }
     return true;
 }
示例#5
0
        Registry::clearCachedKeyValues();
    }
    if ($mode == 'uninstall') {
        fn_uninstall_addon($_REQUEST['addon']);
    }
    return array(CONTROLLER_STATUS_OK, 'addons.manage');
}
if ($mode == 'update') {
    $addon_name = addslashes($_REQUEST['addon']);
    $section = Settings::instance()->getSectionByName($_REQUEST['addon'], Settings::ADDON_SECTION);
    if (empty($section)) {
        return array(CONTROLLER_STATUS_NO_PAGE);
    }
    $subsections = Settings::instance()->getSectionTabs($section['section_id'], CART_LANGUAGE);
    $options = Settings::instance()->getList($section['section_id']);
    fn_update_lang_objects('sections', $subsections);
    fn_update_lang_objects('options', $options);
    Tygh::$app['view']->assign('options', $options);
    Tygh::$app['view']->assign('subsections', $subsections);
    $addon = db_get_row('SELECT a.addon, a.status, b.name as name, b.description as description, a.separate ' . 'FROM ?:addons as a LEFT JOIN ?:addon_descriptions as b ON b.addon = a.addon AND b.lang_code = ?s WHERE a.addon = ?s' . 'ORDER BY b.name ASC', CART_LANGUAGE, $_REQUEST['addon']);
    if ($addon['separate'] == true || !defined('AJAX_REQUEST')) {
        Tygh::$app['view']->assign('separate', true);
        Tygh::$app['view']->assign('addon_name', $addon['name']);
    }
} elseif ($mode == 'manage') {
    $params = $_REQUEST;
    $params['for_company'] = (bool) Registry::get('runtime.company_id');
    list($addons, $search) = fn_get_addons($params);
    Tygh::$app['view']->assign('search', $search);
    Tygh::$app['view']->assign('addons_list', $addons);
}