Jump to content

Auto-Versioning CSS Files (force CSS refresh)


Recommended Posts

Hey,

 

I've found it a bit frustrating that Prestashop doesn't have a way to force users cache to refresh if I've made a CSS change (deleting the cache in themes/cache or smarty/compile, smarty/cache doesn't seem to refresh your CSS) so I've written some code here that will automatically add a version number to your CSS everytime you update it and thus, forcing the user's browser to download a new version of the file if it has been updated since their last time on your site.

 

It involves:

 

1. Creating a new function (autoVer()) that adds a version number onto the end of your CSS file based on the last modified date.

2. Overriding Tools::addCSS() to make a call to that new autoVer() function. The addCSS function only has a change in 1 line (indicated by comments in the code).

 

Use it at your own risk and let me know if you find any places for improvement :)

 

override/Tools.php

 

//credit: http://particletree.com/notebook/automatically-version-your-css-and-javascript-files/
public static function autoVer($url){
$path = pathinfo($url);

if(file_exists($_SERVER['DOCUMENT_ROOT'].$url))
	$ver = filemtime($_SERVER['DOCUMENT_ROOT'].$url);
else
	$ver = '1';
return $path['dirname'].'/'.$path['basename'].'?v='.$ver;
}

public static function addCSS($css_uri, $css_media_type = 'all')
{
	global $css_files;
	if (is_array($css_uri))
	{
			foreach ($css_uri as $file => $media_type)
					self::addCSS($file, $media_type);
			return true;
	}
	//overriding of modules css files
	$different = 0;
	$override_path = str_replace(__PS_BASE_URI__.'modules/', _PS_ROOT_DIR_.'/themes/'._THEME_NAME_.'/css/modules/', $css_uri, $different);
	if ($different && file_exists($override_path))
			$css_uri = str_replace(__PS_BASE_URI__.'modules/', __PS_BASE_URI__.'themes/'._THEME_NAME_.'/css/modules/', $css_uri, $different);
	else
	{
			// remove PS_BASE_URI on _PS_ROOT_DIR_ for the following
			$url_data = parse_url($css_uri);
			$file_uri = _PS_ROOT_DIR_.self::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']);
			// check if css files exists
			if (!file_exists($file_uri))
					return true;
	}
	// detect mass add
	$css_uri = array(Tools::autoVer($css_uri) => $css_media_type);//This is the only line that has been changed to add in the call to the new autoVer function we created above.
	// adding file to the big array...
	if (is_array($css_files))
			$css_files = array_merge($css_files, $css_uri);
	else
			$css_files = $css_uri;
	return true;
}

  • Like 1
Link to comment
Share on other sites

  • 7 months later...
  • 6 months later...
  • 8 months later...

Thank you for this post. That's really helped me. For my case i'm using prestashop 1.5.4.1 and modified to files:

 

1- Tools.php:

        In that file i added the new function "autoVer"

 

2- Media.php

       In that file i modified the ruturn statement of the getCSSPath function to write this

          return array(Tools::autoVer($css_uri) => $css_media_type);

 

 

 

 

Link to comment
Share on other sites

  • 1 year later...

I am using PS 1.6.0.9 and did exactly as knfaly mentioned above and i guess it's working, thanks!!! So the piece of code below is really unnecessary and i don't need to use it???

 

 

 

 

public static function addCSS($css_uri, $css_media_type = 'all')

{

        global $css_files;

        if (is_array($css_uri))

        {

                foreach ($css_uri as $file => $media_type)

                        self::addCSS($file, $media_type);

                return true;

        }

        //overriding of modules css files

        $different = 0;

        $override_path = str_replace(__PS_BASE_URI__.'modules/', _PS_ROOT_DIR_.'/themes/'._THEME_NAME_.'/css/modules/', $css_uri, $different);

        if ($different && file_exists($override_path))

                $css_uri = str_replace(__PS_BASE_URI__.'modules/', __PS_BASE_URI__.'themes/'._THEME_NAME_.'/css/modules/', $css_uri, $different);

        else

        {

                // remove PS_BASE_URI on _PS_ROOT_DIR_ for the following

                $url_data = parse_url($css_uri);

                $file_uri = _PS_ROOT_DIR_.self::str_replace_once(__PS_BASE_URI__, DIRECTORY_SEPARATOR, $url_data['path']);

                // check if css files exists

                if (!file_exists($file_uri))

                        return true;

        }

        // detect mass add

        $css_uri = array(Tools::autoVer($css_uri) => $css_media_type);//This is the only line that has been changed to add in the call to the new autoVer function we created above.

        // adding file to the big array...

        if (is_array($css_files))

                $css_files = array_merge($css_files, $css_uri);

        else

                $css_files = $css_uri;

        return true;

}
Link to comment
Share on other sites

  • 2 years later...

Thanks for pointing me in the right direction.

I have 1.6.1.6 installed and I implemented your idea by adding the override file: override/classes/Media.php with the following content:

class Media extends MediaCore

{

  public static function getCSSPath($css_uri, $css_media_type = 'all', $need_rtl = true)

  {

    $css = parent::getCSSPath($css_uri, $css_media_type, $need_rtl);

    if (is_array($css)) {

      $url = key($css);

      $media = $css[$url];

      if (file_exists($_SERVER['DOCUMENT_ROOT'] . $url)) {

        $ver = filemtime($_SERVER['DOCUMENT_ROOT'] . $url);

      } else {

        $ver = '1';

      }

      $css = array($url .'?v='.$ver => $media);

    }

    return $css;

  }

}
Edited by savedario (see edit history)
Link to comment
Share on other sites

  • 1 year later...
  • 1 year later...
  • 3 months later...
On 9/4/2013 at 12:00 AM, knfaly said:

Thank you for this post. That's really helped me. For my case i'm using prestashop 1.5.4.1 and modified to files:

 

1- Tools.php:

        In that file i added the new function "autoVer"

 

2- Media.php

       In that file i modified the ruturn statement of the getCSSPath function to write this

          return array(Tools::autoVer($css_uri) => $css_media_type);

 

 

 

 

I'm still using prestashop 1.5.6 and you just solved a problem I had years ago. Thank you very much

Link to comment
Share on other sites

  • 2 months later...
  • 1 year later...
On 5/18/2017 at 2:28 PM, savedario said:

Thanks for pointing me in the right direction.

I have 1.6.1.6 installed and I implemented your idea by adding the override file: override/classes/Media.php with the following content:

class Media extends MediaCore

{

  public static function getCSSPath($css_uri, $css_media_type = 'all', $need_rtl = true)

  {

    $css = parent::getCSSPath($css_uri, $css_media_type, $need_rtl);

    if (is_array($css)) {

      $url = key($css);

      $media = $css[$url];

      if (file_exists($_SERVER['DOCUMENT_ROOT'] . $url)) {

        $ver = filemtime($_SERVER['DOCUMENT_ROOT'] . $url);

      } else {

        $ver = '1';

      }

      $css = array($url .'?v='.$ver => $media);

    }

    return $css;

  }

}

Thanks, it is working. What about javascript? 

Link to comment
Share on other sites

  • 5 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...