<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel>
<title>Chris Hope's LAMP Blog</title>
<link>http://www.electrictoolbox.com</link>
<description>Chris Hope's blog for Linux, Apache, MySQL and PHP, otherwise known as LAMP.</description>
<lastBuildDate>Thu, 24 May 2012 19:56:52 GMT</lastBuildDate>
<pubDate>Thu, 24 May 2012 19:56:52 GMT</pubDate>
<copyright>http://www.electrictoolbox.com</copyright>

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ElectricToolboxBlog" /><feedburner:info uri="electrictoolboxblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>ElectricToolboxBlog</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
<title>Fix the timezone data on CentOS</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/V7oois9_yHE/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/centos-fix-timezone-data/</guid>
<pubDate>Thu, 17 May 2012 03:30:00 GMT</pubDate>
<description><![CDATA[<p>I've had an annoying issue on some CentOS 5 virtual machines where I set the timezone to Pacific/Auckland and it doesn't work. This post shows the error and then how to rebuild/reinstall the timezone data.</p>]]></description>
<content:encoded><![CDATA[
<p>I've had an annoying issue on some CentOS 5 virtual machines where I set the timezone to Pacific/Auckland and it doesn't work. This post shows the error and then how to rebuild/reinstall the timezone data.</p>
<h2>Changing the timezone</h2>
<p>I wanted to change the timezone from Eastern time to New Zealand time. To highlight how it didn't work the example below shows: the date command, showing the current date, time and timezone; attempting to set the date; and then showing the current date and time again.</p>
<pre class="brush: bash">
$ date
Wed May 16 23:23:23 EDT 2012
$ ln -sf /usr/share/zoneinfo/Pacific/Auckland /etc/localtime
$ date
Wed May 16 23:26:23 EDT 2012</pre>
<p>No, it didn't seem to make any difference. The timezone is still EDT.</p>
<h2>The fix</h2>
<p>It's very easy, simply run &quot;yum reinstall tzdata -y&quot; as root or using sudo. The -y flag at the end simply means you don't need to type y and &lt;enter&gt; when it's time to say yes, you do want to do the reinstall.</p>
<pre class="brush: bash">
$ yum reinstall tzdata -y
... lots of output ...
$ ln -sf /usr/share/zoneinfo/Pacific/Auckland /etc/localtime
$ date
Thu May 17 15:30:42 NZST 2012</pre>
<p>Excellent, now the timezone has changed.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/centos-change-timezone/'>Change the timezone on CentOS</a> (Wednesday, September 14th 2011)</li>
<li><a href='http://www.electrictoolbox.com/debian-5-timezone/'>Set the timezone on Debian 5 Lenny</a> (Thursday, December 30th 2010)</li>
<li><a href='http://www.electrictoolbox.com/daylight-savings-settings-linux/'>Checking daylight savings settings on Linux</a> (Thursday, March 13th 2008)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/Jnl8I4ywuOCR0I6otQvUy2Zj-Mk/0/da"><img src="http://feedads.g.doubleclick.net/~a/Jnl8I4ywuOCR0I6otQvUy2Zj-Mk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Jnl8I4ywuOCR0I6otQvUy2Zj-Mk/1/da"><img src="http://feedads.g.doubleclick.net/~a/Jnl8I4ywuOCR0I6otQvUy2Zj-Mk/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/V7oois9_yHE" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/centos-fix-timezone-data/</feedburner:origLink></item>
<item>
<title>PHP suhosin, sessions and shared SSL certificates</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/RXnlCUUuuNs/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/php-suhosin-sessions-shared-ssl-certificates/</guid>
<pubDate>Wed, 09 May 2012 23:00:00 GMT</pubDate>
<description><![CDATA[<p>There's a patch for PHP called suhosin which is part of the Hardened PHP Project to make PHP more secure. I came across an issue with the way session data is encrypted when using a shared SSL certificate on an old osCommerce install I occasionally have to support.</p>]]></description>
<content:encoded><![CDATA[
<p>There's a patch for PHP called suhosin which is part of the Hardened PHP Project to make PHP more secure. I came across an issue with the way session data is encrypted when using a shared SSL certificate on an old osCommerce install I occasionally have to support.<br />
<br />
Note, this is not an issue with suhosin itself, but an issue with the way data is encrypted when using a shared SSL certificate.</p>
<h2>sushosin session data encryption</h2>
<p>When session data is written/read, sushosin encrypts/decrypts it using a variety of options as the encryption key. Read the <a href="http://www.hardened-php.net/suhosin/configuration.html">configuration page</a> for more details, specifically the <a href="http://www.hardened-php.net/suhosin/configuration.htmltransparent_encryption_options#">Transparent Encryption Options</a> section which also looks at the cookie options.</p>
<p>In particular, suhosin.session.cryptua and suhosin.session.cryptdocroot are enabled by default. There are no issues with the cryptua setting when it comes to shared SSL certificates, just with the cryptdocroot setting, and even then it won't affect all hosting setups depending how shared hosting is configured.</p>
<p>Encrypting the session data is a good thing. Although I imagine it's fairly trivial to decrypt it, at least it offers some immediate protection from someone just browsing the database or session files.</p>
<h2>The issue with shared SSL certificates</h2>
<p>If you have an SSL certificate specifically set up for your website with the same domain name, then there shouldn't be any issues at all with the default settings, because all the variables to do with encryption won't be affected. The document root will be the same regardless of whether it's through SSL or not.</p>
<p>A shared SSL certificate, on the other hand, will most likely have a different document root with the non-SSL and SSL parts of the site. They may even be on different servers.</p>
<p>Let's say the site we are looking at is www.example.com and the SSL portion of the site is at www.secure-example.com/example</p>
<p>The paths to these might be /var/www/example.com and /var/www/secure-example/example</p>
<p>As you can see the document root is different for each, which means the encryption/decryption key will be different for the SSL and non-SSL version of the site using the default settings.</p>
<h2>The solution</h2>
<p>All you need to do to fix this, is to disable the cryptdocroot option. This can be done in the suhosin configuration file, Apache virtualhost or .htaccess.</p>
<p>I prefer to just do this on a site-by-site basis so recommend doing it just in the .htaccess file. Add the following line to it, and then everything should work fine for new sessions:</p>
<p>php_value suhosin.session.cryptdocroot off</p>
<h2>osCommerce notes</h2>
<p>I mentioned I came across this issue with an osCommerce install, which is the only site I support which uses a shared certificate. For the sake of completeness, here's the relevent osCommerce configuration to get cookies/sessions working across shared SSL, using the example domains above:</p>
<pre style="border: 1px #666 solid; padding: 10px; padding-bottom: 1em; overflow: hidden; overflow-x: auto; background: #eeeeee; font-size: 105%;">
define('HTTP_SERVER', 'http://www.example.com');
define('HTTPS_SERVER', 'https://www.secure-example.com/example');
define('ENABLE_SSL', true);
define('HTTP_COOKIE_DOMAIN', 'example.com');
define('HTTPS_COOKIE_DOMAIN', 'www.secure-example.com');
define('HTTP_COOKIE_PATH', '/');
define('HTTPS_COOKIE_PATH', '/example');<br /></pre>
<p><a href="http://feedads.g.doubleclick.net/~a/3enScxR7zRuuEZKEAjU7nQfC0rc/0/da"><img src="http://feedads.g.doubleclick.net/~a/3enScxR7zRuuEZKEAjU7nQfC0rc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/3enScxR7zRuuEZKEAjU7nQfC0rc/1/da"><img src="http://feedads.g.doubleclick.net/~a/3enScxR7zRuuEZKEAjU7nQfC0rc/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/RXnlCUUuuNs" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/php-suhosin-sessions-shared-ssl-certificates/</feedburner:origLink></item>
<item>
<title>Which version of CentOS or RHEL is running?</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/SJItGKHydoo/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/centos-rhel-which-version/</guid>
<pubDate>Tue, 01 May 2012 04:00:00 GMT</pubDate>
<description><![CDATA[<p>The uname -a command will tell you which kernel version of Linux is running but doesn't give you any information about the distribution or distro version number. This quick tip shows how to do this for CentOS / Red Hat Enterprise Linux.</p>]]></description>
<content:encoded><![CDATA[
<p>The uname -a command will tell you which kernel version of Linux is running but doesn't give you any information about the distribution or distro version number. This quick tip shows how to do this for CentOS / Red Hat Enterprise Linux.</p>
<h2>CentOS / RHEL version</h2>
<p>From the command line enter the following command:</p>
<pre class="brush: bash">
cat /etc/redhat-release</pre>
<p>This will show you something like this:</p>
<pre class="brush: bash">
CentOS release 5.4 (Final)</pre>
<p>Easy! Hopfully now I've posted this I won't forget it next time...</p>
<p><a href="http://feedads.g.doubleclick.net/~a/DM2NUDA12H0iKlZJJTFB4nl3OOE/0/da"><img src="http://feedads.g.doubleclick.net/~a/DM2NUDA12H0iKlZJJTFB4nl3OOE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/DM2NUDA12H0iKlZJJTFB4nl3OOE/1/da"><img src="http://feedads.g.doubleclick.net/~a/DM2NUDA12H0iKlZJJTFB4nl3OOE/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/SJItGKHydoo" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/centos-rhel-which-version/</feedburner:origLink></item>
<item>
<title>iOS Simulator and Xcode 4.3</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/QOg3k3qyXNo/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/ios-simulator-xcode-43/</guid>
<pubDate>Thu, 26 Apr 2012 03:00:00 GMT</pubDate>
<description><![CDATA[<p>I installed/upgrade Xcode on my Mac Lion to 4.3 and couldn't work out where the iOS Simulator was. It turns out you have to manually configure Xcode to install the simulator but even then there's no obvious way to run the iOS Simulator. This post shows how I did it.</p>]]></description>
<content:encoded><![CDATA[
<p>I installed/upgrade Xcode on my Mac Lion to 4.3 and couldn't work out where the iOS Simulator was. It turns out you have to manually configure Xcode to install the simulator but even then there's no obvious way to run the iOS Simulator. This post shows how I did it.</p>
<h2>Installing iOS Simulator</h2>
<p>Start up Xcode, then select the Xcode menu and the Preference menu option. Go to the Downloads option in the preferences dialog window and you'll see the list of simulators etc as shown in the screenshot below.</p>
<div style="margin: 1em 0; text-align: center;"><img src="/assets/images/xcode-install-ios-simulator.png" alt="install iso simulator in xcode" width="550" height="387" /></div>
<p>Click the install buttons for the ones you want and away you go. If you want it to check and install updates automatically then check that box. I left it as-is in my setup.</p>
<h2>Where is iOS Simulator?</h2>
<p>The files downloaded and installed, but where or where is the simulator? I couldn't find it anywhere in the menu options including the Xcode -&gt; Open Developer Tool submenu. And it's not in /Applications either.</p>
<p>The only way I could work out how to run the iOS Simulator was to navigation to the Applications folder with Finder, right-click Xcode and Show Package Contents, then navigate like so:</p>
<p>Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications</p>
<p>In the Applications folder you'll find the iOS Simulator app.</p>
<p>Drag it to the Dock, run it, and away you go.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/lOH2IxVWAfA5Ly8-spozChpRZc0/0/da"><img src="http://feedads.g.doubleclick.net/~a/lOH2IxVWAfA5Ly8-spozChpRZc0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/lOH2IxVWAfA5Ly8-spozChpRZc0/1/da"><img src="http://feedads.g.doubleclick.net/~a/lOH2IxVWAfA5Ly8-spozChpRZc0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/QOg3k3qyXNo" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/ios-simulator-xcode-43/</feedburner:origLink></item>
<item>
<title>Disable the MySQL query cache without restarting MySQL</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/ZslktuNeZUY/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/disable-mysql-query-cache-without-restarting/</guid>
<pubDate>Mon, 23 Apr 2012 02:20:00 GMT</pubDate>
<description><![CDATA[<p>The MySQL query cache enables caching of queries which, in theory, should speed querying the database up. It's possible to disable the MySQL query cache without restarting the server, although you also need to edit the configuration file to make the changes stick on restart.</p>]]></description>
<content:encoded><![CDATA[
<p>The MySQL query cache enables caching of queries which, in theory, should speed querying the database up. It's possible to disable the MySQL query cache without restarting the server, although you also need to edit the configuration file to make the changes stick on restart.</p>
<h2>Query to disable the cache</h2>
<p>From the MySQL command line, a application like phpMyAdmin, or from a script, run the following SQL command to disable the query cache:</p>
<pre class="brush: sql">
SET GLOBAL query_cache_size = 0;</pre>
<p>This will take effect immediately. You will also need to modify the MySQL configuration file to keep it disabled on reboot. Locate the&nbsp;query_cache_size setting in the file and set it to 0.</p>
<p>I needed to do this today myself because one of the websites I manage kept getting locks which were preventing other queries from running, and we decided to shut off the query cache to see if it makes a difference. It's too early so far to tell whether or not it has.</p>
<p>Check out the related posts below for more information about the query cache and how to enable it in the first place.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/mysql-dont-use-query-cache/'>Prevent a query from using MySQL's query cache</a> (Wednesday, August 19th 2009)</li>
<li><a href='http://www.electrictoolbox.com/tell-if-mysql-query-cache-enabled/'>How to tell if the MySQL Query Cache is enabled</a> (Wednesday, August 12th 2009)</li>
<li><a href='http://www.electrictoolbox.com/mysql-query-cache/'>MySQL Query Cache</a> (Wednesday, December 12th 2007)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/CslGBhjJ1AcpFMp8AfyaAzgMFNY/0/da"><img src="http://feedads.g.doubleclick.net/~a/CslGBhjJ1AcpFMp8AfyaAzgMFNY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/CslGBhjJ1AcpFMp8AfyaAzgMFNY/1/da"><img src="http://feedads.g.doubleclick.net/~a/CslGBhjJ1AcpFMp8AfyaAzgMFNY/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/ZslktuNeZUY" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/disable-mysql-query-cache-without-restarting/</feedburner:origLink></item>
<item>
<title>Extract inline image attachments from an email with PHP</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/s1TAtriJ9w8/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/php-email-extract-inline-image-attachments/</guid>
<pubDate>Thu, 12 Apr 2012 22:30:00 GMT</pubDate>
<description><![CDATA[<p>A month ago I posted a <a href="http://www.electrictoolbox.com/php-email-message-class-extracting-attachments/">PHP email message class for extracting attachments</a> and have been asked by a couple of people how to extract inline images and make it so they can appear in the HTML content of the email. This post shows how to do this, using my email class to get the email.</p>]]></description>
<content:encoded><![CDATA[
<p>A month ago I posted a <a href="http://www.electrictoolbox.com/php-email-message-class-extracting-attachments/">PHP email message class for extracting attachments</a> and have been asked by a couple of people how to extract inline images and make it so they can appear in the HTML content of the email. This post shows how to do this, using my email class to get the email.</p>
<h2>The email class</h2>
<p>The email class can be <a href="http://www.electrictoolbox.com/assets/code/EmailMessage.php.zip">downloaded here</a>. The file is a plain text PHP file, compressed as a zip file. I can't really offer any support for this code other than with additional tutorials like this one. For the moment it is poorly documented but when I get more time I'll do more work on it.</p>
<h2>Inline images</h2>
<p>Images can be embeeded in the HTML content of an email and sent along with the email. When they are &quot;inline images&quot; like this, the src property of the image starts with cid: followed by a unique identifier for the image. It's then added as a &quot;message part&quot; which is more commonly known as an &quot;attachment&quot; and can be referenced by the unique identifier with my email class.</p>
<p>The exact format of the cid varies depending on the email client, and is not consistant. For example, I dragged and dropped two images (named 1.jpg and 2.jpg) into Apple's Mail client and then to Gmail, and this is the resulting HTML from each.</p>
<p>Apple Mail:</p>
<p>I've removed the html and boy tags in the example below so it's not quite such a mess of tag soup.</p>
<pre class="brush: xml">
&lt;img id=&quot;9583f2e3-aa95-49dd-9576-a29dc4e2a72b&quot; height=&quot;450&quot; width=&quot;600&quot; apple-width=&quot;yes&quot; apple-height=&quot;yes&quot; src=&quot;cid:3FE80658-A359-4A43-82EA-BEAEA7CEBAEA@local&quot;&gt;
&lt;img id=&quot;e710c040-0288-44c5-afb5-14cf5294879d&quot; height=&quot;450&quot; width=&quot;600&quot; apple-width=&quot;yes&quot; apple-height=&quot;yes&quot; src=&quot;cid:BE4DF124-417B-4AFC-9DC9-F01818A942B2@local&quot;&gt;
</pre>
<p>Gmail:</p>
<pre class="brush: xml">
&lt;img src=&quot;cid:ii_136a895175f87da3&quot; alt=&quot;Inline images 1&quot;&gt;&lt;br&gt;
&lt;div&gt;&lt;img src=&quot;cid:ii_136a895663ed0afd&quot; alt=&quot;Inline images 2&quot;&gt;&lt;br&gt;&lt;/div&gt;
</pre>
<p>So both have cid: followed by a unique identifier. Apple adds a @local at the end which is presumably the domain name, Gmail does not. Other email clients will format the identifier differently.</p>
<h2>Using the email class to download the message</h2>
<p>Connect using the imap mail functions first and then use the email class to fetch the first message. The class doesn't yet have functions for seeing how many messages are in the mailbox etc, use the regular imap functions for that.</p>
<pre class="brush: php">
$login = 'me@example.com';
$password = 'mypassword';
$server = '{imap.gmail.com:993/ssl/novalidate-cert}';
$connection = imap_open($server, $login, $password);
$emailMessage = new EmailMessage($connection, 1);
$emailMessage-&gt;fetch();</pre>
<p>The structure of $emailMessage will be like this for the Gmail example:</p>
<pre class="brush: php">
EmailMessage Object
(
    [connection:protected] =&gt; Resource id #4
    [messageNumber:protected] =&gt; 1
    [bodyHTML] =&gt; &lt;img src=&quot;cid:ii_136a895175f87da3&quot; alt=&quot;Inline images 1&quot;&gt;&lt;br&gt;
&lt;div&gt;&lt;img src=&quot;cid:ii_136a895663ed0afd&quot; alt=&quot;Inline images 2&quot;&gt;&lt;br&gt;&lt;/div&gt;

    [bodyPlain] =&gt; [image: Inline images 1]
[image: Inline images 2]

    [attachments] =&gt; Array
        (
            [ii_136a895663ed0afd] =&gt; Array
                (
                    [type] =&gt; 5
                    [subtype] =&gt; JPEG
                    [filename] =&gt; 2.jpg
                    [data] =&gt; ...
                    [inline] =&gt; 1
                )

            [ii_136a895175f87da3] =&gt; Array
                (
                    [type] =&gt; 5
                    [subtype] =&gt; JPEG
                    [filename] =&gt; 1.jpg
                    [data] =&gt; ...
                    [inline] =&gt; 1
                )

        )

    [getAttachments] =&gt; 
)
</pre>
<p>We can now do do a regular expression match to extract all the src=&quot;cid:...&quot; from bodyHTML and then replace them with a full http (or https) URL to the image on our filesystem.</p>
<pre class="brush: php">
preg_match_all('/src=&quot;cid:(.*)&quot;/Uims', $emailMessage-&gt;bodyHTML, $matches);
</pre>
<p>The $matches array will contain the following:</p>
<pre class="brush: php">
Array
(
    [0] =&gt; Array
        (
            [0] =&gt; src=&quot;cid:ii_136a895175f87da3&quot;
            [1] =&gt; src=&quot;cid:ii_136a895663ed0afd&quot;
        )
    [1] =&gt; Array
        (
            [0] =&gt; ii_136a895175f87da3
            [1] =&gt; ii_136a895663ed0afd
        )
)
</pre>
<p>So we want to loop on the items in $matches[1] as that contains the unique idenfier which is used as the array key for the attachments array. They can be saved to file with a unique name and the src attribute in the HTML changed to a full URL.</p>
<pre class="brush: php">
if(count($matches)) {
	
	$search = array();
	$replace = array();
	
	foreach($matches[1] as $match) {
		$uniqueFilename = &quot;A UNIQUE_FILENAME.extension&quot;;
		file_put_contents(&quot;/path/to/images/$uniqueFilename&quot;, $emailMessage-&gt;attachments[$match]['data']);
		$search[] = &quot;src=\&quot;cid:$match\&quot;&quot;;
		$replace[] = &quot;src=\&quot;http://www.example.com/images/$uniqueFilename\&quot;&quot;;
	}
	
	$emailMessage-&gt;bodyHTML = str_replace($search, $replace, $emailMessage-&gt;bodyHTML);
	
}
</pre>
<p>I'll leave it up to you to work out how you want to craft your unique filename. Note you'll need to change /path/to/images to the actual path where the file should be saved, and http://www.example.com/images/ to the actual URL that points to that location.</p>
<h2>Download the code from this post</h2>
<p>To save you having to copy and paste, here's download links for the full PHP example from this page (which contains additional inline comments), and also the EmailMessage class:</p>
<p>- <a href="http://www.electrictoolbox.com/assets/code/ExtractInlineAttachments.php.gz">PHP example</a><br />
- <a href="http://www.electrictoolbox.com/assets/code/EmailMessage.php.zip">EmailMessage class</a></p>
<p>Both are gzip compressed and contain a single PHP plain text file.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/php-email-message-class-extracting-attachments/'>PHP email message class for extracting attachments</a> (Thursday, March 15th 2012)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/WaH5mlD-ggeCembZ71E_XQROIXM/0/da"><img src="http://feedads.g.doubleclick.net/~a/WaH5mlD-ggeCembZ71E_XQROIXM/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/WaH5mlD-ggeCembZ71E_XQROIXM/1/da"><img src="http://feedads.g.doubleclick.net/~a/WaH5mlD-ggeCembZ71E_XQROIXM/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/s1TAtriJ9w8" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/php-email-extract-inline-image-attachments/</feedburner:origLink></item>
<item>
<title>Remove ads at the top of Gmail</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/6epEYZAu6Pw/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/remove-ads-top-gmail/</guid>
<pubDate>Tue, 10 Apr 2012 02:00:00 GMT</pubDate>
<description><![CDATA[<p>Gmail by default shows ads above the list of emails. It's easy to switch these off but they're not intuitively named when looking at Gmail's settings. This post shows how to switch them off.</p>]]></description>
<content:encoded><![CDATA[
<p>Gmail by default shows ads above the list of emails. It's easy to switch these off but they're not intuitively named when looking at Gmail's settings. This post shows how to switch them off.</p>
<h2>The defaults - ads above the message list</h2>
<p>The first screenshot below shows the default setting, which is to show ads above the message list. I've highlighted the ad in the screenshot with a red box.</p>
<div style="margin: 1em 0; text-align: center;"><img src="/assets/images/gmail-remove-ads-1.png" alt="ads above the message list in gmail" width="500" height="306" /></div>
<h2>Remove the ads</h2>
<p>To remove the ads, click the settings cog icon above-right from the message list. This will show a drop down menu where you can select the &quot;Settings&quot; option. This is shown in the screenshot below, with a red box around the icon and menu.</p>
<div style="margin: 1em 0; text-align: center;"><img src="/assets/images/gmail-remove-ads-2.png" alt="ads above the message list in gmail" width="500" height="306" /></div>
<h2>Don't show &quot;Web Clips&quot;</h2>
<p>The ads are called &quot;Web Clips&quot;. Along the top of the settings are a series of tabs/options and you'll see one labelled &quot;Web Clips&quot;. Click that and then un-check the &quot;Show my web clips above the Inbox&quot; option. You don't need to click a button to save; it immediately takes effect.</p>
<p>Again, the relevent things to click are highlighted with a red box in the screenshot below.</p>
<div style="margin: 1em 0; text-align: center;"><img src="/assets/images/gmail-remove-ads-3.png" alt="ads above the message list in gmail" width="500" height="306" /></div>
<h2>Now there are no ads above the message list</h2>
<p>Now go back to your inbox and there are no longer any ads above the message list.</p>
<div style="margin: 1em 0; text-align: center;"><img src="/assets/images/gmail-remove-ads-4.png" alt="ads above the message list in gmail" width="500" height="306" /></div><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/gmail-notification-ringtone-android/'>How to set the Gmail notification ringtone on Android</a> (Monday, April 2nd 2012)</li>
<li><a href='http://www.electrictoolbox.com/gmail-search-by-date/'>Searching Gmail by date</a> (Friday, June 3rd 2011)</li>
<li><a href='http://www.electrictoolbox.com/enable-imap-gmail/'>How to enable IMAP access for a Gmail account</a> (Monday, February 23rd 2009)</li>
<li><a href='http://www.electrictoolbox.com/gmail-view-raw-email-message/'>View the raw email message in Gmail</a> (Sunday, October 5th 2008)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/ckHbnQitquNNz-MaiNZ2CZfc_w0/0/da"><img src="http://feedads.g.doubleclick.net/~a/ckHbnQitquNNz-MaiNZ2CZfc_w0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/ckHbnQitquNNz-MaiNZ2CZfc_w0/1/da"><img src="http://feedads.g.doubleclick.net/~a/ckHbnQitquNNz-MaiNZ2CZfc_w0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/6epEYZAu6Pw" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/remove-ads-top-gmail/</feedburner:origLink></item>
<item>
<title>Disable the screenshot shadow on Mac OS X</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/5jWuhqLFYrQ/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/disable-screenshot-shadow-mac-osx/</guid>
<pubDate>Mon, 09 Apr 2012 02:00:00 GMT</pubDate>
<description><![CDATA[<p>When you take screenshots on Mac OS X there's a shadow around the screenshot by default. This post shows how to disable the shadow from the screenshot and how to subsequently restore the shadow.</p>]]></description>
<content:encoded><![CDATA[
<p>When you take screenshots on Mac OS X there's a shadow around the screenshot by default. This post shows how to disable the shadow from the screenshot and how to subsequently restore the shadow.</p>
<h2>Screenshot example with shadow</h2>
<p>The first example below is a screenshot with the default shadow around the window. It's a nice effect but makes the image a lot bigger than it needs to be, which can be less than useful when doing documentation etc.</p>
<div style="margin: 1em 0; text-align: center;"><img src="/assets/images/osx-screenshot-shadow-enabled.png" alt="osx screenshot with shadow enabled" width="558" height="410" /></div>
<h2>Screenshot example with shadow disabled</h2>
<p>The second example below shows a screenshot of the same terminal window above, but this time with the shadow disabled.</p>
<div style="margin: 1em 0; text-align: center;"><img src="/assets/images/osx-screenshot-shadow-disabled.png" alt="osx screenshot with shadow disabled" width="444" height="296" /></div>
<p>The downside with this particular example is there's no borders showing on the window in the screenshot, so there appears to be a lot of whitespace between the top of the screenshot and this text here, even though all that white space is part of the image.</p>
<p>So depending on the app you are taking a screenshot of, the result of removing the shadow may be good, or it may be not so good.</p>
<h2>Disable the shadow from the screenshot</h2>
<p>Open up Terminal and enter the following two commands:</p>
<pre class="brush: bash">
defaults write com.apple.screencapture disable-shadow -bool true
killall SystemUIServer</pre>
<p>The next screenshot you take will not have the shadow.</p>
<h2>Enable the shadow in the screenshot</h2>
<p>To reverse the above, enter the following two commands in Terminal. As you can see the only difference is changing &quot;true&quot; to &quot;false&quot;.</p>
<pre class="brush: bash">
defaults write com.apple.screencapture disable-shadow -bool false
killall SystemUIServer</pre>
<p>Now shadows will appear in the screenshots again.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/Jn2euuDFSt2_RIZrE5R_jgBrWI0/0/da"><img src="http://feedads.g.doubleclick.net/~a/Jn2euuDFSt2_RIZrE5R_jgBrWI0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Jn2euuDFSt2_RIZrE5R_jgBrWI0/1/da"><img src="http://feedads.g.doubleclick.net/~a/Jn2euuDFSt2_RIZrE5R_jgBrWI0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/5jWuhqLFYrQ" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/disable-screenshot-shadow-mac-osx/</feedburner:origLink></item>
<item>
<title>Recursively upload files via FTP using NCFTPPUT</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/kniISHVcbfw/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/recursively-upload-files-ftp-ncftpput/</guid>
<pubDate>Tue, 03 Apr 2012 00:00:00 GMT</pubDate>
<description><![CDATA[<p>If you have a lot of files to upload to a website and the only access is via FTP then you can use a nice GUI tool to just drag and drop the directory, or you can use the command line ncftpput tool.</p>]]></description>
<content:encoded><![CDATA[
<p>If you have a lot of files to upload to a website and the only access is via FTP then you can use a nice GUI tool to just drag and drop the directory, or you can use the command line ncftpput tool.</p>
<h2>Why use a command line tool?</h2>
<p>I needed to upload a directory containing thousands of files and directories with many subdirectories. I could have used a GUI tool to do it but it would have taken a really long time. There was no SSH, SFTP, rsync or SCP access to the website in question so I did this:</p>
<p>1) tar up and gzip the directory on my local machine</p>
<p>2) copy it via sftp to my US based VPS (just one file copied up)</p>
<p>3) decompress it on the VPS</p>
<p>4) use ncftpput to copy it to the website (all files copied from VPS to website)</p>
<p>The whole process took a couple of minutes or so, instead of potentially 30 minutes or longer using a GUI tool like Transmit on my crappy ADSL connection.</p>
<h2>How to use ncftpput to recursively copy a directory</h2>
<p>Let's say the directory containing the files to upload is to go into the website's root directory and is called &quot;myapplication&quot;.</p>
<p>The current working directory looks like this:</p>
<pre class="brush: bash">
$ ls -l 

total 8380
drwx------ 5 chris chris 4096 Aug 23 2010 myapplication
-rw-r--r-- 1 chris chris 8418990 Apr 3 11:36 myapplication.tar.gz</pre>
<p>To recursively upload the myapplication directory, do this:</p>
<pre class="brush: bash">
ncftpput -u [username] -p [password] -R [hostname] / myapplication</pre>
<p>Substitute [username], [password] and [hostname] with the appropriate values; -R tells ncftpput to recursively upload; / is the directory you want to upload to, and myapplication at the end is the directory to upload.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/PnJzK4qYKkd8QdjmywuykTXVzNI/0/da"><img src="http://feedads.g.doubleclick.net/~a/PnJzK4qYKkd8QdjmywuykTXVzNI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/PnJzK4qYKkd8QdjmywuykTXVzNI/1/da"><img src="http://feedads.g.doubleclick.net/~a/PnJzK4qYKkd8QdjmywuykTXVzNI/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/kniISHVcbfw" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/recursively-upload-files-ftp-ncftpput/</feedburner:origLink></item>
<item>
<title>How to set the Gmail notification ringtone on Android</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/hk6fmC_PRLo/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/gmail-notification-ringtone-android/</guid>
<pubDate>Mon, 02 Apr 2012 07:00:00 GMT</pubDate>
<description><![CDATA[<p>On an Android phone there is a notification ringtone which will be used by default for all notifications. The Gmail app allows you to specify a different notification ringtone which can be quite useful for having the default for SMS messages and something else for new emails, but the option is buried quite deep and I can never remember where it is, so this post will help to remind me in the future.</p>]]></description>
<content:encoded><![CDATA[
<p>On an Android phone there is a notification ringtone which will be used by default for all notifications. The Gmail app allows you to specify a different notification ringtone which can be quite useful for having the default for SMS messages and something else for new emails, but the option is buried quite deep and I can never remember where it is, so this post will help to remind me in the future.</p>
<h2>Default notification ringtone</h2>
<p>The default notification ringtone for all apps etc is at:</p>
<p>Android Setttings -&gt; Sound -&gt; Notification Ringtone</p>
<p>This will be used for everything unless specified differently in each app, when it can be specified in the app. As I mentioned above, this can be useful in the case of Gmail for having a different notification ringtone for email than the default, which will be used for text messages.</p>
<h2>Gmail notification ringtone</h2>
<p>You can specify a different notification ringtone for each account and it's buried quite deep in the app settings. When I wanted to change it myself yesterday, it took a while to work out where it was.</p>
<p>Gmail App -&gt; Menu -&gt; More -&gt; Settings -&gt; [Account Name] -&gt; Labels to notify -&gt; Inbox</p>
<p>Phew, and now you can set it by touching the &quot;Ringtone&quot; setting.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/YWajG4JBp5OaQq4Pch-SY2S1M0o/0/da"><img src="http://feedads.g.doubleclick.net/~a/YWajG4JBp5OaQq4Pch-SY2S1M0o/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/YWajG4JBp5OaQq4Pch-SY2S1M0o/1/da"><img src="http://feedads.g.doubleclick.net/~a/YWajG4JBp5OaQq4Pch-SY2S1M0o/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/hk6fmC_PRLo" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/gmail-notification-ringtone-android/</feedburner:origLink></item>
<item>
<title>PHP email message class for extracting attachments</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/K0Aj_w6aH6Y/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/php-email-message-class-extracting-attachments/</guid>
<pubDate>Thu, 15 Mar 2012 09:30:00 GMT</pubDate>
<description><![CDATA[<p>I've done a bit of work in the past extracting attachments from email with PHP and posted a few articles here showing how to do it. None of them have really been all that satisfactory and so a little earlier this year I started again from scratch. I've posted here what is a work-in-progress due to requests from several people. It's not complete but it does work.</p>]]></description>
<content:encoded><![CDATA[
<p>I've done a bit of work in the past extracting attachments from email with PHP and posted a few articles here showing how to do it. None of them have really been all that satisfactory and so a little earlier this year I started again from scratch. I've posted here what is a work-in-progress due to requests from several people. It's not complete but it does work.</p>
<h2>Notes about the email class</h2>
<p>When working on it, I discovered just how difficult it is to actually get information out of emails because email clients format emails differently, and also differently depending on whether there are attachments, inline attachments, html and/or plain text body parts.</p>
<p>This class recursively loops through the email and finds all the attachements including email messages themselves that may have been attached and recurses through those too. While doing all this it puts the html and plain text body of the top level message into the bodyHTML and bodyPlain properties.</p>
<p>Unfortunately I didn't write any comments through the code because I was intending to get it finished at the time and write a blog about it which would have served that function, but time ran away from me.</p>
<p>Basically the format of a message is in &quot;parts&quot; and they can be like e.g. 1, 1.1, 1.2, 1.2.1, 1.2.2, etc and you need those numbers to be able to get the &quot;attachments&quot;. I worked out through trial and error with many emails that the order and numbering varies considerably.</p>
<p>At some point in the future I will do some more work on this code, making it more usable for email in general, adding commenting etc and probably post it to GitHub.</p>
<h2>Download the email class</h2>
<p><a href="http://www.electrictoolbox.com/assets/code/EmailMessage.php.zip">Download it here</a>.</p>
<p>The file is a plain text PHP file, compressed as a zip file. I can't really offer any support for this code so it's really up to you to try it out and see what you can do with it.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/php-email-extract-inline-image-attachments/'>Extract inline image attachments from an email with PHP</a> (Friday, April 13th 2012)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/k0O55pamq204rlxBeuTjoo8_Aew/0/da"><img src="http://feedads.g.doubleclick.net/~a/k0O55pamq204rlxBeuTjoo8_Aew/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/k0O55pamq204rlxBeuTjoo8_Aew/1/da"><img src="http://feedads.g.doubleclick.net/~a/k0O55pamq204rlxBeuTjoo8_Aew/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/K0Aj_w6aH6Y" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/php-email-message-class-extracting-attachments/</feedburner:origLink></item>
<item>
<title>Cannot load from mysql.proc. The table is probably corrupted</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/TOoqjVTlwcw/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/cannot-load-from-mysql-proc-the-table-is-probably-corrupted/</guid>
<pubDate>Tue, 21 Feb 2012 21:00:00 GMT</pubDate>
<description><![CDATA[<p>I mistyped the name of an internal MySQL function in some code this morning and got back the error message &quot;Cannot load from mysql.proc. The table is probably corrupted&quot; which appeared to have no bearing on the actual error. The simple fix to this problem is to run the mysql_upgrade command.</p>]]></description>
<content:encoded><![CDATA[
<p>I mistyped the name of an internal MySQL function in some code this morning and got back the error message &quot;Cannot load from mysql.proc. The table is probably corrupted&quot; which appeared to have no bearing on the actual error. The simple fix to this problem is to run the mysql_upgrade command.</p>
<h2>mysql_upgrade</h2>
<p>From the command line (you won't be able to do this from a tool like phpMyAdmin) run the command line tool mysql_upgrade passing like so:</p>
<pre class="brush: bash">
mysql_upgrade -u root -p</pre>
<p>Then enter the root's password and it will check all the databases and tables and fix them where appropriate. You may need to specify the full path to the above command if it's not in the shell's search path.</p>
<p>On Debian 6 it's at /usr/bin/mysql_upgrade</p>
<p>On Mac MAMP&nbsp;/Applications/MAMP/Library/bin/mysql_upgrade</p>
<p>On Windows it'll be where-ever MySQL is installed in the bin subdirectory. You'll need to open up the command prompt, change to that directory and then run mysql_upgrade.exe -u root -p</p>
<p>Now that I'd upgraded the databases I got a much better error message which was related to the error I'd created: &quot;FUNCTION [dbname].[function name] does not exist&quot;</p>
<h2>Disclaimer</h2>
<p>Before running a command like this on a production server, it's always a good idea to take a full backup of all databases first, just in case something goes wrong.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/mysql-table-marked-crashed-should-be-repaired/'>MySQL table is marked as crashed and should be repaired</a> (Tuesday, August 2nd 2011)</li>
<li><a href='http://www.electrictoolbox.com/mysql-utility-commands/'>MySQL utility commands</a> (Wednesday, December 30th 2009)</li>
<li><a href='http://www.electrictoolbox.com/mysql-incorrect-key-file-for-table-error/'>MySQL &quot;Incorrect key file for table&quot; error</a> (Wednesday, June 24th 2009)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/86Vy1R__UskdkhD6USRrJ-52qyY/0/da"><img src="http://feedads.g.doubleclick.net/~a/86Vy1R__UskdkhD6USRrJ-52qyY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/86Vy1R__UskdkhD6USRrJ-52qyY/1/da"><img src="http://feedads.g.doubleclick.net/~a/86Vy1R__UskdkhD6USRrJ-52qyY/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/TOoqjVTlwcw" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/cannot-load-from-mysql-proc-the-table-is-probably-corrupted/</feedburner:origLink></item>
<item>
<title>PHP script to check MySQL replication status</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/zEsgh9vDmA8/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/php-script-check-mysql-replication-status/</guid>
<pubDate>Fri, 17 Feb 2012 04:00:00 GMT</pubDate>
<description><![CDATA[<p>If you have MySQL replication running in either a master-slave or master-master type setup then don't assume everything is running perfectly all the time. Power cuts and other disasters do happen so you need to check periodically to ensure it's all working. This post has a PHP script to check for any MySQL replication errors and then emails if there are any issues</p>]]></description>
<content:encoded><![CDATA[
<p>If you have MySQL replication running in either a master-slave or master-master type setup then don't assume everything is running perfectly all the time. Power cuts and other disasters do happen so you need to check periodically to ensure it's all working. This post has a PHP script to check for any MySQL replication errors and then emails if there are any issues</p>
<h2>MySQL Slave Status</h2>
<p>Get the current MySQL Slave status by running the command &quot;SHOW SLAVE STATUS&quot; on the slave. This will spit out all sorts of information including whether the following are running (&quot;Yes&quot; or &quot;No&quot;):</p>
<ul>
    <li>Slave_IO_Running</li>
    <li>Slave_SQL_Running</li>
</ul>
<p>and then an error number and message for each of the above like so:</p>
<ul>
    <li>Last_IO_Errno</li>
    <li>Last_IO_Error</li>
    <li>Last_SQL_Errno</li>
    <li>Last_SQL_Error</li>
</ul>
<h2>PHP script to check MySQL slave status</h2>
<p>The following script should be run periodically. Modify it to suit your own purposes as you see fit.</p>
<p>Enter values for the username and password to log in as (my script assumes the same login and password is used for all servers, and that all servers can be logged into from the current server) and a list of MySQL servers to check.</p>
<pre class="brush: php">
$username = '[username]';
$password = '[password]';
$servers = array(
	'[server1]',
	'[server2]',
	'[serverN]',
);

$errors = '';

foreach($servers as $server) {
	$link = mysql_connect($server, $username, $password);
	if($link) {
		$res = mysql_query(&quot;SHOW SLAVE STATUS&quot;, $link);
		$row = mysql_fetch_assoc($res);
		if($row['Slave_IO_Running'] == 'No') {
			$errors .= &quot;Slave IO not running on $server\n&quot;;
			$errors .= &quot;Error number: {$row['Last_IO_Errno']}\n&quot;;
			$errors .= &quot;Error message: {$row['Last_IO_Error']}\n\n&quot;;
		}
		if($row['Slave_SQL_Running'] == 'No') {
			$errors .= &quot;Slave SQL not running on $server\n&quot;;
			$errors .= &quot;Error number: {$row['Last_SQL_Errno']}\n&quot;;
			$errors .= &quot;Error message: {$row['Last_SQL_Error']}\n\n&quot;;
		}
		mysql_close($link);
	}
	else {
		$errors .= &quot;Could not connect to $server\n\n&quot;;
	}
}

if($errors) {
	mail('[email address]', 'MySQL slave errors', $errors);
}
</pre>
<h2>Useful links for dealing with errors</h2>
<p>I'm not going to help you fix errors myself as I'd simply be copying more or less the information I've found on other websites (and I don't know how accurate or successful all of the solutions are) so will link to some solutions here.</p>
<p>HowtoForge has a post called&nbsp;&quot;<a target="_blank" href="http://www.howtoforge.com/how-to-repair-mysql-replication">how to repair MySQL replication</a>&quot; which shows examples of the SHOW SLAVE STATUS command and covers fixing issues when Slave_SQL_Running is &quot;No&quot;. I've used the solution presented a couple of times to fix issues, but do be aware if you've got something like a primary key violation issue and you skip the error then your databases may not actually be accurately in sync.</p>
<p>I personally got a Slave_IO_Running = &quot;No&quot; error which resulted in the message &quot;Got fatal error 1236: 'Client requested master to start replication from impossible position' from master when reading data from binary log&quot;.</p>
<p><a href="http://www.brianklug.com/w/page/15052161/MySQL%20Error%3A%20Client%20requested%20master%20to%20start%20replication%20from%20impossible%20position">This article</a> at Brian Klug's wiki helped me; I did the change master log file solution which worked for me, but again be careful as you may lose data. Note you don't need to also set the master host, user and password too, just the file and position.</p>
<p><a href="http://dev.kafol.net/2011/09/mysql-error-1236-client-requested.html">Another article</a> at dev.kafol.net gave me a cross reference for the same solution and also talks about setting sync_binlog to 1 in the MySQL configuration which may be useful; I haven't tried this yet myself but I imagine on a busy server it may lead to more intensive disk activity.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/mysql-master-master-replication/'>Master master replication with MySQL</a> (Friday, January 14th 2011)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/lzie3DE5YGYcpmUo99OJ8eVQrRk/0/da"><img src="http://feedads.g.doubleclick.net/~a/lzie3DE5YGYcpmUo99OJ8eVQrRk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/lzie3DE5YGYcpmUo99OJ8eVQrRk/1/da"><img src="http://feedads.g.doubleclick.net/~a/lzie3DE5YGYcpmUo99OJ8eVQrRk/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/zEsgh9vDmA8" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/php-script-check-mysql-replication-status/</feedburner:origLink></item>
<item>
<title>Sending a header using the PHP SOAP client</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/FOrdhJBHSgs/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/sending-header-php-soap-client/</guid>
<pubDate>Thu, 02 Feb 2012 03:00:00 GMT</pubDate>
<description><![CDATA[<p>I've recently been interfacing with a SOAP API on a .NET server and also creating an API in PHP, and both require sending a specific SOAP header for authentication. This post shows how to send a SOAP header using the PHP SOAP client which is built into PHP.</p>]]></description>
<content:encoded><![CDATA[
<p>I've recently been interfacing with a SOAP API on a .NET server and also creating an API in PHP, and both require sending a specific SOAP header for authentication. This post shows how to send a SOAP header using the PHP SOAP client which is built into PHP.</p>
<h2>Sending an authentication header with PHP SOAP</h2>
<p>In the case of the SOAP server I have been developing, the server requires a header to be sent which contains the API key. The header name is APIKey and the value the key itself. In the example below the namespace used for the API call is &quot;ExampleNamespace&quot;.</p>
<p>To initiate the SOAP client and set the header using PHP do the following, where $wsdl is the URL of the WSDL file for the SOAP request:</p>
<pre class="brush: php">
$client = new SoapClient($wsdl);
$header = new SoapHeader('ExampleNamespace', 'APIKey', $apiKey);
$client-&gt;__setSoapHeaders($header);</pre>
<p>Now you can make requests to the SOAP server and the header will be sent each time.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/php-soapclient-unable-parse-url/'>PHP SoapClient &quot;Unable to parse URL&quot; error</a> (Thursday, October 23rd 2008)</li>
<li><a href='http://www.electrictoolbox.com/class-soapclient-not-found/'>PHP Error Class 'SoapClient' not found</a> (Tuesday, September 25th 2007)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/BqS86LaZ5bCTHM01bVw20N6YRNo/0/da"><img src="http://feedads.g.doubleclick.net/~a/BqS86LaZ5bCTHM01bVw20N6YRNo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/BqS86LaZ5bCTHM01bVw20N6YRNo/1/da"><img src="http://feedads.g.doubleclick.net/~a/BqS86LaZ5bCTHM01bVw20N6YRNo/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/FOrdhJBHSgs" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/sending-header-php-soap-client/</feedburner:origLink></item>
<item>
<title>PHP $_SERVER variables - CLI via SSH vs cron</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/oM7oRpqacxE/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/php-server-variables-cli-via-ssh-vs-cron/</guid>
<pubDate>Tue, 31 Jan 2012 00:30:00 GMT</pubDate>
<description><![CDATA[<p>I have a number of batch processes that run using PHP as the command interpreter, and discovered after making a change to one of them the other day that the variables available to PHP in the $_SERVER superglobal are different depending on whether it's run via an SSH session or cron. This post shows the difference on Debian 6. The values available are probably the same on other distros.</p>]]></description>
<content:encoded><![CDATA[
<p>I have a number of batch processes that run using PHP as the command interpreter, and discovered after making a change to one of them the other day that the variables available to PHP in the $_SERVER superglobal are different depending on whether it's run via an SSH session or cron. This post shows the difference on Debian 6. The values available are probably the same on other distros.</p>
<h2>$_SERVER using the CLI via SSH</h2>
<p>Using the PHP command line interpeter (CLI) the following was displayed when running print_r($_SERVER), showing which variables are available:</p>
<pre style="border: 1px #666 solid; padding: 10px; padding-bottom: 1em; overflow: hidden; overflow-x: auto; background: #eeeeee; font-size: 105%;">
Array
(
    [TERM] =&gt; xterm-color
    [SHELL] =&gt; /bin/bash
    [SSH_CLIENT] =&gt; A.B.C.D 58867 22
    [SSH_TTY] =&gt; /dev/pts/0
    [USER] =&gt; chris
    [MAIL] =&gt; /var/mail/chris
    [PATH] =&gt; /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
    [PWD] =&gt; /tmp
    [LANG] =&gt; en_NZ.UTF-8
    [SHLVL] =&gt; 1
    [HOME] =&gt; /home/chris
    [LOGNAME] =&gt; chris
    [SSH_CONNECTION] =&gt; A.B.C.D 58867 A.B.C.D 22
    [_] =&gt; /usr/bin/php
    [OLDPWD] =&gt; /home/chris
    [PHP_SELF] =&gt; 1.php
    [SCRIPT_NAME] =&gt; 1.php
    [SCRIPT_FILENAME] =&gt; 1.php
    [PATH_TRANSLATED] =&gt; 1.php
    [DOCUMENT_ROOT] =&gt; 
    [REQUEST_TIME] =&gt; 1327976915
    [argv] =&gt; Array
        (
            [0] =&gt; 1.php
        )

    [argc] =&gt; 1
)</pre>
<p>Note that I've substituted the actual IP addresses with A.B.C.D in the example above.</p>
<h2>$_SERVER using the CLI via cron</h2>
<p>Running a PHP script under cron yields less variables in the $_SERVER array. My example script doing print_r($_SERVER) output this:</p>
<pre style="border: 1px #666 solid; padding: 10px; padding-bottom: 1em; overflow: hidden; overflow-x: auto; background: #eeeeee; font-size: 105%;">
Array
(
    [HOME] =&gt; /home/chris
    [LOGNAME] =&gt; chris
    [PATH] =&gt; /usr/bin:/bin
    [LANG] =&gt; en_NZ.UTF-8
    [SHELL] =&gt; /bin/sh
    [PWD] =&gt; /home/chris
    [PHP_SELF] =&gt; /tmp/1.php
    [SCRIPT_NAME] =&gt; /tmp/1.php
    [SCRIPT_FILENAME] =&gt; /tmp/1.php
    [PATH_TRANSLATED] =&gt; /tmp/1.php
    [DOCUMENT_ROOT] =&gt; 
    [REQUEST_TIME] =&gt; 1327976941
    [argv] =&gt; Array
        (
            [0] =&gt; /tmp/1.php
        )

    [argc] =&gt; 1
)</pre>
<h2>Reason for posting this</h2>
<p>As I mentioned at the start of this post, I run a lot of batch processes via cron using PHP. Sometimes I need to use $_SERVER variables and as I discovered they're not all available under cron, so testing via the command line won't necessarily yield the same response as when using cron.</p>
<p>I've posted this as a quick reference should I need to use $_SERVER variables in the future using cron so I can see what's available. With the issue I was having the other day, it was the [USER] variable being present from the command line using SSH which isn't present when using cron.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/php-command-line-syntax-checking/'>PHP command line syntax checking</a> (Saturday, April 24th 2010)</li>
<li><a href='http://www.electrictoolbox.com/running-php-scripts-as-shell-scripts/'>Running PHP scripts as shell scripts</a> (Monday, February 2nd 2009)</li>
<li><a href='http://www.electrictoolbox.com/command-line-arguments-for-php-cli/'>Command line arguments for the PHP CLI</a> (Thursday, June 19th 2008)</li>
<li><a href='http://www.electrictoolbox.com/command-line-arguments-php-cli/'>Command line arguments with a PHP CLI script</a> (Sunday, June 15th 2008)</li>
<li><a href='http://www.electrictoolbox.com/determine-php-run-via-http-or-cli/'>Determine whether PHP is being run via HTTP or CLI</a> (Saturday, March 8th 2008)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/_WaVsLoj05PxITrBp7bSuuv2uBo/0/da"><img src="http://feedads.g.doubleclick.net/~a/_WaVsLoj05PxITrBp7bSuuv2uBo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/_WaVsLoj05PxITrBp7bSuuv2uBo/1/da"><img src="http://feedads.g.doubleclick.net/~a/_WaVsLoj05PxITrBp7bSuuv2uBo/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/oM7oRpqacxE" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/php-server-variables-cli-via-ssh-vs-cron/</feedburner:origLink></item>
<item>
<title>"Error opening terminal xterm-color" on Mac OSX Terminal</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/zwE_mKx07BM/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/error-opening-terminal-xterm-color-mac-osx-terminal/</guid>
<pubDate>Thu, 26 Jan 2012 11:00:00 GMT</pubDate>
<description><![CDATA[<p>If you are connecting to a remote server from the Mac OS X terminal and get the message &quot;Error opening terminal: xterm-color&quot; when doing certain operations on the remote server, then you either change your terminal's declaration setting or add a TERM declaration to the bash profile on the server at the other end to prevent the error message from happening. There may be other ways to solve it at the server end but this post shows a quick and easy fix.</p>]]></description>
<content:encoded><![CDATA[
<p>If you are connecting to a remote server from the Mac OS X terminal and get the message &quot;Error opening terminal: xterm-color&quot; when doing certain operations on the remote server, then you either change your terminal's declaration setting or add a TERM declaration to the bash profile on the server at the other end to prevent the error message from happening. There may be other ways to solve it at the server end but this post shows a quick and easy fix.</p>
<h2>Other operating systems and apps</h2>
<p>This may also affect users on other operating systems using SSH to connect to a remote server, but I use a Mac and that's where I had the issue. If you're using something else then the setting the TERM section at the end of this post should probably help.</p>
<h2>Change the terminal emulation declaration</h2>
<p>Open up Terminal's preferences and click &quot;Settings&quot; then &quot;Advanced&quot;.<br />
This is shown in the screenshot below:</p>
<p class="imgcenter"><img alt="mac osx terminal advanced settings" width="600" height="548" src="/assets/images/mac-osx-terminal-preferences-advanced.jpg" /></p>
<p>The section highlighted with the red box is where you can set the terminal declaration. Open up the drop down box and change it to xterm and when you log in to the remote server it won't show the error about xterm-color.</p>
<h2>Setting TERM on the remote server</h2>
<p>You can instead change the TERM declaration on the remote server.<br />
Do this on the command line like so:</p>
<pre class="brush: bash">
TERM=xterm</pre>
<p>This will take effect immediately for all future commands executed. When you log out and back in again it will revert to the TERM setting your SSH client application had sent the last time. To make the change permanent add the above line to your .bash_profile or .bashrc on the remote server.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/history-search-auto-completion-bash-shell-ubuntu/'>History search auto completion on the BASH shell on Ubuntu</a> (Wednesday, November 28th 2007)</li>
<li><a href='http://www.electrictoolbox.com/pageup-history-auto-completion-bash-shell/'>PageUp and PageDown history search auto completion on the BASH shell</a> (Wednesday, November 14th 2007)</li>
<li><a href='http://www.electrictoolbox.com/changing-colour-of-bash-shell-prompt/'>Changing the color of the BASH shell prompt</a> (Sunday, November 11th 2007)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/8_6otQI6wOVtdLgqF2mNRe6XODY/0/da"><img src="http://feedads.g.doubleclick.net/~a/8_6otQI6wOVtdLgqF2mNRe6XODY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/8_6otQI6wOVtdLgqF2mNRe6XODY/1/da"><img src="http://feedads.g.doubleclick.net/~a/8_6otQI6wOVtdLgqF2mNRe6XODY/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/zwE_mKx07BM" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/error-opening-terminal-xterm-color-mac-osx-terminal/</feedburner:origLink></item>
<item>
<title>Free inactive memory on Mac with FreeMemory</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/yQLVx8BeNLw/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/free-inactive-memory-mac-freememory/</guid>
<pubDate>Wed, 18 Jan 2012 21:30:00 GMT</pubDate>
<description><![CDATA[<p>I've posted in the past about using the &quot;purge&quot; command line utility on <a href="http://www.electrictoolbox.com/purge-free-inactive-memory-mac-osx/">Mac OSX to free up inactive memory</a> but a recent update appears to have broken the tool from working. An alternative is to use the FreeMemory app from the App Store to do the same thing, but more easily.</p>]]></description>
<content:encoded><![CDATA[
<p>I've posted in the past about using the &quot;purge&quot; command line utility on <a href="http://www.electrictoolbox.com/purge-free-inactive-memory-mac-osx/">Mac OSX to free up inactive memory</a> but a recent update appears to have broken the tool from working. An alternative is to use the FreeMemory app from the App Store to do the same thing, but more easily.</p>
<h2>Issue with purge</h2>
<p>I don't know if this affects many people or just me, because searching for the errors I get when using the purge command only comes up with a few results. Here's the error I get:</p>
<pre style="border: 1px #666 solid; padding: 10px; padding-bottom: 1em; overflow: hidden; overflow-x: auto; background: #eeeeee; font-size: 105%;">
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPAddressSpace.c:608&gt;	Unable to open user client for address space 13583, error 0xe00002bd.
[ERROR]	&lt;CPDevice.c:4013&gt;	Unable to get all available address spaces.
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPDevice.c:4252&gt;	Unable to update device instances (including replacements) for &quot;osx:Mac OS X 10.6&quot; (0x103357740), error kCPUnknownError.
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPDevice.c:3752&gt;	Unable to create new counter client.
[ERROR]	&lt;CPOSX.c:1172&gt;	Unable to get user client so as to poke the kernel.
Unable to purge disk buffers, error #-2.
</pre>
<p>It doens't matter if I run the command as myself or using sudo, I get the same error.</p>
<h2>FreeMemory app</h2>
<p>When I was browsing the App Store for free stuff, I found the FreeMemory app. It adds memory free status text to the notification area of the menu bar which, when clicked, shows usage details (free, inactive, active, wired, used, total) and has an option to free up memory. When clicked, it does just that and then tells you how much memory has been freed. Just what I wanted!</p>
<p>Here's a screenshot:</p>
<p class="imgcenter"><img alt="freememory to free inactive memory on mac osx" width="324" height="175" src="/assets/images/freememory.png" /></p>
<h2>A note about VMWare Fusion</h2>
<p>I use VMWare Fusion and one thing that really annoys me with the most recent version running on Snow Leopard is the operaing system's refusal to release the memory it consumes. I can start up a big virtual machine, shut it down and quite VMWare and the memory remains active.</p>
<p>I'm pretty sure the command line purge tool would free up that &quot;active&quot; memory (that isn't active) but unfortunately FreeMemory doesn't. It's a pain because it can make my system run slowly and the only way to actually free the memory now is to reboot.</p>
<h2>Get the FreeMemory app</h2>
<p>Either search the App Store for &quot;freememory&quot; or <a target="_blank" href="http://itunes.apple.com/nz/app/freememory/id460931672?mt=12">go here</a> for more details.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/purge-free-inactive-memory-mac-osx/'>Using purge to free inactive memory on Mac OS X</a> (Wednesday, November 17th 2010)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/c1d8uHACCk9tllTIq5E3Lzfao68/0/da"><img src="http://feedads.g.doubleclick.net/~a/c1d8uHACCk9tllTIq5E3Lzfao68/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/c1d8uHACCk9tllTIq5E3Lzfao68/1/da"><img src="http://feedads.g.doubleclick.net/~a/c1d8uHACCk9tllTIq5E3Lzfao68/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/yQLVx8BeNLw" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/free-inactive-memory-mac-freememory/</feedburner:origLink></item>
<item>
<title>Running Calendar v4 theme goes live</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/6Fig1aKKEOs/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/running-calendar-v4-theme-goes-live/</guid>
<pubDate>Mon, 16 Jan 2012 19:00:00 GMT</pubDate>
<description><![CDATA[<p>One of the websites I own is the <a href="http://www.runningcalendar.co.nz/">New Zealand Running Calendar</a>. I launched the 4th version of its template / theme yesterday and document the changes here with a couple of screenshots from the new version and the previous version, and talk about some of the changes.</p>]]></description>
<content:encoded><![CDATA[
<p>One of the websites I own is the <a href="http://www.runningcalendar.co.nz/">New Zealand Running Calendar</a>. I launched the 4th version of its template / theme yesterday and document the changes here with a couple of screenshots from the new version and the previous version, and talk about some of the changes.</p>
<h2>Homepage screenshots</h2>
<p>The first two screenshots below are of the homepage. All pages that are not in the inline popup effectively look like this with the full header at the top of the page and with advertising in the right side.</p>
<p>The differences between the v3 and v4 theme are to make the navigation more defined and more button / tab like; add social sharing links to the left of the main content area; and move the subscription buttons from above the advertising on the right side to the top right of the header area.</p>
<p><strong>Version 3 Homepage:</strong></p>
<p class="imgcenter"><img class="center" alt="running calendar v3 theme - homepage" width="600" height="374" src="/assets/images/running-calendar-20120116-v3a.png" /></p>
<p><strong>Version 4 Homepage:</strong></p>
<p class="imgcenter"><img class="center" alt="running calendar v4 theme - homepage" width="600" height="374" src="/assets/images/running-calendar-20120116-v4a.png" /></p>
<h2>Popup with event information screenshots</h2>
<p>The event page appears in an inline colorbox popup when clicking an event in the calendar lists. This means the user can easily look at an event's information, close the popup and then look at another event in the list without having to go backwards and forwards between pages. (Although see my note below about mobile / touch devices).</p>
<p>This behaviour is the same in both the v3 and v4 templates, but the widh of the popup has been increased slightly to include the social sharing buttons which again are offset to the left of the main content body.</p>
<p><strong>Version 3 inline popup:</strong></p>
<p class="imgcenter"><img class="center" alt="running calendar v3 theme - colorbox popup" width="600" height="374" src="/assets/images/running-calendar-20120116-v3b.png" /></p>
<p><strong>Version 4 inline popup:</strong></p>
<p class="imgcenter"><img class="center" alt="running calendar v4 theme - colorbox popup" width="600" height="374" src="/assets/images/running-calendar-20120116-v4b.png" /></p>
<h2>Header area</h2>
<p>The header image has been created in a way that no matter how wide the browser window is it will repeat seamlessly. The same technique was used in both versions of the theme but it was remade for version 4 with more of the runners' bodies shown.</p>
<p>Originally I reduced the height of the header area from 120px to 100px and less of the runners' bodies were showing, but it looked far too cramped at the top of the page so I returned it back to 120px.</p>
<p>The logo originally ran onto multiple lines, but I remade that as well so it would be a single line, allowing the navigation to run the full width of the template.</p>
<h2>Navigation</h2>
<p>The tabbed navigation is now database driven so I can modify it at any time. The underlying engine will be used to drive both this NZ website and an Australian version of the same website and they won't necessarily always have the same navigation, so it's important I can easily change what's in the nav without having to update hard coded links in a template. This is the same for the footer navigation.</p>
<p>There are no images used in the navigation at all; border-radius and rgba background colours are used for browsers that support them, and CSS3Pie is used for Internet Explorer &lt; 9 which do not.</p>
<h2>Social sharing buttons</h2>
<p>I've added social sharing icons to the left of the main content area. It's fixed positioned with CSS just under the header area, and uses Javascript to scroll to 5px from the top of the page as the header scrolls off the page.</p>
<p>The icons are positioned with a left margin of -75px and don't affect the layout / centering of the main content. If the browser window is wide enough (it is for 90% of the visitors to the website) they'll see it, if it's not then they won't. For example, using an iPad you won't see the social icons at all.</p>
<p>When the event page appears in an inline Colorbox popup the social icons also show, but again have a margin left of -75px so if the window isn't big enough they won't show.</p>
<h2>No colorbox for touch devices</h2>
<p>On an iPad in version 3 the popup would fill the whole screen and it wasn't easy to close the window. The site isn't optimized in any way whatsoever for mobile devices but smaller devices will have the same issue, assuming people can be bothered browsing such small content on a small device.</p>
<p>I decided mobile devices shouldn't use colorbox at all to solve this usability issue of not being able to easily close it. The easiest way to do this was to use <a href="http://www.modernizr.com/">Modernizer</a> with just touch device detection and not show colorbox for touch enabled devices.</p>
<p>I know this isn't perfect because touch devices can be big (and we'll see more of them in time e.g. Windows 8), but for now it's a good enough way to detect mobile devices as far as I am concerned and I can change it in time. In any case, it doesn't break the site if it doesn't work correctly: event links will simply load as a new page instead of in the inline popup.</p><div style="margin-top:10px; border-top:1px solid #ccc;">
<h2>Related posts:</h2>
<ul>
<li><a href='http://www.electrictoolbox.com/running-calendar-facebox-colorbox/'>Running Calendar change from Facebox to Colorbox</a> (Thursday, September 8th 2011)</li>
<li><a href='http://www.electrictoolbox.com/running-calendar-update-20101112/'>Running Calendar Update November 12th 2010</a> (Friday, November 12th 2010)</li>
<li><a href='http://www.electrictoolbox.com/new-zealand-running-calendar-goes-live/'>New Zealand Running Calendar Goes Live</a> (Sunday, April 18th 2010)</li>
</ul>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/yk7w8O7E9sq6mif9WF-GyrjycFs/0/da"><img src="http://feedads.g.doubleclick.net/~a/yk7w8O7E9sq6mif9WF-GyrjycFs/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/yk7w8O7E9sq6mif9WF-GyrjycFs/1/da"><img src="http://feedads.g.doubleclick.net/~a/yk7w8O7E9sq6mif9WF-GyrjycFs/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/6Fig1aKKEOs" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/running-calendar-v4-theme-goes-live/</feedburner:origLink></item>
<item>
<title>Assign additional users in Google Webmaster Central</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/FoD7Fqj2YNU/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/assign-additional-users-google-webmaster-central/</guid>
<pubDate>Mon, 16 Jan 2012 02:00:00 GMT</pubDate>
<description><![CDATA[<p>I needed to assign an additional verfied owner in Google Webmaster Central for a website today and forgot how to do it because it's not in a very obvious place. This post will help me remember next time if I forget again, and hopefully will help some other people too if you have the same problem.</p>]]></description>
<content:encoded><![CDATA[
<p>I needed to assign an additional verfied owner in Google Webmaster Central for a website today and forgot how to do it because it's not in a very obvious place. This post will help me remember next time if I forget again, and hopefully will help some other people too if you have the same problem.</p>
<h2>Assign additional verified owners</h2>
<p>It's possible for multiple people to take ownership of a domain in Google Webmaster Central by adding an HTML file, meta tag or DNS entry, but you can also assign ownership / verified ownership in the interface if you are already a verified owner.</p>
<p>When you've logged in to webmaster central the home page shows a list of domains you have ownership of. An example of one of the entries in my own account is in the following screenshot:</p>
<p class="imgcenter"><img alt="google webmaster central website" width="560" height="104" src="/assets/images/google-webmaster-tools-verified-users-1.png" /></p>
<p>Click the &quot;Manage Site&quot; control and a menu will appear which is shown in the screenshot above. Select the &quot;Add or remove&quot; owners option to do just that.</p>
<p>It's fairly obvious what to do on the next page as shown in the screenshot below. Click the &quot;Add Owner&quot; button to add a new verified owner, and you can remove one by clicking &quot;Unverify&quot;.</p>
<p class="imgcenter"><img alt="google webmaster central add and remove verified owners" width="560" height="336" src="/assets/images/google-webmaster-tools-verified-users-2.png" /></p>
<p><a href="http://feedads.g.doubleclick.net/~a/M7zl6wSPzHgbh854hKMXbxySpMg/0/da"><img src="http://feedads.g.doubleclick.net/~a/M7zl6wSPzHgbh854hKMXbxySpMg/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/M7zl6wSPzHgbh854hKMXbxySpMg/1/da"><img src="http://feedads.g.doubleclick.net/~a/M7zl6wSPzHgbh854hKMXbxySpMg/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/FoD7Fqj2YNU" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/assign-additional-users-google-webmaster-central/</feedburner:origLink></item>
<item>
<title>Restore the admin toolbar when logged into WordPress</title>
<link>http://feedproxy.google.com/~r/ElectricToolboxBlog/~3/sVZVm3R5RpQ/</link>
<guid isPermaLink="false">http://www.electrictoolbox.com/restore-admin-toolbar-wordpress/</guid>
<pubDate>Thu, 12 Jan 2012 00:00:00 GMT</pubDate>
<description><![CDATA[<p>I don't use WordPress myself, but one of website partners does for their blog. We recently both upgraded from WordPress 2.7 to 3.3 and changed the layout of the website and either as a result of the upgrade or the theme change, lost the admin toolbar that appears at the top of the page when logged in as as admin.</p>]]></description>
<content:encoded><![CDATA[
<p>I don't use WordPress myself, but one of website partners does for their blog. We recently both upgraded from WordPress 2.7 to 3.3 and changed the layout of the website and either as a result of the upgrade or the theme change, lost the admin toolbar that appears at the top of the page when logged in as as admin.</p>
<h2>Restore the admin toolbar when logged into WordPress</h2>
<p>This is the toolbar I'm talking about:</p>
<div style="margin: 1em 0; text-align: center;"><img alt="wordpress admin toolbar" width="600" height="28" src="/assets/images/wordpress-admin-toolbar.png" /></div>
<p>After the upgrade and changes to the template, when logged into the admin there was a blank space at the top of the page where the toolbar would normally have been previously.</p>
<p>To fix the problem, locate the footer.php file (it will be at wordpress/wp-content/themes/THEME-NAME/footer.php) and add the following before the closing &lt;/body&gt; tag:</p>
<pre class="brush: xml">
&lt;?php wp_footer(); ?&gt;</pre>
<p>This should solve the problem, it did for me.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/YriWxPxYirKkTbyJMVKMRCULnvw/0/da"><img src="http://feedads.g.doubleclick.net/~a/YriWxPxYirKkTbyJMVKMRCULnvw/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/YriWxPxYirKkTbyJMVKMRCULnvw/1/da"><img src="http://feedads.g.doubleclick.net/~a/YriWxPxYirKkTbyJMVKMRCULnvw/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/ElectricToolboxBlog/~4/sVZVm3R5RpQ" height="1" width="1"/>]]></content:encoded>
<feedburner:origLink>http://www.electrictoolbox.com/restore-admin-toolbar-wordpress/</feedburner:origLink></item>
</channel>
</rss>

