Desktop tidy

December 3rd, 2014

A cluttered desktop can be a problem, typically people use the desktop becuase they know the location of the files should they have downloaded them from somewhere, and need to reuse them quickly.

I have written a script that runs on Linux that cleans the desktop up on a daily basis, by moving all the files into a folder with an easily readable date name within an archive folder, so that your desktop remains clean and ordered, and you also do not lose your files.

The beauty of this is that you can configure your applications to point at the desktop, safe in the knowledge that all the clutter from today will be gone tomorrow, and placed neatly within a folder with the date so you can find it, when somebody says “I sent it to you Tuesday”

Just run the script below and it will automatically install, any clutter on the Desktop will archive to folder with yesterday’s date found within the Archive folder located on the Desktop.

You can download it here after unzipping, simply install using terminal with:

sudo chmod a+x desktop-tidy-install.sh
sudo ./desktop-tidy-install.sh

The source code is below:

#!/bin/bash
########################
#
#
# Install script
# For Desktop tidy, compat with any distro running Gnome 3, tested on fedora 20
#
# Adrian callaghan 02-12-2014
#
#
########################

########################
# are you capable?
if [[ $(/usr/bin/id -u) -ne 0 ]]; then
	echo "You must run this install script with super user privileges, use either sudo or become root with su -"
	exit;
fi

########################
# enviroment
user=$SUDO_USER;
userhome="/home/$user";
scriptPath="/usr/local/bin/dt.sh";
autostartFile="dt.desktop";
desktop="$userhome/Desktop";
archive="$desktop/Archived";

########################
# reinstall?
if [ -f "$scriptPath" ] || [ -f "$autostartPath" ]; then
	echo "Removing previous install"
	if [ -f "$scriptPath" ]; then
		rm "$scriptPath"
	fi
	if [ -f "$autostartPath" ]; then
		rm "$autostartPath"
	fi
fi

########################
# create archive folder if none exists, permissions follow later
if [ ! -d "$archive" ]; then
	mkdir "$archive"
fi

########################
# create script
echo "#!/bin/bash" > $scriptPath;
echo "archive=$archive" >> $scriptPath;
echo "desktop=$desktop" >> $scriptPath;
echo 'curr_archive="$archive/$(date +"%d-%B-%Y" -d "1 day ago")";

# if has not been archived yet, archive
if [ ! -d "$curr_archive" ]; then

	mkdir "$curr_archive";

 	for file in $desktop/*; do
		if [ "$file" != "$archive" ]; then
			mv "$file" "$curr_archive"
		fi
	done
fi
' >> $scriptPath;
chmod 755 $scriptPath
chown "$user:$user" $scriptPath

########################
# Add autostart
if [ ! -d "$userhome/.config" ]; then
	mkdir "$userhome/.config"
fi
if [ ! -d "$userhome/.config/autostart" ]; then
	mkdir "$userhome/.config/autostart"
fi
echo "[Desktop Entry]
Name=DeskTidy
GenericName=Creates a daily desktop
Comment=Allows the user to have a clean desktop daily and keep the all the files in an ordered fashion
Exec=$scriptPath
Terminal=true
Type=Application
X-GNOME-Autostart-enabled=true
" > "$userhome/.config/autostart/$autostartFile";
chmod 755 "$userhome/.config/autostart/$autostartFile"
chown "$user:$user" "$userhome/.config/autostart/$autostartFile"

#########################
# Trigger script!
#
source "$scriptPath"
chmod "1775" "-R" "$archive"
chown "root:$user" "-R" "$archive"

#########################
# FEEDBACK
echo "!! Desktop Tidy successfully installed !!"
echo "When you login a desktop will be created based on todays date"
echo "Should you wish to retrieve an old file, archives can be found at $archive and are named by date"
VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
100 views

Zend framework 2 restful CMS

August 26th, 2014

Based on ZF2 Skeleton and the Album tutorial, this ZF2 application extends this further by migrating fully to Doctrine2 and adding comments for Albums as an association.

The source code is on GitHub and below is how to set the example up

Dynamic modules

There is provision for Dynamic Modules & layouts, seperating the various layers.

Restful service using put/get/post & delete

The default module has routing setup with a top bar navigation, along with a GUI to demonstrate an AJAX RESTful service.

A RESTful service is in place, that is contained within its own module to serve the Albums and comments objects as Create, Update, Delete and List to the default application.

CMS module

A CMS module is in place that uses identity persistance and Zend Auth to authenticate the users, the login forms and validation are all handled.

The CMS users can be created and managed, the CMS also has independent Navigation from the default route, along with CRUD services for the albums & comments services.

Form validation & Flash Messages

Twitter bootstrap has been intergrated into the CMS, so Flash Messages and form validation are all displaying within a bootstrap enviroment.

HOSTING STRUCTURE

  • Folder structure is /NAMEOFNEWPROJECT/public/
  • Public is the Document-root for the server.
  • Public should not be present prior to cloning from GIT, but setup in the host file
INITIAL SETUP
cd ../NAMEOFNEWPROJECT
git clone https://github.com/adriancallaghan/cmszend2.git NAMEOFNEWPROJECT  (will clone the project into the new project)
cd NAMEOFNEWPROJECT
mv config/autoload/examplelocal.php config/autoload/local.php
nano config/autoload/local.php (set database credientials)
php composer.phar self-update
php composer.phar install
./vendor/bin/doctrine-module orm:schema-tool:create
git remote rm origin
git init
git add *
git commit -m "first commit"
git remote add origin https://github.com/NEW-GIT-REPO-LOCATION.git
git push -u origin master
UPDATE USING GIT/COMPOSER & DOCTRINE2
git pull
php composer.phar install
./vendor/bin/doctrine-module orm:schema-tool:create./vendor/bin/doctrine-module orm:validate-schema
UPDATE DB IF NECESSARY (Caution it can cause the db to flush)
./vendor/bin/doctrine-module orm:schema-tool:update --force
Cms access

You need to add a username, active (true) boolean and (md5) password combination into the cmsuser table in order to be able to login to the cms. The password can be easily md5′d on the cmd line with something like

php -r 'echo md5("SOME PASS");'
VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
4,482 views

Bash script to create virtual hosting in Fedora

August 15th, 2014

I am often needing to add a script to create virtual hosting, below is one I have written for fedora (that can be altered for any distro) that creates the necessary folder structure, vhost host entries and restarts Apache.

#!/bin/bash

#################################
# SETTINGS LOCATIONS
WWW_ROOT='/var/www' # no trailing slash
DOC_ROOT='httd_docs' # no trailing slash

# SETTINGS TEMPLATE FILE
INDEX_MSG='HOSTING READY FOR <DN>' # <DN> WILL BE REPLACED WITH THE DOMAIN
INDEX_FILE='index.html'

# SETTINGS DIRECTORY PERMISSIONS
DIR_OWNER='apache'
DIR_GROUP='apache'
DIR_MOD='770'

# APACHE (FEDORA)
APACHE_RELOAD='service httpd restart' # cmd to reload/restart apache
APACHE_CONF_LOCATION='/etc/httpd/conf/httpd.conf' # no trailing slash
APACHE_CONF_TEMPLATE="
# <FQDN>
<VirtualHost *:80>
    ServerAdmin webmaster@<DN>
    ServerName <FQDN>
    ServerAlias <DN>

    DocumentRoot <DN_ROOT>
    ErrorLog /var/log/httpd/<DN_SLUG>-apache-error_log
    CustomLog /var/log/httpd/<DN_SLUG>-access_log common
</VirtualHost>"; # <DN> WILL BE REPLACED WITH THE DOMAIN, FQDN WITH THE FQDN, DN_SLUG WITH THE DOMAIN SLUG AND DN_ROOT WITH DOCUMENT ROOT

# HOSTS FILE
HOSTS_FILE='/etc/hosts'
#################################

#################################
# FUNCTIONS
function notice() {
        echo "============================================================================================================"
        echo $1
        echo "============================================================================================================"
}

function slugify(){
	echo $* | sed 's/^dl-*//ig' | tr '[:punct:]' '-' | tr '[:upper:]' '[:lower:]' | tr -s '[:blank:]' '[\-*]'
}
#################################

