AlexandrX
AlexandrX

Reputation: 838

Is there a way to override any of /js/*.js files?

I know there are the ways to override module's js/css/tpl and other files, but I cant find a way to override, for example, the /js/validate.js file. I've tried to place my own file to /themes/my-theme/js folder, but I cant see a result (validate.js is still loaded from /js/ folder).

Is there a way to do this?

Upvotes: 3

Views: 2789

Answers (1)

Florian Lemaitre
Florian Lemaitre

Reputation: 5748

There is no built-in functionality to do this.

But you can override the method addMedia of FrontController.

Create this file /override/classes/controller/FrontController.php:

<?php
class FrontController extends FrontControllerCore
{
    /**
     * Adds a media file(s) (CSS, JS) to page header
     *
     * @param string|array $media_uri Path to file, or an array of paths like: array(array(uri => media_type), ...)
     * @param string|null $css_media_type CSS media type
     * @param int|null $offset
     * @param bool $remove If True, removes media files
     * @param bool $check_path If true, checks if files exists
     * @return true|void
     */
    public function addMedia($media_uri, $css_media_type = null, $offset = null, $remove = false, $check_path = true)
    {
        if (!is_array($media_uri)) {
            if ($css_media_type) {
                $media_uri = array($media_uri => $css_media_type);
            } else {
                $media_uri = array($media_uri);
            }
        }

        $list_uri = array();
        foreach ($media_uri as $file => $media) {
            if (!Validate::isAbsoluteUrl($media)) {
                $different = 0;
                $different_css = 0;
                $type = 'css';
                if (!$css_media_type) {
                    $type = 'js';
                    $file = $media;
                }
                if (strpos($file, __PS_BASE_URI__.'modules/') === 0) {
                    $override_path = str_replace(__PS_BASE_URI__.'modules/', _PS_ROOT_DIR_.'/themes/'._THEME_NAME_.'/'.$type.'/modules/', $file, $different);
                    if (strrpos($override_path, $type.'/'.basename($file)) !== false) {
                        $override_path_css = str_replace($type.'/'.basename($file), basename($file), $override_path, $different_css);
                    }

                    if ($different && @filemtime($override_path)) {
                        $file = str_replace(__PS_BASE_URI__.'modules/', __PS_BASE_URI__.'themes/'._THEME_NAME_.'/'.$type.'/modules/', $file, $different);
                    } elseif ($different_css && @filemtime($override_path_css)) {
                        $file = $override_path_css;
                    }
                    if ($css_media_type) {
                        $list_uri[$file] = $media;
                    } else {
                        $list_uri[] = $file;
                    }
                // Here we add our test to override default js files
                } elseif (strpos($file, _PS_JS_DIR_) === 0) {
                    $override_path = str_replace(_PS_JS_DIR_, _PS_ROOT_DIR_.'/themes/'._THEME_NAME_.'/js/default/', $file, $different);
                    if (strrpos($override_path, $type.'/'.basename($file)) !== false) {
                        $override_path_css = str_replace($type.'/'.basename($file), basename($file), $override_path, $different_css);
                    }

                    if ($different && @filemtime($override_path)) {
                        $file = str_replace(_PS_JS_DIR_, __PS_BASE_URI__.'themes/'._THEME_NAME_.'/js/default/', $file, $different);
                    } elseif ($different_css && @filemtime($override_path_css)) {
                        $file = $override_path_css;
                    }
                    if ($css_media_type) {
                        $list_uri[$file] = $media;
                    } else {
                        $list_uri[] = $file;
                    }
                } else {
                    $list_uri[$file] = $media;
                }
            } else {
                $list_uri[$file] = $media;
            }
        }

        if ($remove) {
            if ($css_media_type) {
                return parent::removeCSS($list_uri, $css_media_type);
            }
            return parent::removeJS($list_uri);
        }

        if ($css_media_type) {
            return parent::addCSS($list_uri, $css_media_type, $offset, $check_path);
        }

        return parent::addJS($list_uri, $check_path);
    }
}

With this override, you can now create a file /themes/my_theme/js/default/validate.js to override the default /js/validate.js file.

PS: as with any override, you will have to delete the file /cache/class_index.php.

Upvotes: 4

Related Questions