A web developers blog
28 May
Hi all,
I’ve decided to move all of the posts etc from studioyucca.com to chris-barber.co.uk, so that it’s more personal and I can then talk about things that aren’t just purely development, so should mean I’ll be posting more often.
For now studioyucca.com will remain as an archive, but I have also moved all the posts to www.chris-barber.co.uk, so feel free to have a look.
You can also keep up to date with what I’m upto by following me on twitter
Chris.
15 Apr
Today I’ve added a small fix to the comments form on studioyucca.com as I’ve been getting around 60 SPAM comments per day recently.
In order to make things just a little bit harder for the bots, I have added a security question field, “What is 2+3?”, which will only allow a user to add a comment if they enter a ‘5′ in the box and press submit.
The code I added to the form was: (this may differ depending on your theme/styles)
<p> <label for="security"> <small>What is 2+3? (<strong>*</strong>)</small> <input type="text" name="security" id="security" value="" tabindex="3" class="TextField" style="width: 375px;" /> </label> </p>
This should be added to comments.php within your theme directory.
Then the code to check the answer for this is placed in wp-comments-post.php in the root:
if($_POST['security'] != 5) { wp_die( __('Error: please answer the security question correctly.') ); }
This isn’t a brilliant fix and it will only be temporary, but it means I don’t have to trawl through the 60 or so messages akismet has caught in it’s net just to check for any false positives.
Plus, If the bots work out the answer, I’ll change the question
30 Mar
A button that allows you to remove something is always a dangerous thing, especially if someone clicks it by accident.
To avoid problems like this, you can use a simple confirm action box:
<input type="button" value="Remove" onclick="javascript: if(confirmAction('Are you sure you wish to delete this item?')) window.location.href = '<?php print "/index.php?section=products&action=remove&product_id=10"; ?>';" />This little bit of javascript will pop up a confirmAction box that asks to user to confirm if they wish to delete the product. If they say cancel, nothing happens. If they say OK, then the page will go to the link specified.
The script to create the confirmAction box is below:
// JavaScript Document confirmAction = function(message) { if(confirm(message)) return true; return false; }
26 Mar
A simple button to go back a page in javascript:
<input type="button" value="Back" onclick="javascript: window.history.back();" />
An alternative that uses a URL instead of the history:
<input type="button" value="Back" onclick="javascript: window.location.href = '<?php print "/index.php"; ?>';" />
(Takes the user back to /index.php)
1 Feb
Flickr is an excellent way to share your photos online, having a gallery on your own website to show off these photos is an even better way to share photos with your captive audience. Today I will show you how to create a Flickr Gallery on your website showing off photos from one of your Flickr Sets.
First you will need to sign up for a Yahoo account that will allow you access to Flickr, the sign up form can be found here. Once you have signed up for an account, you will need to add your pictures. These photos will need to be arranged into Sets, this will enable us to grab the photos by the set title later on…
Now you will need to sign up for a Flickr Services API Key. This key will be used to access your photos on Flickr. In order to utilize the API methods available to us, we will use a third-party open source piece of software called phpFlickr, which can be downloaded here.
In this example, we will be creating a gallery, so in order to do this, I will use Smooth Gallery by Jon Design
Firstly, we will add the javascript and css for the gallery and initialise the gallery.
<script src="/third-party/SmoothGallery/scripts/mootools.v1.11.js" type="text/javascript"></script> <script src="/third-party/SmoothGallery/scripts/jd.gallery.js" type="text/javascript"></script> <link rel="stylesheet" href="/third-party/SmoothGallery/css/jd.gallery.css" type="text/css" media="screen" /> <script type="text/javascript"> function startGallery() { var myGallery = new gallery($('aboutGallery'), { timed: true, delay: 5000, showInfopane: false, showArrows: false, showCarousel: false, embedLinks: false }); } window.addEvent('domready', startGallery); </script> <style> #aboutGallery { margin: 5px auto; width: 500px !important; height: 260px !important; border: 1px solid #086289; background: #0e3a4e; } </style>
Now the basic work is done, we need to write the code to retrieve the photos from Flickr. Below are the basic variables we will need, such as database connection information and the flickr api key, username and title of the set we are looking to retrieve the photos from.
The reason that we need to use a database connection is because phpFlickr will then store a cache of calls made to the Flickr API, thus reducing the amount of calls that need to be made which means that Flcikr won’t disable your API Key for overuse.
define("DB_USER", "database_username"); define("DB_PASS", "database_password"); define("DB_HOST", "localhost"); define("DB_NAME", "database_name"); define("FLICKR_API_KEY", "flickr_api_key"); define("FLICKR_USER", "flickr_username"); define("FLICKR_SET_TITLE", "flickr_set_title"); include "third-party/phpFlickr/phpFlickr.php";
Now we will initialise phpFlickr, enable the cache and then retrieve a list of photo sets by the flickr user:
$f = new phpFlickr(FLICKR_API_KEY); $f->enableCache("db", "mysql://".DB_USER.":".DB_PASS."@".DB_HOST."/".DB_NAME, 7200); $nsid = $f->people_findByUsername(FLICKR_USER); $photosets = $f->photosets_getList($nsid['id']);
Now we have an array of photosets, we will run through the array looking for the specified set. First we will check to see if the photosets array is empty, if it isn’t then we will loop through them using a for loop.
If the title of the photoset is equal to the set we are looking for, it will try and retrieve the photos from the set, otherwise it will pass on to the next photoset. Once we have the photos, we will start generating the html to print out the html for the gallery. Finally we print out the html and break from the for loop.
if(!empty($photosets)) { for($i=0; $i<count($photosets['photoset']); $i++) { $setid = $photosets['photoset'][$i]['id']; if($photosets['photoset'][$i]['title'] == FLICKR_SET_TITLE) { $photos = $f->photosets_getPhotos($setid); if(!empty($photos)) { $html .= "<div id=\"aboutGallery\"> \n"; foreach ($photos['photo'] as $photo) { $html .= "<div class=\"imageElement\"> \n"; $html .= "<img src=\"".$f->buildPhotoURL($photo, "Medium")."\" class=\"full\" /> \n"; $html .= "<img src=\"".$f->buildPhotoURL($photo, "Medium")."\" class=\"thumbnail\" /> \n"; $html .= "</div> \n"; } $html .= "</div> \n"; $html .= "<br /> \n"; print $html; break; } } } }
In this example, I have modified the Smooth Gallery code to remove the carousel, arrows and infopane. I have also set the gallery to rotate through the images every 5 seconds, these were set in the javascript function at the top startGallery().
A working example can be found here. The photos were loaded from my Flickr Account.
Source code can be downloaded here.
12 Jan
At work we recently moved to a Linux / Apache powered server from our old windows server. As a result we can now take advantage of using .htaccess files rather than third party software like Helicon’s ISAPI re-write module for IIS which we were previously using.
Of course the disadvantage for this was that I had to completely relearn how I was writing the regular expressions to deal with the SEO rules when we were moving our sites across.
Start off by setting the base:
Options +Indexes +FollowSymLinks
RewriteEngine on
RewriteBase /
The Basics:
Force www. with a 301 redirect:
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
Force a trailing slash with a 301 redirect:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ http://www.example.com/$1/ [R=301,L]
Let folders pass through:
RewriteRule ^(css|admin|images|js)/$ $1/$2 [QSA,L]
Simple redirect a url to a specific file
RewriteRule ^/admin/login/$ /admin/login.php [QSA,L]
Grabbing an ID number from the url
RewriteRule ^/profile/(\d+)/$ /profile.php?profileID=$1 [QSA,L]
eg: www.example.com/profile/10/
Grabbing an name / variable from the url
RewriteRule ^/profile/([\w+-?]+)/$ /profile.php?profileName=$1 [QSA,L]
eg: www.example.com/profile/studioyucca.com/
E-commerce Style Rules
Category Product Listing Pages
RewriteRule ^([\w+-?]+)/\??(.*?) products.php?categoryName=$1 [QSA,L]
eg: www.example.com/computers/
Product Detail Pages:
RewriteRule ^([\w+-?]+)/([0-9*?|\w+-?]+)/([0-9*?|\w+-?]+)/\??(.*?) product-detail.php?categoryName=$1&brandName=$2&productName=$3&$4 [QSA,L]
eg: www.example.com/computers/apple/apple-mac-24-inch/
If you would like to know how to do anything else using .htaccess just ask and I will add it to the list.
5 Jan
Google Base allows users to upload products from their site to be included in Google’s Product Search.
If you have an E-Commerce site and store your products in a database, then you can quickly and easily automate your uploads to Google Base and just leave it to do it’s job.
Firstly, you will need to sign up for a Google Base Account.
Now you are ready to get started, firstly, we’ll set up some global variables and generate the top of the XML feed:
$insert_feed_path = "/var/www/html/studioyucca.com/google/googleinsert.xml"; $insert_xml .="<?xml version='1.0' encoding='UTF-8'?> <feed xmlns='http://www.w3.org/2005/Atom' xmlns:g='http://base.google.com/ns/1.0'> <title>StudioYucca Products Feed</title> <link rel='self' href='http://www.studioyucca.com'/> <updated>".date("Y-m-d")."T".date("H:i:s")."Z</updated> <author> <name>StudioYucca</name> </author> <id>tag:studioyucca .com,".date("Y-m-d").":/</id> ";
We will then need to retrive the products from the database using a select query whilst checking that the products are active and in stock. (here I’m using my query result to array function, details can be found here.)
$query = "SELECT * FROM products WHERE products.status = '1' AND products.qty > '0'"; $result = mysql_query($query); $products = result_array($result);
Now we have a products array, we will use a for loop to go through the products and add them into the feed:
for($k = 0; $k < count($products); $k++) { $name = trim($products[$k]['product_name']); $brand = trim($products[$k]['brand_name']); $summary = trim($products[$k]['product_description']); $expiry = date("Y-m-y", strtotime("+31 days")); $image = "http://www.studioyucca.com".trim($products[$k]['product_image_1']); $link = "http://www.studioyucca.com/products.php?product_id=".$products[$k]['product_id']; $insert_xml .= "<entry> <title>".$name."</title> <g:brand>".$brand."</g:brand> <g:condition>new</g:condition> <summary>".$summary."</summary> <g:expiration_date>".$expiry."</g:expiration_date> <id>".trim($products[$k]['product_id'])."</id> <g:image_link>".$image."</g:image_link> <link>".$link."</link> <g:price>".trim($products[$k]['product_price'])."</g:price> </entry> "; }
Now we just need to add the closing tag for the feed to the xml string and then we put the xml string into the file using the file_put_contents function.
$insert_xml .= " </feed>"; file_put_contents($insert_feed_path,$insert_xml); exit;
Now if you log into your Google account, you can set up a schedule that will retrieve this file from your server at specified intervals. Finally you will need to set up a scheduled task on your server to run this code about an hour before you have told Google to get the file. The frequency will generally depend on how often you add products, for larger sites you would be best generating the xml every day, for smaller sites, perhaps once a week.
26 Dec
We all know what an if statement in PHP looks like, but what if you wanted to make things easier, to shorten your code and make it simpler…
Let’s take the following example, You wish to print out if a user has signed up to a mail shot in some sort of admin area:
if($user['mailing_list'] == 1) { print "yes"; } else { print "no"; }
Wouldn’t it be nicer to reduce this down:
print ($user['mailing_list'] == 1)?("yes"):("no");
The syntax of the one line if statement goes as follows:
(condition) ? ( do this if the condition is true ) : ( else do this )
22 Dec
Here is a quick little function that will enable you to remove extra words above a specified word limit in PHP. This would be perfect for printing out a small description of a product, or the starting words of a news item with “…..” added on the end and a “Read More” link.
function substr_words($str, $start, $limit) { $words = array_filter(explode(" ", $str)); $str = ""; for($i=$start; $i<$limit; $i++) { $str .= $words[$i]." "; } return trim($str); }
The function takes 3 paramters, the string ($str), the start position ($start) and the word limit ($limit).
First, the function explodes the string using spaces as the string separator and then filters the array using the array_filter function. Once this is complete it empties the string and uses a for loop to go through the array of words and add them back into the string. The for loop starts in the starting position and stops when it reaches the limit. The function then returns the word limited string.
Usage:
$str = "This is a test string. Can you see these words?"; print substr_words($str, 0, 5); // Prints out: "This is a test string." print substr_words($str, 0, 8)."...."; // Prints out: "This is a test string. Can you see....