#################################
# START
if [[ $(/usr/bin/id -u) -ne 0 ]]; then
	notice "You must be root to run this script"
else
	# GET DN AND FQDN
	notice "Please enter the domain name"
	read DN
	DN="${DN/#\www./}"
	FQDN="www.$DN"

	# BEGIN
	host $DN 2>&1 > /dev/null
	if [ ! $? -eq 0 ]; then
		echo "$DN is not valid domain"
	else
		DN_SLUG=$(slugify "$DN");
		if [ -d "$WWW_ROOT/$DN_SLUG" ]; then
			notice "$DN already exists in $WWW_ROOT/$DN_SLUG"
		else
			# MAIN STRUCTURE
			mkdir "$WWW_ROOT/$DN_SLUG"
			mkdir "$WWW_ROOT/$DN_SLUG/$DOC_ROOT"
			echo "${INDEX_MSG//<DN>/$FQDN}" > "$WWW_ROOT/$DN_SLUG/$DOC_ROOT/$INDEX_FILE"

			# OWNERSHIP
			chown -R "$DIR_OWNER:$DIR_GROUP" "$WWW_ROOT/$DN_SLUG"
			chmod -R "$DIR_MOD" "$WWW_ROOT/$DN_SLUG"

			# QUICK LOOK UP LOCALLY
			HOSTS_FILE_BK="$(date +$HOSTS_FILE-%d%m%Y_%R.bak)";
			cp "$HOSTS_FILE" "$HOSTS_FILE_BK";
			if [ ! -f "$HOSTS_FILE_BK" ]; then
				notice "Failed to create host file backup at $HOSTS_FILE_BK"
			else 

				echo "# ${FQDN}" >> "$HOSTS_FILE";
				echo 127.0.0.1   ${DN} >> "$HOSTS_FILE";
				echo 127.0.0.1   ${FQDN} >> ""$HOSTS_FILE"";

				# APACHE ENTRIES
				APACHE_TEMPLATE="${APACHE_CONF_TEMPLATE//<DN>/$DN}";
				APACHE_TEMPLATE="${APACHE_TEMPLATE//<FQDN>/$FQDN}";
				APACHE_TEMPLATE="${APACHE_TEMPLATE//<DN_ROOT>/$WWW_ROOT/$DN_SLUG/$DOC_ROOT/}";
				APACHE_TEMPLATE="${APACHE_TEMPLATE//<DN_SLUG>/$DN_SLUG}";
				APACHE_CONF_LOCATION_BK="$(date +$APACHE_CONF_LOCATION-%d%m%Y_%R.bak)";
				cp "$APACHE_CONF_LOCATION" "$APACHE_CONF_LOCATION_BK";
				if [ -f "$APACHE_CONF_LOCATION_BK" ]; then
					echo "$APACHE_TEMPLATE" >> $APACHE_CONF_LOCATION;
					$APACHE_RELOAD;
					notice "$DN created at $WWW_ROOT/$DN_SLUG (apache bkup file found at $APACHE_CONF_LOCATION_BK)"
				else
					notice "Failed to create Apache config backup at $APACHE_CONF_LOCATION_BK"
				fi
			fi
		fi
	fi

fi
read STOP
exit;
################################
VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
3,584 views

ZF2 different layouts in modules

June 4th, 2013

To enable a different layout in a module, to your module.php for the module define a new layout like so

public function init(ModuleManager $mm)
    {
        $mm->getEventManager()->getSharedManager()->attach(__NAMESPACE__, 'dispatch', function($e) {
            $e->getTarget()->layout('admin/layout');
        });
    }

then within your module.config.php view_manager settings define the template

'view_manager' => array(
        'template_map' => array(
            'admin/layout'           => __DIR__ . '/../view/layout/cms.phtml',
        ),
        'template_path_stack' => array(
            __DIR__ . '/../view',
        ),
    ),

or you can define a direct path in your module.php without any template mapping i.e

public function init(ModuleManager $mm)
    {
        $mm->getEventManager()->getSharedManager()->attach(__NAMESPACE__, 'dispatch', function($e) {
            $e->getTarget()->layout('layout/admin');
        });
    }

This will load module/view/layout/admin.phtml when this module is run

VN:F [1.9.9_1125]
Rating: 4.3/10 (4 votes cast)
VN:F [1.9.9_1125]
Rating: -1 (from 1 vote)
8,510 views

Galaxy S3 no internet on virgin media super hub

March 17th, 2013

Samsung galaxy S3 will not connect to virgin media super hub can be a problem, I found mine would connect but had no internet – and everything else on the network did.

After several hours of looking through forums, rebooting and changing settings, I found the issue to be with the hub itself, for some reason in Advanced-settings>DHCP>DHCP Reservation I found the mobile was being addressed on a strange IP like 10.125.x.x.x and not the one it had been allocated by DHCP.

I took note of the mac and device name in the IP Lease table, switched off the WIFI on the mobile (disconnecting it from the router), hit refresh to make sure it was no longer listed in the IP lease table.

Next I added a reservation entry to the the lease table for the device, using its mac and device name, and bound it to an IP that was not being used.

Voila.. Internet on the S3

VN:F [1.9.9_1125]
Rating: 6.0/10 (1 vote cast)
VN:F [1.9.9_1125]
Rating: 0 (from 2 votes)
6,420 views

Remote controlling Tivo

