Wordpress Hack » Reading MySQL username & password from wp-config.php

A few months ago I was working on a prototype Wordpress plug-in that generated graphs using GNUPlot. To do this it had another script embedded at the end of the file which dumped data from the Wordpress database and produced graphs as images for the output.

The problem is that the GNUPlot section of the script is referred to directly my an "img" XHTML tag and is not loaded by Wordpress itself; it does not have access to the Wordpress database configuration.

To workaround this I wrote the following section of code, it opens the "wp-config.php" file and parses out anything matching the pattern "define( name, value )" into a $config variable. Immediately afterwards it attempts to connect to MySQL using these details.

Bit of a hack, but it was the only nice way I could see to do it and keep the plug-in simple & configuration free.

PHP:
  1. $config = array();
  2.    
  3.    // HACK Read wp-config.php for the Database username/password, including it wouldnt work
  4.    $handle = fopen( "../../wp-config.php", "r" );
  5.    if ( $handle ) {
  6.       $content = '';
  7.       while ( !feof($handle) ) {
  8.          $content .= fread( $handle, 1024 );
  9.       }
  10.       fclose( $handle );
  11.       if ( preg_match_all("/define\s*\(\s*'(.*?)'\s*,\s*'(.*?)'\s*\);/", $content, $matches, PREG_SET_ORDER) ) {
  12.          for ( $i = 0; $i <count($matches); $i++ ) {
  13.             $name = $matches[$i][1]; $value = $matches[$i][2];
  14.             $config[$name] = $value;
  15.          }
  16.       }
  17.    }
  18.  
  19.    
  20.    $link = mysql_connect( $config['DB_HOST'], $config['DB_USER'], $config['DB_PASSWORD']) or die ("Can't connect!");
  21.    mysql_select_db( $config['DB_NAME'] ) or die("Can't select database!");

Experimenting with Googlebot

In my previous post 'Blogs are fundamentally flawed…' I noted an observation that more often than not search results would direct a user to an index-style page containing the post instead of directly to the 'permalink' location of the post. This leads to a poor user-experience from the visitor’s point of view, on busy blogs the post has almost certainly moved since the page was spider'd. Google in particular appeared to be the worst for it.

Discussions on the subject with Gerry determined that this is most likely down to Google's PageRank technology; where index-style pages have a higher value than the post pages themselves. To get around this he suggested manipulating 'robots.txt' directives within the index-style pages.

On Google's "Information for Webmasters" help page I found they look for special 'robots.txt' directives and meta tags in documents when spidering specific to Googlebot only. This meant I could single out Googlebot for these directives and not affect other search engines (which don’t exhibit the problem so much).

I basically want Google to 'FOLLOW' links on all pages, but not to 'INDEX' the index-style pages like categories & archives by date. The desired effect being that Google can find all posts as before but simply ignore the index-style pages themselves. Implementing this is quite simple; I modified my theme's "header.php" file inserting the following code in the "head" section:

PHP:
  1. <?php
  2.     if ( !is_single() && !is_page() && !is_home() )
  3.         echo "  <meta name=\"GOOGLEBOT\" content=\"NOINDEX,FOLLOW\" />\n";
  4. ?>

This reads almost literally, if this is not a single post view, not a page view or the home page, add the following "meta..." tag. Although the home page is an index-style page I am reluctant to add 'NOINDEX' because I don't want it disappearing from search results. ;)

Now the long wait for the changes to reflect in Google's results.

Updated 24th January 2006 - Gerry pointed out this can be optimised using De Morgan's Law :P

PHP:
  1. <?php
  2.     if ( ! (is_single() || is_page() || is_home()) )
  3.         echo "  <meta name=\"GOOGLEBOT\" content=\"NOINDEX,FOLLOW\" />\n";
  4. ?>

Wordpress Hack » Inserting rel nofollow on links in all categories…

I wanted to add rel='external nofollow' onto every Link in every Category that didn't have an explicit rel attribute defined. I looked though the Wordpress Codex but found no Plugin Hooks to do it so I broke out the source code.

Somewhere down the chain the link markup "<a ..." is generated in the function get_links() found in /wp-include/links.php (approx line 142). I added two lines of code shown below and it works a treat.

Before

PHP:
  1. $rel = $row->link_rel;
  2.        
  3. if ($rel != '') {
  4.     $rel = " rel='$rel'";
  5. }

After

PHP:
  1. $rel = $row->link_rel;
  2.        
  3. if ($rel != '') {
  4.     $rel = " rel='$rel'";
  5. } else {
  6.     $rel = " rel='external nofollow'";
  7. }