Handle sites/default/files redirect in Drupal 6 with Custom Errors module

When I’ve migrated sites into Aegir recently, I find that the users have many links in the content hard-coded to files in the default directory.
While it is possible to use the Scanner search & replace module to ferret those out. It’s not always thorough enough. For example, it doesn’t search and replace menu link urls, or content in blocks, views, headers, footers or custom fields. You can specify custom fields and locations to search but that’s another bag of worms that fraught with issues.
So I wanted to find a simple way to catch any hard coded links that I missed.
Enter the Custom Error module.

I’ve been using it to provide a populated search form on the 404 ‘Not found’ page as well as a site map but I also have a few custom redirects in there so adding an option for sites/default/files was simple.

Here’s the code:

<?php
//Handle specific redirects
$newLink='';
$path = $_REQUEST['destination'];
if (!empty($path)) {
  $path = str_replace(" ", "%20", $path);

  if(preg_match('/sites/default/files/.*/i',$path,$matches)){
    ### /sites/default/files/... ###
    $newPath = preg_replace('/sites/default/files/', file_directory_path() , $path);
    $protocol = strtolower(substr($_SERVER['SERVER_PROTOCOL'], 0, strpos($_SERVER['SERVER_PROTOCOL'], "/", 0)));

    $newLink = $protocol.'://'.$_SERVER['HTTP_HOST'] . base_path() . $newPath;
    Header( "HTTP/1.1 301 Moved Permanently" );
    Header( "Location: $newLink" );
    #JS fall back. Comment out header if you wish to use JS only
    drupal_add_js("
    Drupal.behaviors.redirectThis = function(context) {
      function redirectThis() {
        location.href='$newLink';
        $(&#039;#redirectText&#039;).html(&#039;<br />We'll attempt to redirect you now.');
      }
      redirectThis();
    }", 'inline');
    echo 'We're you looking for: '.l('this: ('.str_replace('http://','',$newLink).')',$newLink).'<span></span>';
  }//end if sites/default/files
}//end if (!empty($path))
?&gt;

It’s simple and it works!
Here it is again commented out:

&lt;?php
//Handle specific redirects
$newLink=&#039;&#039;;  #(re)Set the newLink var to an empty value.
$path = $_REQUEST[&#039;destination&#039;];  #grab the &#039;not found&#039; url from the request destination var
if (!empty($path)) {   #Only attempt to redirect if the path exists
  $path = str_replace(&quot; &quot;, &quot;%20&quot;, $path);   #put in ASCII for spaces to accommodate files names.

  if(preg_match(&#039;/sites/default/files/.*/i&#039;,$path,$matches)){  #Do a regexp search on the path for &#039;sites/default/files&#039; if a match is found then continue
    ### /sites/default/files/... ###
    $newPath = preg_replace(&#039;/sites/default/files/&#039;, file_directory_path() , $path);  #Replace &#039;sites/default/files&#039; with the variable &quot;file_directory_path()&quot; *NOTE: this may be different in D7
    #Start to build the redirect link
    $protocol = strtolower(substr($_SERVER[&#039;SERVER_PROTOCOL&#039;], 0, strpos($_SERVER[&#039;SERVER_PROTOCOL&#039;], &quot;/&quot;, 0)));   #Get the protocol: http or https

    $newLink = $protocol.&#039;://&#039;.$_SERVER[&#039;HTTP_HOST&#039;] . base_path() . $newPath;   #Build the new link: protocol + :// + http_host + drupal site base_path() + $newPath
    Header( &quot;HTTP/1.1 301 Moved Permanently&quot; );  #Prepare php to redirect using a header request
    Header( &quot;Location: $newLink&quot; );  #Redirect
    #JS fall back. Comment out header if you wish to use JS only
    drupal_add_js(&quot;    #Add js to a page in drupal
    Drupal.behaviors.redirectThis = function(context) {   #This is the syntax to create a function that works in Drupal nodes
      function redirectThis() {  #Function name
        location.href=&#039;$newLink&#039;;  #Set location and redirect
        $(&#039;#redirectText&#039;).html(&#039;<br />We'll attempt to redirect you now.');   #add redirect text
      }
      redirectThis();   #call the function
    }", 'inline');   #The 'inline' value places the above input into the page header.
    echo 'We're you looking for: '.l('this: ('.str_replace('http://','',$newLink).')',$newLink).'<span></span>';   #Add some content to the page in case the use has no js
  }//end if sites/default/files
}//end if (!empty($path))
?&gt;

Hope that clears that up.
If you’re good about checking your error logs then you’ll probably be fixing 404’s anyway but in the interim we don’t need to worry about this one.

Leave a Comment