October 21st, 2012

I was interested in what my ethernet port was doing on my virgin media TIVO box, so I ran some tests and found I could control my TIVO box from my laptop, here are my findings.

First, I went into the Tivo boxes settings on screen and enabled network access.

Next, I logged into my home hub/router to find out what IP address it had been allocated
http://192.168.100.1/ and clicked devices.

Once I had its IP address, (192.168.0.7) I scanned its ports and found the following services:

adrian@adrian-laptop:~$ nmap 192.168.0.7
 
Starting Nmap 5.00 ( http://nmap.org ) at 2012-10-21 10:37 BST
Interesting ports on 192.168.0.7:
Not shown: 997 filtered ports
PORT     STATE SERVICE
443/tcp  open  https
2190/tcp open  unknown
2191/tcp open  unknown
 
Nmap done: 1 IP address (1 host up) scanned in 5.50 seconds

The obvious one that stands out is port 443, so visiting https://192.168.0.7/ shows a web server requesting login, I found that the username is tivo and the password is your media key found in settings > mediakey.

Once logged in, a list of recorded programmes will be displayed but however streaming and downloading are disabled :( .

I tried for sometime to circumvent the streaming restriction using various techniques the closest I came was with VLC and special plugins http://tivo-vlc.sourceforge.net/notes.php#install, but so far I haven’t been able to achieve this.

I looked into what the box is, and it turns out its fundamentally Linux box with a glossy coat, with some features disabled (like streaming something to do with UK copyright laws).

Along the way I found I could telnet to port 31339 on the box

telnet 192.168.0.7 31339

which responded with

CH_STATUS 0213 RECORDING

This is the status of the two tuners, and what they are doing, you can now use commands like:

Code:
KEYBOARD (Dunno what this does)

TELEPORT <PLACE>- e.g TIVO, LIVETV, GUIDE, and NOWPLAYING.

SETCH <CHANNEL> - Change channel. If the current tuner is recording a program, it will change the other tuner. If both tuners are recording, the TiVo will respond with "CH_FAILED RECORDING <Title>. Using this command while Tivo is replaying will give "CH_FAILED NO_LIVE".

FORCECH <CHANNEL> - This command will force the current tuner to the tune the desired channel regardless of what it's doing. If a recording is being recorded it will cancel the recording and change the channel without confirmation.

Also a complete set of IRCODE’s exist

Code:
IRCODE <COMMAND>

a quick google and I found the following IRCODE commands that seem to work.

UP
DOWN
LEFT
RIGHT
SELECT
TIVO
LIVETV
THUMBSUP
THUMBSDOWN
CHANNELUP
CHANNELDOWN
RECORD
DISPLAY
DIRECTV
NUM0
NUM1
NUM2
NUM3
NUM4
NUM5
NUM6
NUM7
NUM8
NUM9
ENTER
CLEAR
PLAY
PAUSE
SLOW
FORWARD
REVERSE
STANDBY
NOWSHOWING
REPLAY
ADVANCE
DELIMITER
GUIDE

Typing these commands into the telnet session, made the tivo box change channel etc…. cool!

To exit the telnet session press

Code:
CTRL + ]

thats right, control and right square bracket!!, then type quit at the prompt

I was able to source a nice GUI that can automate these commands https://github.com/wmcbrine/tivoremote

So, as long as you have Python installed (Mac & linux users by default), just running the script produces a nice GUI that can manage your Tivo box from your laptop.

I also found, if your interested in developing apps for it, its SDK is written for AS3 and can be found here http://developer.tivo.com/

VN:F [1.9.9_1125]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
10,054 views

form to database php

October 15th, 2012

I have written a collection of classes, that are capable of accepting a submission from a get (REST) or post (form) and output them to an email, the screen or to a database table.

The class can be used to output a CSV, an email or XML (REST).

The code is very straight forward for example create a form.html and add the following.

<form method="post" action="save.php">
  <label for="firstname">Firstname</label>
  <input type="text" name="firstname" id="firstname"><br>
  <label for="surname">Surname</label>
  <input type="text" name="surname" id="surname"><br>
  <input type="submit" value="Submit">
</form>

This form will submit to save.php, we need to now create this, create the file save.php and add the following

require_once('classes.php'); // load the classes

This loads the classes, and is required to make this work, next

        listener::getInstance();

Gets an instance of the listener, the listener has the responsibility of handling the data, it sets a number of values by default, one of which is the default submission type (GET) this needs to be changed to POST, so

        listener::getInstance()->method('POST');

Next, the listener needs to know which fields are valid fields, otherwise every bit of junk somebody sends to this script will be placed into the database, this is done in the form of an array, with the array key being the fieldname, and the value being whether or not is it required, if a field is defined as required and not codesent, the submission will fail with an error.

array(
    'firstname'=>true
    'surname'=>true
)

tell the listener about these fields

        listener::getInstance()
                ->method('POST')
                ->setFields(
                        array(
                            'firstname'=>true
                            'surname'=>true
                            )
                        );

next we have to define, what we wish to do with the submission, in this case, save it to a database, first get the database instance.

database::getInstance();

by default, the database will default to certain values, typically it will connect with the username “root”, password “”, database “data”, host “localhost”, table called “submissions” and the field “submitted”.
if you need to change any of these values, it can be done by setting a config of type stdConfig with an array of new parameters.
If you do not decalre say a username, it just defaults, the avaialble fields are: username, password, database, table, field and host

database::getInstance()->setConfig(
                        database::stdConfig(
                                array(
                                    'password'=>'1234'
                                    )
                                )
);

The database instance is placed in setAction like this:

        listener::getInstance()
                ->method('POST')
                ->setFields(
                        array(
                            'firstname'=>true
                            'surname'=>true
                            )
                        )
                ->setAction(
                    database::getInstance()->setConfig(
                        database::stdConfig(
                                array(
                                    'password'=>'1234'
                                    )
                                )
                    )
                );

Next we need some sort of feedback, about whether or not it was successful, this can be done by asking the instance what happened, for example:

// some visual feedback
if (listener::getInstance()->success){
     echo 'Thankyou!';
} else {
     echo 'The following problems were encountered';
     print_r(listener::getInstance()->errors);
}

Lets put it all together!, complete code below:

 
        require_once('classes.php'); // load the classes
 
        listener::getInstance()
                ->method('POST')
                ->setFields(
                        array(
                            'firstname'=>true
                            'surname'=>true
                            )
                        )
                ->setAction(
                    database::getInstance()->setConfig(
                        database::stdConfig(
                                array(
                                    'password'=>'1234'
                                    )
                                )
                    )
                );
 
// some visual feedback
if (listener::getInstance()->success){
     echo 'Thankyou!';
} else {
     echo 'The following problems were encountered';
     print_r(listener::getInstance()->errors);
}

You will need the class library found in here (right click save as)

Should you require a REST service, a wrapper is included to output the response as xml, for example:

<?php
require_once('classes.php'); // load the classes
 
Output::toXml(
        listener::getInstance()
                ->setFields(
                        array(
                            'bob'=>true
                            )
                        )
                ->setAction(
                    database::getInstance()->setConfig(
                        database::stdConfig(
                                array(
                                    'password'=>'1234'
                                    )
                                )
                    )
                )
            );
 
//foreach(listener::getInstance()->errors AS $err) echo $err;

to get the submissions as a Csv, similiarly:

<?php
require_once('classes.php'); // load the classes
 
Output::toCsv(
        database::getInstance()->setConfig(
            database::stdConfig(array('password'=>'1234'))
            )->fetchAll()
        );
 
//echo database::getInstance()->error;

A rest Example can be found here, along with the ability to CSV export

VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
4,990 views

thickdialog

June 20th, 2012
Jquery dialog can be made to work as a either an ajax form, a dialog box or confirmation box just by use of a class similair to the way in which thickbox used to work (the examples work perfectly outside of wordpress).

ThickDialog examples

Download

Simple thickbox style popup

Popup example
code:

<a href="/demos/thickdialog/popup.html" title="A pop up" class="dialog-box">Popup example</a>

usage: add the class “dialog-box” to make this work

Simple thickbox style confirmation box

Confirm example
code:

<a href="/demos/thickdialog/delete.html" title="Are you sure?" class="dialog-confirm">Confirm example</a>

usage: add the class “dialog-confirm” to make this work

Simple thickbox style form submission

Form example
code:

<a href="/demos/thickdialog/form.php" title="Please complete" class="dialog-confirm">Form example</a>

usage: add the class “dialog-form” to make this work

VN:F [1.9.9_1125]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.9_1125]
Rating: +1 (from 1 vote)
2,234 views

