nemrod.se Various guides and experiments

Custom page listing with thumbnails for WordPress [PHP]


I have run into several cases where I need to list subpages to a certain page in a neat little list with thumbnails, mostly for listing products. Since I’ve had to reuse it several times I thought I might as well share it since others might be looking for something similar. To see it in action here are two examples (both in Swedish, but you get the idea from the visuals): Bröllopsklänningar and Begagnade båtar. As you can see they list them differently, the first lists them in a grid while the second lists them in a list with excerpts attached. The code below is the first, but it’s easily customisable, tell me if you want any help!

<?php
    $children = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_parent = $post->ID AND post_type = 'page' AND post_status = 'publish' ORDER BY menu_order", 'OBJECT');
    if($children) {
        echo '<table><tr>';
        $j = 0;
        foreach($children as $child) {
            setup_postdata($child);
            $attachment = get_posts("post_type=attachment&orderby=menu_order&order=ASC&post_parent=$child->ID");
            if($attachment) {
                $i = 0;
                for($i = 0; $i < sizeof($attachment); $i++) {
                    if('application/pdf' != $attachment[$i]->post_mime_type) {
                        $image = wp_get_attachment_thumb_url($attachment[$i]->ID);
                        break;
                    }   
                }   
            }   
            if($j && $j % 4 == 0) {
                echo '</tr><tr>';
            }   
            echo '<td>';
            echo '<h2><a href="' . get_permalink($child->ID) . '">' . $child->post_title . '</a></h2>';
            if($image) {
                echo '<a href="' . get_permalink($child->ID) . '"><img src="' . $image . '" /></a>';
            }   
            echo '</td>';
            unset($image);
            $j++;
        }   
        echo '</tr></table>';
    }   
?>

There are some minor improvements that can be made to pretty up the code – the $j variable for example I’d rather have in a for-loop and replace the foreach, but it was an addition to the code where the variable wasn’t needed at all and I haven’t been buggered to make any such changes. ;)


Posted in WordPress | Leave a comment

Breadcrumb function with heading structure for WordPress [PHP]


My coworker wanted breadcrumbs where the ancestry went from h1 all the way down to as deep as you are for one of our clients’ website, and so I wrote this little function for him:

<?php
    function hawt_breadcrumb() {
        global $post;

        $pages = array();

        $pages[] = array(get_permalink(), get_the_title());

        $parent = $post->post_parent;
        while($parent) {
            $pages[] = array(get_permalink($parent), get_the_title($parent));
            $parent = get_post($parent)->post_parent;
        }   

        $i = 1;
        foreach(array_reverse($pages) as $page) {
            echo "<h$i>$page[1]</h$i>";
            $i++;
        }   
    }   
?>

Might as well share it in case someone is in the need of something similar. :)


Posted in WordPress | 2 Comments

Automatic Daily Backup of Files & Database to USB stick


On a development project I’m working on I was challenged with the task of setting up a daily backup of code and database until the project is completed and everything is moved to a production server that has a more proper backup system in place.

The customer, with physical access to the development server, suggested daily backups to a USB stick. He also suggested that the USB stick is switched with an identical one weekly with the other one being locked up in a safe place in case of fire or theft.

My first thought was to simply create a script that copies everything to a folder where I’ve mounted the USB stick, but it didn’t take long before I realised this would mean trouble when the USB sticks are switched once a week. I considered simply adding a check to see if it’s mounted and if not mount /dev/sdb1 in the correct folder, but after switching them once I noticed that the USB stick was actually assigned to /dev/sdc this time. Solution? udev. udev, an accompanying script to mount and finally the backup script.

What udev does is react to physical devices, identified by a set of rules, being connected or disconnected from the computer with things such as creating symlinks to the device and running scripts upon detection. It’s perfect for what I want to do – create a symlink (/dev/usbackup1) so it doesn’t matter what device name the stick gets assigned, sdb or sdc, and run a script to mount it where I want (/mnt/usbackup/)!

Here’s how the new udev rules file (/etc/udev/rules.d/10-usbackup.rules) look:

KERNEL=="sd*", SUBSYSTEMS=="scsi", ATTRS{vendor}=="Verbatim", SYMLINK+="usbackup%n", RUN+="/usr/local/bin/mount_usbackup"

The first three key-value pairs (the pairs are separated by comma) are for matching the device, in this case the kernel name for the device should match “sd*”, meaning sd and any letter, it should be in the “scsi” subsystem and finally the “vendor” attribute should match Verbatim (the maker of the USB stick in this case). There are plenty other attributes to match, such as partition size and model.

The remaining two key-value pairs are the ones that do all the magic – first of all to create a symlink to the device called /dev/usbackup. The “%n” is there to instruct udev to also create symlinks to the separate partitions (/dev/usbackup1 for the first partition etcetera). It then continues to run the script in /usr/local/bin/ called mount_usbackup. All the script does is mount the device where I want it to:

#! /bin/sh
mount /dev/usbackup1 /mnt/usbackup/

Finally! We can now be sure that we always have the right device mounted exactly where we want and won’t have to worry about any switching or manual mounting. What’s left? To actually create the backup, duh.

I chose to put my script in /etc/cron.daily to run it daily, but if you want to run it on a different schedule feel free to add a new entry to crontab or any other way you see fit. My script looks like this:

#! /bin/sh
tar -C /path/to/parent/ -cjf /mnt/usbackup/projectname/code/projectname_`date +'%F'`.tar.bz2 folder/
mysqldump -uuser -ppassword database | bzip2 > /mnt/usbackup/backup/projectname/db/projectname_`date +'%F'`.sql.bz2

