<![CDATA[ CDN plugin; use CDN images automatically - My Forums]]> https://forums.modx.com/thread/?thread=18785 <![CDATA[Re: CDN plugin; use CDN images automatically]]> https://forums.modx.com/thread/18785/cdn-plugin-use-cdn-images-automatically#dis-post-102936 jeroenkenters Jul 21, 2011, 04:05 AM https://forums.modx.com/thread/18785/cdn-plugin-use-cdn-images-automatically#dis-post-102936 <![CDATA[Re: CDN plugin; use CDN images automatically]]> https://forums.modx.com/thread/18785/cdn-plugin-use-cdn-images-automatically#dis-post-102935
this plugin is for Revolution, right?

thanks, j]]>
anonymized-26931 Jul 20, 2011, 01:55 PM https://forums.modx.com/thread/18785/cdn-plugin-use-cdn-images-automatically#dis-post-102935
<![CDATA[CDN plugin; use CDN images automatically]]> https://forums.modx.com/thread/18785/cdn-plugin-use-cdn-images-automatically#dis-post-102934
Disclaimer
Use this at your own risk; this is just a first attempt to write a CDN URL plugin. There will most likely be bugs, but so far it’s working great for me. Code is still a bit messy though; could use some cleanup.

How does it work?
- The plugin is fired just before the page is rendered (OnWebPagePrerender event)
- Every local image (whether inside img, a or input tag) on the page is checked for existence on the CDN
- If a CDN version exists the image URL (src) is replaced by a CDN URL
- The CDN URL is also cached so that it will always be the same (prevents too much checking as well)
- If a CDN version does not exist, the local image is used

<?php
class CDN {

    var $cdn; //array of CDN hostnames
    var $cdncache = array(); //files already checked to be on CDN

    function __construct($output, &$modx) {
        $this->modx = $modx;

        $this->cdn = array('http://cdna.kenters.com', 'http://cdnb.kenters.com', 'http://cdnc.kenters.com', 'http://cdnd.kenters.com');

        //get cached images
        $this->cdncache = $this->modx->cacheManager->get('cdncache');
        if(!is_array($this->cdncache)) {
            $this->cdncache = array();
        }
    }

    function process($output) {

        $output = preg_replace_callback('|<img(?:.+?)src\=\"(\S+)\"|', array($this ,'doCDN'), $output);
        $output = preg_replace_callback('|<input(?:.+?)src\=\"(\S+)\"|', array($this ,'doCDN'), $output);
        $output = preg_replace_callback('|<a(?:.+?)href\=\"(\S+)\"|', array($this ,'doCDN'), $output);
        $this->modx->cacheManager->set('cdncache', $this->cdncache,7200);

        return $output;
    }

    function doCDN($match) {
      //only process local images
      if( (!stripos($match[1], '.jpg') && !stripos($match[1], '.png') && !stripos($match[1], '.gif') || stripos($match[1], 'http://') !== false || stripos($match[1], 'https://') !==false || stripos($match[1], 'mailto:') !== false) )
      {
          return $match[0];
      }
      else
      {
          $replace = $match[1]; //text to replace

          if(array_key_exists($replace, $this->cdncache)) {
              $replaced = $this->cdncache[$replace];
              return str_replace($replace, $replaced, $match[0]);
          }
          else {
                $replaced = $this->cdn[array_rand($this->cdn)].( substr($match[1], 0, 1) == '/' ? '' : '/' ).$match[1]; //replaced url
                if(  $this->url_validate($replaced) ) {
                    $this->cdncache[$replace] = $replaced; //add to cache
                    return str_replace($replace, $replaced, $match[0]);
                }
                else {
                    return $match[0];
                }
          }
      }
    }

    function url_validate( $link )
    {
        $url_parts = @parse_url( $link );

        if ( empty( $url_parts["host"] ) ) return( false );

        if ( !empty( $url_parts["path"] ) )
        {
            $documentpath = $url_parts["path"];
        }
        else
        {
            $documentpath = "/";
        }

        if ( !empty( $url_parts["query"] ) )
        {
            $documentpath .= "?" . $url_parts["query"];
        }

        $host = $url_parts["host"];
        $port = $url_parts["port"];

        if (empty( $port ) ) $port = "80";
        $socket = fsockopen( $host, $port, $errno, $errstr, 30 );
        if (!$socket)
        {
            return(false);
        }
        else
        {
            fwrite ($socket, "HEAD ".$documentpath." HTTP/1.0\r\nHost: $host\r\n\r\n");
            $http_response = fgets( $socket, 22 );

            if ( stripos($http_response, "200 OK") )
            {
                return(true);
                fclose( $socket );
            } else
            {
                return(false);
            }
        }
    }
}

$output = &$modx->resource->_output;
$cdn = new CDN($output, $modx);
$output = $cdn->process($output);
]]>
jeroenkenters May 26, 2011, 09:42 AM https://forums.modx.com/thread/18785/cdn-plugin-use-cdn-images-automatically#dis-post-102934