jquery ui ajax form thickbox

June 20th, 2012
Jquery dialog can be made to work as a ajax form in a similair way to thickbox.

The link to the form (such as registration form), can be made to load inside a popup, and loaded using ajax by simply adding a class to the href.

For example this link could perform a registration, just like thickbox used to behave adding the class ‘dialog-form’ (the title is used to title the form popup) loading the content on submission.

<a href="/demos/thickdialog/form.php" class="dialog-form" title="Register">register</a>

Example: register

In order to do this you will need Jquery, and Jquery-UI and the code below.

Alternatively I have written a library called thickdialog which supports the form, confirmation box and pop ups just by adding a simple class, which is compatible with any framework and can be downloaded from there.

// form pop ups, just give an anchor point the class dialog_form, and the title will be used as the title 
$(function (){
 
    function submitBind(layout,original_url){
 
        $(layout).find('form').submit(function(event){
 
            /* stop form from submitting normally */
            event.preventDefault(); 
 
            url = $(this).attr('action')=='' ? original_url : $(this).attr('action');                    
 
            /* Send the data using post and put the results in a div */
            $.post(
                url,
                $(this).serialize(),
                function(data) {
 
                    $('#dialog').empty();
                    $('#dialog').append(data);
                    $('#dialog').dialog('option', 'position', 'center');
                    submitBind(layout, original_url);
                });
 
        }); 
 
    }
 
 
    $('a.dialog-form').click(function() {
 
        var original_url = this.href;
        var title = this.title;
        // show a spinner or something via css
        var dialog = $('<div id="dialog" style="display:none" class="loading">Loading</div>').appendTo('body');
        // open the dialog
        dialog.dialog({
 
            width: dialogBox_width,
 
            // add a close listener to prevent adding multiple divs to the document
            close: function(event, ui) {
                // remove div with all data and events
                dialog.remove();
            },
            modal: true
        });
 
        // load remote content
 
        dialog.load(
            original_url,
            function (responseText, textStatus, XMLHttpRequest) {
                // remove the loading class
                dialog.removeClass('loading');
                dialog.dialog('option', 'position', 'center');
                dialog.dialog('option', 'title', title);
 
                submitBind(this,original_url);
 
            }
        );
        //prevent the browser to follow the link
        return false;
    });
});
VN:F [1.9.9_1125]
Rating: 6.3/10 (3 votes cast)
VN:F [1.9.9_1125]
Rating: -2 (from 2 votes)
5,427 views

jquery confirmation box thickbox

June 20th, 2012
Jquery dialog can be made to work as a confirmation box in a similair way to thickbox.

The link to the action (such as deletion), can be made to display a confirmation box before it completes, by simply adding a class to the href.

For example this link could perform a deletion, just like thickbox used to behave adding the class ‘dialog-confirm’ (the title is used to title the dialog confirm) will request the user to confrim firstly.

<a href="/demos/thickdialog/delete.php" class="dialog-confirm" title="Are you sure about this?">delete</a>

Example: delete(example works fine outside of wordpress)

In order to do this you will need Jquery, and Jquery-UI and the code below.

Alternatively I have written a library called thickdialog which supports the confirmation box, pop ups and forms just by adding a simple class, which is compatible with any framework and can be downloaded from there.

// confirm box, add the class dialog-confirm and a title and it does the rest
$(function (){
    $('a.dialog-confirm').click(function() {
 
        var url = this.href;
        var dialog = $('<div id="dialog" style="display:none" title="Are you sure?">'+this.title+'</div>').appendTo('body');
 
        dialog.dialog({
            resizable: false,
            height:confirmBox_height,
            modal: true,
 
            buttons: {
                    "Yes": function() {
                            $(this).dialog( "close" );
                            window.location.href = url;
 
                    },
                    "No": function() {
                            $(this).dialog( "close" );
                    }
            }
        });
 
        dialog.dialog('option', 'position', 'center');
 
        //prevent the browser to follow the link
        return false;
    });
});
VN:F [1.9.9_1125]
Rating: 8.0/10 (1 vote cast)
VN:F [1.9.9_1125]
Rating: +2 (from 2 votes)
3,076 views

Jquery dialog thickbox

June 20th, 2012
Jquery dialog can be made to work in a similair way to thickbox.

Any link to content, can have its content loaded into a jquery dialog box, by simply adding a class to the href.

For example this standard page can be made to behave like a thickbox pop-up by adding the class ‘dialog-box’ (the title is used to title the dialog box).

<a href="/demos/thickdialog/page.php" class="dialog-box" title="popup">popup</a>

Example: popup (example works fine outside of wordpress)

In order to do this you will need Jquery, and Jquery-UI and the code below.

Alternatively I have written a library called thickdialog which supports the popups, confirmation boxes and forms just by adding a simple class, which is compatible with any framework and can be downloaded from there.