The first line (after the shebang) first changes directory (“-C /path/to/parent/”) so we won’t have the full structure when we unpack and then creates a .tar.bz2 archive where we mounted the USB stick of the folder we want to create a backup of (“folder/” in this case).The second line dumps the MySQL database, pipes the output to bzip2 and puts it in a file on the USB stick. Both files are named projectname_<date in Y-m-d format>.ext.bz2 so we know what day the backup was taken.

It’s really quite simple and the bzip2 makes sure the backups doesn’t take up much space. In my case the whole thing, code and database, is just under half a megabyte after compression. As you can see it’s not an incremental backup, it makes a full copy every day, but as the size is so small (in my case at least) and it’ll be moved to a production server within two months I didn’t deem it necessary to make anything more complicated.

So yeah, that was my little backup endeavour.


Posted in Guides | Leave a comment

nemLightBox – a very simple WordPress plugin


Today I decided to use an old jQuery lightbox script I wrote long ago for the thumbnails I have in some posts on this site (for example on the MacBook reed switch post or the Password Generator post) and the easiest way to do that (apart from what’s actually easiest – just including the code right in the template) is of course to make it into a WordPress plugin.

The code for the plugin is very short since it’s got very limited functionality (lightbox all image links and that’s about it), but both people interested in how a basic WordPress plugin might look and those interested in how you make a lightbox in jQuery might find this interesting nonetheless. :)

wp-content/plugins/nemlightbox/nemlightbox.php

<?php
    /*
        Plugin Name: nemLightBox
        Plugin URI: http://nemrod.se/wordpress/nemlightbox/
        Description: A very simplistic lightbox plugin - opens all image links in a lightbox
        Version: 0.1
        Author: Anders Mårtensson
        Author URI: http://nemrod.se/about/
        License: BSD
    */

    wp_enqueue_script('jquery');
    $nlb_script_url = WP_PLUGIN_URL . '/nemlightbox/nlb.js';
    $nlb_script_file = WP_PLUGIN_DIR . '/nemlightbox/nlb.js';
    if(file_exists($nlb_script_file)) {
        wp_register_script('nlb', $nlb_script_url);
        wp_enqueue_script('nlb');
    }
?>

wp-content/plugins/nemlightbox/nlb.js

$j = jQuery.noConflict();
$j(function() {
    $j('a[href$=".jpg"], a[href$=".png"], a[href$=".gif"]').click(function(event) {
        var html = '<div id="nlb"><div style="position:fixed;top:0;left:0;height:100%;width:100%;display:block;background:#000;opacity:0.7;"></div><div style="position:fixed;top:0;left:0;height:100%;width:100%;display:table;"><div style="display:table-cell;vertical-align:middle;text-align:center;"><div style="display:inline-block;background:#eee;padding:20px 20px 5px;"><img src=""><p style="font-size:12px;font-family:sans-serif;color:#333;text-decoration:underline;">Click anywhere to close</p></div></div></div></div>';
        $j('body').append(html);
        $j('#nlb img').attr('src', $j(this).attr('href'));
        event.preventDefault();
    });
    $j('#nlb').live('click', function(event) {
        $j('#nlb').remove();
        event.preventDefault();
    });
});

Click one of the links to the posts above to check it out in action. If anyone against better judgement (it really isn’t that bad though, just simplistic) wants a .zip of it so they can just install in on their blog/site I don’t mind making one, just ask and I’ll update the post.


Posted in WordPress | 1 Comment

Validera Personnummer (Swedish SSN Validator)


This post will be in Swedish since it will mainly be interesting to a Swedish audience. The code will work just the same and shouldn’t be too hard to figure out.

På ett uppdrag jag slutförde för ett tag sedan uppstod problemet att bekräfta att en person inte redan fanns registrerad i databasen. Det är givetvis rätt lätt att kolla om personnumret redan finns registrerat, men vad är det som säger att personen inte helt enkelt bestämde sig för att skriva in några slumpmässiga siffror i fältet? Inget, om du inte validerar personnumret.

Ett personnummer är uppbyggt av sex siffror för födelsedatumet, två siffror för var man föddes (innan 1990) eller ett löpnummer (efter 1990), en udda siffra för män eller en jämn för kvinnor och till sist en kontrollsiffra, som är den siffra vi måste räkna ut för att bekräfta att personnumret är giltligt utformat. Du kan läsa mer på Wikipedias artikel om personummer i Sverige.

Så här ser koden jag skrev ut:

function validateSSN($personnummer = 'yymmddxxxx') { 
    $summa = 0;  
    for($i = 1; $i < 10; $i++) { 
        $del = $personnummer[$i - 1] * ($i % 2 + 1); 
        $summa += ($del > 9 ? 1 + $del % 10 : $del); 
    }   
    return !(($summa + $personnummer[9]) % 10);
}

Självklart bekräftar inte det här att det är personens riktiga personummer och om han på liknande sätt räknar ut en kontrollsiffra för ett slumpmässigt personnummer eller gissar tillräckligt länge kommer han förmodligen att kunna komma förbi valideringen. Det är ändock en viktig validering då de flesta i min erfarenhet ger upp att “förfalska” sitt personummer när de märker att deras första slumpmässiga input inte fungerar.

Uppdatering: gjorde om det till en funktion och kortade ner koden en aning.


Posted in Projects | Leave a comment