// pop ups, just give an anchor point the class dialog_box, and the title will be used as the title 
$(function (){
    $('a.dialog-box').click(function() {
        var url = this.href;
        var title = this.title;
        // show a spinner or something via css
        var dialog = $('<div id="dialog" style="display:none" class="loading">Loading</div>').appendTo('body');
        // open the dialog
        dialog.dialog({
 
            width: dialogBox_width,
 
            // add a close listener to prevent adding multiple divs to the document
            close: function(event, ui) {
                // remove div with all data and events
                dialog.remove();
            },
            modal: true
        });
 
        // load remote content
        dialog.load(
            url, 
            {}, // omit this param object to issue a GET request instead a POST request, otherwise you may provide post parameters within the object
            function (responseText, textStatus, XMLHttpRequest) {
                // remove the loading class
                dialog.removeClass('loading');
                dialog.dialog('option', 'position', 'center');
                dialog.dialog('option', 'title', title);
 
            }
        );
        //prevent the browser to follow the link
        return false;
    });
});
VN:F [1.9.9_1125]
Rating: 7.0/10 (3 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
8,277 views

javascript image rotation

January 9th, 2012

Very simple class that rotates images on any event, on any target element (with a preloader).

Click here for an example.

To use it yourself (how the example works):

1. include jquery and the class

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="galleryRotate.js"></script>

2. Instantiate the class with an array of images

$images = ['1.jpg','2.jpg','3.jpg'];
var rotator = new GalleryRotate($images);

3. bind the objects change method to an event, such as mouseclick, telling it the name of target element (always done once the webpage is ready)

$(document).ready(function(){
 
	// click the image
	$('#button').click(function(){
		return rotator.change('#img');
	});
});

Once again an example can be found here.

The full source code can be downloaded here.

The class code is very straight forward and below for completeness.

function GalleryRotate ($images){  
 
	this.preload = function () {
	    $(this.images).each(function(){
	        $('<img/>')[0].src = this;
	    });
	}
 
	this.change = function($element){
 
		$img = this.images[this.imgNo];
 
		if ($element){
			$($element).attr("src", $img);
		}
		else alert($img);
 
		this.imgNo++;
 
		if (this.imgNo==this.images.length){
			this.imgNo=0;
		}
 
		return false;
	}
 
	this.init = function ($images) {
		this.images = $images;
		this.imgNo=0;
		this.preload();	
	}
 
	this.init($images);
}
VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
2,176 views

adding password authentication for a zend cms or controller

December 13th, 2011

This is a very quick way to add password protection to a controller such as a cms controller.

This code intercepts the login within the init() method of your chosen controller, if they are logged in they are free to go, if not they are required to login, the form is rendered and validated against the access model.

The session is obfuscated to deter tampering.

so firstly in your controller init() add

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$adminSession = new Zend_Session_Namespace('Admin');
$this->access = new Application_Model_accessControl(); // access control
 
// logged in user
$loginMsg = 'Please login';
$loginForm = new Zend_Form;
$loginForm
	->setMethod('post')
	->setAttrib('id','login')
	->addElement('text','user',array('label'=>'Username','required'=>true))
	->addElement('password','pass',array('label'=>'Password','required'=>true))
	->addElement('submit','Login');
 
if ($this->getRequest()->isPost() && $loginForm->isValid($_POST)){
	$session = $this->access->validateUser(
		$loginForm->getValue('user'), 
		$loginForm->getValue('pass')
		);
 
	if ($session){
		$adminSession->loggedInSession = $session;
		$adminSession->loggedInUser = $loginForm->getValue('user');
	}
 
	$loginMsg='Access denied';
} 			
 
if (!$this->access->sessionIsValid($adminSession->loggedInSession) || !$adminSession->loggedInUser){
       	$this->view->header=$loginMsg;			
	$this->view->content = $loginForm;
	$this->render('login');  
} else {
	// renew session, will always be the "Now" session, but three are provided, see the model 
	$adminSession->loggedInSession = $this->access->getValidSession();
    	$this->view->userIdent = $adminSession->loggedInUser;
}

$this->view->userIdent will always contain the logged in user

The next step is to create the model for authentication in models/accessControl.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
 
class Application_Model_accessControl
{
 
 
	public function __construct(){
 
		// set users, password is the key, because this is less likely to be duplicated
        $this->setUsers(
        	array(
				'password1'=>'admin',
				'password2'=>'admin'
				)
       		);
        // salt for session key
		$this->setSalt('MySaltGoesHere1234');
	}
 
	public function validateUser($username, $password){
 
		/*
		 * return session if correct, null otherwise
		 */
 
		$users = $this->getUsers();
 
		if (isset($users[$password]) && $users[$password]==$username){
			return $this->getValidSession();
		}
	}
	public function sessionIsValid($session,$debug=false){
 
		$validSessions = $this->getValidSessions();
		if ($debug){
			echo "MY KEY: $session<br >KEYS: ".print_r($validSessions,true);
		}
		return in_array($session, $validSessions) ? true : false;
	}
 
	public function getValidSessions(){
 
		$sessions = array(
			$this->getValidSession('past'),
			$this->getValidSession('now'),
			$this->getValidSession('future')
			);
 
		return $sessions;
	}
	public function getValidSession($for='now'){
 
		/*
		 * Three sessions are provided,
		 * 
		 * past, now and present
		 * 
		 * past, person logs in at 11:59 spends ten minutes editing, clicks save at 12:09, past would be the valid session
		 * now, person is logged in during 11:00 - 11:59
		 * future, is provided encase of time travel, or if the british summer time kicks in while editing, unlikely but more is better than not enough...
		 */
 
		$hour = intval(date('H'));
 
		switch($for){
			case 'past' : 
				$validSession = ($hour-1) < 0 ? 23 : $hour-1;
			break;
			case 'now' : default:
				$validSession = $hour;
			break;
			case 'future' : 
				$validSession = ($hour+1) > 23 ? 0 : $hour+1;
			break;
 
		}
 
		/*
		 * obsfucation
		 */
		// firstly grab specific details to stop session hijacking 
		$ip = $_SERVER['REMOTE_ADDR'];
		$browser = $_SERVER['HTTP_USER_AGENT'];
		// then mix it up and md5 it
		$validSession = $ip.$validSession.$this->getSalt().$browser;
 
		if (!getenv('APPLICATION_ENV')){
			$validSession = md5($validSession);
		}
 
		return $validSession;
	}
 
	public function setUsers($users){
		$this->users = $users;
	}
	public function getUsers(){
		return $this->users;
	}
	public function setSalt($salt){
		$this->salt = $salt;
	}
	public function getSalt(){
		return $this->salt;
	}
 
 
}

and finally create a view login.phtml (this is just bare bones)

1
2
<?php echo "<h2>{$this->header}</h2>";  ?>
<?php echo $this->content;  ?>

Thats it!

VN:F [1.9.9_1125]
Rating: 8.3/10 (3 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
3,940 views

session_start hangs when it used to work

December 13th, 2011

I had a problem with my zend application hanging with a white screen for no reason.
I narrowed it down to when

1
$adminSession = new Zend_Session_Namespace('Admin');

was executed, this is just a session? so debugging further, confirmed that session_start() hangs when it used to work.

There are lots of explanations for this, but before you start modifying ini settings, just try this

1
2
3
session_write_close();
session_start();
die(print_r($_SESSION,true));

I found this resolved the problem completely.
I then just removed this debug-code and went back to developing my zend app.

VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: +1 (from 1 vote)
1,294 views

ckeditor to upload images

September 19th, 2011

A few posts on how to do this, and a lot of frustrated people so here is how:

Download both ckeditor and ckfinder.

Decompress them into the root directory.

Include them in your php

include_once ‘ckeditor/ckeditor.php’;
include_once ‘ckfinder/ckfinder.php’;

hopefully no error messages? ok cool…. now simply

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
 
$ckeditor = new CKEditor();
$ckeditor->basePath = '/ckeditor/';
$ckeditor->config['filebrowserBrowseUrl'] = '/ckfinder/ckfinder.html';
$ckeditor->config['filebrowserImageBrowseUrl'] = '/ckfinder/ckfinder.html?type=Images';
$ckeditor->config['filebrowserFlashBrowseUrl'] = '/ckfinder/ckfinder.html?type=Flash';
$ckeditor->config['filebrowserUploadUrl'] = '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files';
$ckeditor->config['filebrowserImageUploadUrl'] = '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images';
$ckeditor->config['filebrowserFlashUploadUrl'] = '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Flash';
$ckeditor->editor('CKEditor1');
 
?>

To add the field to the form.

Ensure that in ckfinder/userfiles is writable

You also need to alter in ckfinder/userfiles/config.php the function CheckAuthentication(), to return true, take note of the warning!!

ive put it all together in one zip file displaying the submission here

VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
1,822 views

database class php

August 8th, 2011

Updated the database class

Usage:

1
2
3
4
5
6
 
// min instantiation
$dataBase = new DB('hostname','username','password','database');
 
// max instantiation
$dataBase = new DB('hostname','username','password','database',DEBUG_LEVEL,array('admin@domain.com','admin@domain2.com));

Class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
 
class DB{
 
	/* 
	 * DESCRIPTION:		Object class, Handles all database requests and returns content accordingly
	 * WRITER:			Adrian Callaghan 12,08,08      
	 * UPDATED: 		Adrian Callaghan 08,08,11
	 * 
	 * 
	 * errLvl 
	 * 		(0), none, 
	 * 		(1) show a user error, 
	 * 		(2) (1) + mysql error
	 * 		(3) (2) + show a full error (mysql errors), 
	 * 		(4) (3) + plus debugging 
	*/
 
 
	private $host, $usr, $pwd, $errLvl, $mySqlHost, $dataBase, $emailAddresses;
 
 
	public function __construct($host, $usr, $pwd, $db, $errLvl=0, $adminEmails=array()) {
 
		/*
		 * Sets up a new connection
		 */
 
		// MIN required
		$this->setHost($host);
		$this->setUsr($usr);
		$this->setPwd($pwd);
 
		$this->setErrLvl($errLvl); // sets defualt RTE
		$this->setEmailErrsTo($adminEmails);
 
		// connect
		$this->connect();
		$this->setDb($db);
 
		}
 	public function __destruct(){
 		/*
 		 * Close the connection
 		 */
 		$this->disconnect();
 	}
	protected function setHost($host='localhost'){
		/*
		 * Sets the hostname
		 */
		$this->host = $host;
	}	
 	protected function setUsr($usr=''){
		/*
		 * Sets the username
		 */
 		$this->usr = $usr;
	}	
	protected function setPwd($pwd=''){
		/*
		 * Sets the password
		 */
		$this->pwd = $pwd;
	}	
	protected function setErrLvl($errLvl=0){
		/*
		 * Sets the error reporting level
		 */
		$this->errLvl = $errLvl;
	}	
	protected function connect(){
		/*
		 * Connect to server
		 */
		$this->mySqlHost = @mysql_connect($this->host, $this->usr, $this->pwd);
		if (!$this->mySqlHost) {
			$this->error('Cannot connect to server',mysql_error());
		}	
 
	}
	protected function disconnect() {
		/*
		 * closes current connection
		 */ 
		@mysql_close($this->mySqlHost);
	}
	public function setDb($db){
		/*
		 * Set the database
		 */
		$this->dataBase = @mysql_select_db($db,$this->mySqlHost);
		if (!$this->dataBase) {
			$this->error('Cannot select database',mysql_error());
		}
	}
	public function setEmailErrsTo($email = array()){
 
		// ensure it is an array
		$email = !is_array($email) ? array($email) : $email;
 
		// if empty return
		if (empty($email)){
			return;
		}
 
		// assign the email addresses
		$this->emailAddresses = $email;
	}
 
 
 
 
	function getQuery($SQL){
		// executes a query
		$result = @mysql_query($SQL);
		if (!$result) {
			$this->error('Invalid query',mysql_error(),$SQL);
			}
		// create a 2D array of results
		$return = array();
		while ($row = mysql_fetch_assoc($result)) $return[] = $row;
		return $return;
		}
 
 
 
 
	function setQuery($SQL){
		// executes a query without returning any results, used for insert, create etc, returns the ID of the last auto-increment
		$result = @mysql_query($SQL);
		if (!$result) {
			$this->error('Invalid query',mysql_error(),$SQL);
			}
		$return = mysql_insert_id();
		return $return;
		}
 
 
 
 
	public function error($message, $mysqlErr='', $SQL=''){
 
		/*
		 * Handles errors
		 * 
		 */
 
		switch ($this->errLvl){
 
			case 0: break;
			case 1:	$mysqlErr=''; // kill the mysql output
			case 2:	$SQL=''; // kill the sql output
			case 3: 
			case 4: 
				echo "<h1 style='color:#444444;'>$message</h1><hr>";
				if ($mysqlErr!=='') {
					echo "<p><span style='color:#ff0000; font-weight:bold;'>Mysql: </span>$mysqlErr</p>";
				}
				if ($SQL!=='') {
					echo "<p><span style='color:#ff0000; font-weight:bold;'>Whole query: </span>$SQL</p>";
				}			
 
		}
 
 		$email = $this->generateEmail(array('Error'=>$message,'Mysql'=>$mysqlErr,'Sql'=>$SQL,'Err Level'=>$this->errLvl));
 
 		// three is for debugging
 		if ($this->errLvl>3){
			echo $email;
		}
 
		if (!empty($this->emailAddresses)){
 
			$sent = $this->sendEmails($email);
 
 			if ($sent) echo '<h2>The administrator has been notified</h2>';
			else {
				echo '<h2>Please notify the administrator';
				echo count($this->emailAddresses)>1 ? "'s " : " ";
				echo implode(' or ',$this->emailAddresses);
				echo '</h2>';
			}
 
		}
 
		exit();
	}	
	private function generateEmail($err=array()){
 
		$fields = array(
			'Server name'=>$_SERVER['SERVER_NAME'],
			'Query'=>$_SERVER['SCRIPT_FILENAME'].'?'.$_SERVER['QUERY_STRING'],
			'Ip'=>$_SERVER['REMOTE_ADDR'].':'.$_SERVER['REMOTE_PORT'],
			'@'=>date("D dS M,Y h:i a")
		);	
 
		$rtn = '<table bgcolor="#cccccc">';
		foreach (array_merge($fields, $err) AS $title=>$value){
			$rtn.="<tr><td bgcolor='#aaaaaa'>$title</td><td bgcolor='#bbbbbb'>$value</td></tr>";
		}
		return $rtn.'</table>';
 
	}
	public function sendEmails($reciptents=array()){
 
		// email message
		$Name = $_SERVER['SERVER_NAME']; //senders name 
		$email = "noreply@".$_SERVER['SERVER_NAME']; //senders e-mail adress 
 
		$subject = $_SERVER['SERVER_NAME']." Error"; //subject 
 
		$header = 'MIME-Version: 1.0' . "\r\n";
		$header.= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";		
		$header.= "From: ". $Name . " <" . $email . ">\r\n"; 
 
		$success=false;
		foreach ($this->emailAddresses AS $admin_email){
			$sent = @mail($admin_email, $subject, $mail_body, $header);
			if ($sent) $success=true; // holds state for any email being succesfully sent
		}
		return $success;
	}
}
VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
3,378 views

compile your own lamp stack with mysqli

June 16th, 2011

Install LAMP with one line

One liner

sudo apt-get install lamp-server^

Add CURL and enable mod-rewrite

sudo apt-get install php5-curl
sudo a2enmod rewrite

To compile LAMP with mysqli and mysql

Assuming you have a fresh clean minimal install of ubuntu start by install gcc and wget

sudo apt-get gcc
sudo apt-get wget

Download apache and php and use filezilla or a similar SFTP client to upload them to the server (I was unable to find a direct link that didnt pass through a mirror), once uploaded move to the directory on the cmd line.

unpack apache

1
2
gzip -d httpd-2_x_NN.tar.gz
tar -xf httpd-2_x_NN.tar

unpack PHP

1
2
gzip -d php-NN.tar.gz
tar -xf php-NN.tar

Compile and install Apache

1
2
3
4
cd httpd-2_x_NN
./configure --enable-so
make
sudo make install

Compile PHP

1
2
cd ../php-NN
./configure --with-aspxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/bin/mysql_config  --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd

This will fail with an error “error locating libxml2″ fix this with:

sudo apt-get install libxml2

Next the error below will appear

xml2 config not found Please check your libxml2 installation

Point your browser or ftp client at ftp://xmlsoft.org/libxml2/ and take note of the latest version for libxml2-2.6.28 and then grab it and install it from the server

1
2
3
4
5
6
sudo wget ftp://xmlsoft.org/libxml2/libxml2-2.X.XX.tar.gz
sudo tar -zxvf libxml2-2.X.XX.tar.gz
cd libxml2-2.X.XX/
./configure
make
sudo make install

Try to compile PHP again:

1
./configure --with-aspxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/bin/mysql_config  --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd

next problem is Mysql

configure: error: Cannot find MySQL header files under /usr/bin/mysql_config

To fix this, Install mysql:

sudo apt-get install mysql-server

But now even though Mysql is found there are still no headers so first install php module for mysql:

sudo apt-get install php5-mysql

and add the header library

sudo apt-get install libmysqlclient15-dev

Now PHP should compile and install fine:

1
2
3
./configure --with-aspxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/bin/mysql_config  --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd
make
make install

Set up an ini file for PHP:

sudo cp php.ini-development /usr/local/lib/php.ini

tell apache to load the module:

LoadModule php5_module modules/libphp5.so

You need to re/start apache

/usr/local/apache2/bin/apachectl start

personally I like to restart the entire server with changes this big

shutdown now -r

Thats it!

VN:F [1.9.9_1125]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
6,056 views

simple mvc

August 30th, 2010

Need a lightweight, fast, php mvc framework?

I have written a small framework named “Simple MVC” it does exactly what it says on the box, its quick to install and can be configured to handle most tasks.

Once the file is unzipped you will be presented with this structure:

Simply upload the whole structure, and the framework will work.

It is designed to be very fast and lightweight, however it can be configured, opening the file mvc_env.php within the “Simple MVC” folder displays the following preferences:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php 
/*
 * 
 * Simple MVC settings file (this file does not need to be present)
 * Examples of different settings are contained here, just uncomment to use
 * 
 * By Adrian Callaghan 300810
 * 
 */
 
// error controller
// defines a controller to handle errors, namely the page not found
// the controller is automatically exempt from an actual page request
/*
$env->error['controller']='error';
$env->error['view']='index';
$env->error['pageNotFoundAction']='pageNotFound';
*/
 
// routerMap
// holds controller and action mappings to different controller, action (comma delimited)
/*
$env->routerMap['foo,bar']='index,index';
*/
 
// routerDeny
// holds controller and action mappings to deny (comma delimited)
/*
$env->routerDeny[]='controller,action'; // will deny the page /controller/action/
$env->routerDeny[]=''; // will deny homepage
*/
 
// prelayout
// defines an array of elements to be included before the main view
/*
$env->prelayout = array('header');
*/
 
// postlayout
// defines an array of elements to be included after the main view
/*
$env->postlayout = array('sidebar','footer');
*/

As you can see, page routing, error controllers, page denials etc can all be added here.

The whole framework is just one file and the source looks like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?php
 
/*
 * 
 * Simple MVC 
 * 
 * By Adrian Callaghan 300810
 * 
 */
 
 
// enviroment
$env = new stdClass();
 
// url mapping
$env->url['base'] = dirname($_SERVER['SCRIPT_NAME']);
$env->url['path'] = realpath('.');
$env->url['relative'] = str_replace('//','/',dirname(__FILE__)).'/../application/';
$env->url['request'] = htmlentities($_SERVER['REQUEST_URI']);
$env->url['request_array'] = explode('/',trim($_GET['__url'],'/'));
 
// mvc
$env->controller = !empty($env->url['request_array'][0]) ? $env->url['request_array'][0] : 'index';
$env->action = !empty($env->url['request_array'][1]) ? $env->url['request_array'][1] : 'index';
$env->view = $env->controller;
 
// settings
@include_once('mvc_env.php');
 
// tell the controllers where to load models from
function __autoload($class_name) {
	global $env;
    require_once "{$env->url['relative']}models/$class_name.php";
}
 
 
// add custom error controller to list of denys
if (isset($env->error['controller'])){
	$env->routerDeny[] = $env->error['controller'];
}
 
 
// mapping
if (isset($env->routerMap) && in_array("{$env->controller},{$env->action}",array_keys($env->routerMap))){
	$route = explode(',',$env->routerMap["{$env->controller},{$env->action}"]);
	$env->controller = $route[0];
	$env->action = $route[1];
	$env->view = $env->controller;
}
 
// get the controller
if (file_exists("{$env->url['relative']}/controllers/{$env->controller}.php")) {
	require_once("{$env->url['relative']}/controllers/{$env->controller}.php");
	$controller = new $env->controller();	
	} 
 
// unset the controller if this is a denied resource, this is done on URL only, so not to interfere with any mappings
if (isset($env->routerDeny) && in_array(implode(',',$env->url['request_array']),$env->routerDeny)){
	unset($controller, $env->controller);
	}	
 
// if neither the controller or action was found set an error for the error controller to handle
if (!isset($controller) || !method_exists($controller,$env->action)){
 
	// can we run the error handler?
	if (isset($env->error)){
		$env->controller = $env->error['controller'];
		$env->action = $env->error['pageNotFoundAction'];
		$env->view = $env->error['view'];
 
		@require_once("{$env->url['relative']}/controllers/{$env->controller}.php");
		$controller = new $env->controller();	
		if (!method_exists($controller,$env->action)) {
			die("<h1>Fatal error</h1>Missing action: <b>{$env->action}</b> in controller: <b>{$env->controller}</b>");
			}
 
		// output will be handled by the dispatcher below	
		}
	else {
		// if we do not even have an error handler, throw a traditional 404 and die
		ob_start();	?>
		<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
		<html><head><title>404 Not Found</title></head><body>
		<h1>Not Found</h1>
		<p>The requested URL <?php echo $env->url['request']; ?> was not found on this server.</p>
		</body></html>
		<?php header("HTTP/1.0 404 Not Found"); die(ob_get_clean());
	}
}
 
// dispatcher /////////////////////////////////////////////////
 
//attempt to execute the action in the controller,
$controller->{$env->action}();	
 
// check to see if the view has been altered
$env->view = isset($controller->view) ? $controller->view : $env->view;
 
// set up the content and view
$content = $controller->content;
if (isset($env->prelayout)) foreach ($env->prelayout AS $element) include_once("{$env->url['relative']}/views/$element.phtml");
include_once("{$env->url['relative']}/views/{$env->view}.phtml");
if (isset($env->postlayout)) foreach ($env->postlayout AS $element) include_once("{$env->url['relative']}/views/$element.phtml");

A helloworld quickstart can be downloaded from here

The helloworld also has examples of where to instaniate the models, and how to redirect the view in the comments.

VN:F [1.9.9_1125]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
3,132 views

sort a array by its value

July 29th, 2010

To sort an array by its value, similiar to mysql sort by just use

1
usort($array, create_function('$a, $b, $sortBy="distance"', 'return strnatcmp($a[$sortBy], $b[$sortBy]);'));

$array stores the array
$sortBy set the key to sort by

i.e

1
2
3
4
5
6
7
$array = array (
    1=>array('name'=>'me','location'=>'somewhere','distance'=>'200'),
    2=>array('name'=>'you','location'=>'somewhere','distance'=>'2') 
    );
 
usort($array, create_function('$a, $b, $sortBy="distance"', 'return strnatcmp($a[$sortBy], $b[$sortBy]);'));
print_r($array);

will result in the array being re-ordered with location 2 now being in location 1 (preserving the keys)

VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: +2 (from 2 votes)
3,140 views

styling form buttons with divs

August 28th, 2009

Styling a button inside a form with multiple div`s to achieve a curved button with click events etc, can be done relatively easy with the use of javascript.

For example:



firstly lets take a look at our raw code

<form method="post" action="">
      <input type="submit" name="submit">
</form>

Next we place the button within no script tags, so it only displays if javascript is switched off, so that
non javascript enabled browsers can still submit.

<form method="post" action="">
      <noscript>
          <input type="submit" name="submit">
      </noscript>
</form>

Now we add the javascript styled button

 
<form method="post" action="" name="mainForm">
      <noscript>
          <input type="submit" name="submit">
      </noscript>
	<script type="text/javascript">
	<!--					
 
	// do the submission
	function submitform(){
		document.mainForm.submit();
		}
 
	// print the button
	document.write('<a href="javascript:submitform();" style="text-decoration:none; color:#fff; font-weight:bold;">');
 
	document.write('<div id="buyButtonMid">');
	document.write('<div id="buyButtonLeft"></div>');
	document.write('submit');
	document.write('<div id="buyButtonRight"></div>');
	document.write('</div>');
 
	document.write('</a>');
 
 
	// -->
 
	</script>
</form>

Then style your button accordingly with your css,

/* buy button */
#buyButtonRight{
	width:16px;
	height:44px;
	display:block;
	position:absolute;
	top:0;
	right:0;
	cursor:pointer;
	}
 
#buyButtonLeft{
	width:16px;
	height:44px;
	display:block;
	position:absolute;
	top:0;
	left:0;
	cursor:pointer;
	}
 
#buyButtonMid{
	height:24px;
	min-width:20px;
	/*max-width:300px;*/
	padding:13px 20px 7px 20px;
	display:block;
	position:relative;
	float:left;
	cursor:pointer;
	color:#ffffff; 
	font-size:13px; 
	text-decoration:none;
	}
 
 
/* normal */
#buyButtonLeft{background:url('images/add2bas_left.jpg');}	
#buyButtonMid{background:url('images/add2bas_mid.jpg');}	
#buyButtonRight{background:url('images/add2bas_right.jpg');}
 
/* hover */
#buyButtonMid:hover #buyButtonLeft{background:url('images/add2bas_left_hover.jpg');}
#buyButtonMid:hover {background:url('images/add2bas_mid_hover.jpg');}
#buyButtonMid:hover #buyButtonRight{background:url('images/add2bas_right_hover.jpg');}
 
/* click */
#buyButtonMid:active #buyButtonLeft{background:url('images/add2bas_left_click.jpg') no-repeat;}
#buyButtonMid:active {background:url('images/add2bas_mid_click.jpg');}
#buyButtonMid:active #buyButtonRight{background:url('images/add2bas_right_click.jpg');}

Job done ;)

VN:F [1.9.9_1125]
Rating: 6.0/10 (1 vote cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
7,865 views