* * * * * command to be executed ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └───── day of week (0 - 6) (Sunday=0 ) │ │ │ └────────── month (1 - 12) │ │ └─────────────── day of month (1 - 31) │ └──────────────────── hour (0 - 23) └───────────────────────── min (0 - 59)
Category Archives: fun
PHP Dump/Debug script.
Ever use PHP’s var_dump() or print_r() to debug what is going wrong with that $data you have ?
Well, this simple script acts as the above functions, yours first parameter is your data, and the second optional parameter is stoping the script or continuing on.
The ‘debug_backtrace()’ function will return which file call’s the dump function so you can easily track where your errors are coming from.
function dump($data = array(), $finish = TRUE) {
list($referrer) = debug_backtrace();
$total = count($data);
echo '
";
if($finish == TRUE) die;
}
Webkit custom scroll bars
Webkit browsers such as Safari and Chrome support some superb CSS3 styling.
They are ( even thought I use firefox as my primary browser ) the most advanced browsers.
For a while now I have created custom scroll bars using a Javascript library called Mootools, other libraries such as jQuery and Prototype can do this too, but here is one easy way to do it with CSS alone;
here is the simple code, if you know CSS it will be self explanatory, else I have added some commenting
/* were a webkit browser, lets style our scroll bar */
@media screen and (-webkit-min-device-pixel-ratio:0) {
html{
/* hide overall scrolling */
overflow: auto;
}
body {
/* absolute position our 'body' and allow for the width of the scroll bar */
position: absolute;
left: 0;
top: 0;
right: 10px;
bottom: 0;
padding-right: 10px;
overflow-x: auto;
overflow-y:scroll;
}
::-webkit-scrollbar {
/* set the width of the scroll bar */
width: 10px;
}
::-webkit-scrollbar-button:start:decrement,
::-webkit-scrollbar-button:end:increment {
/* hide the arrows */
display: block;
height: 10px;
}
::-webkit-scrollbar-track-piece {
/* set the style/colour of the scroll bar background */
background:
-webkit-gradient(
linear,
0 0,
100% 0,
from(rgba(0,0,0,0.2)),
to(rgba(0,0,0,0.12))
);
-webkit-box-shadow: 0 1px 0 0 rgba(255,255,255,0.35);
-webkit-border-radius: 5px;
}
::-webkit-scrollbar-thumb:vertical{
/* this is the acutal scrooll bar, set the colours here to match your site */
/* I have used grey's (#464646 & #383838 & #cccccc) */
background:
-webkit-gradient(
linear,
0 0,
100% 0,
from(#464646),
to(#383838)
);
-webkit-border-radius: 6px;
border: 3px solid #cccccc;
-webkit-background-clip: padding-box;
}
::-webkit-scrollbar-track-piece:horizontal{
background: none;
-webkit-box-shadow:none;
}
::-webkit-scrollbar:horizontal{
height: 16px;
}
::-webkit-scrollbar-thumb:horizontal{
height: 12px;
-webkit-border-radius:12px;
background:
-webkit-gradient(
linear,
0 0,
0 100%,
from(rgba(0,0,0,0.1)),
to(rgba(0,0,0,0.25))
);
border: 6px solid transparent;
-webkit-background-clip: padding-box;
}
}
}
Mootools Gallery ZoomBox Plugin
I needed a simple lightweight Mootools Gallery Lightbox, and after a few googles, I found nothing that suited my needs with out all the extra ‘captions’ and grouping and bloat.
This is a simple zoom from start position type lightbox that uses only the Mootools Core version 1.2.4 at this time but should work with 1.3.x
I have used it on the Glass Effects web page which you can view for a demo.
You will notice on my class, I am adding a CSS class ‘shadow’ to the large image, this is used for basic styling and you can do any CSS you want to it. ( or none at all )
Here is how it is built up;
HTML:
< div id="photos">
< ul>
< li>< a href="http://www.glasseffects.co.nz/assets/volume1/2_large.jpg" class="zoomBox" title="Glass Effects - Painted toi toi image on glass splashback">< img src="http://www.glasseffects.co.nz/assets/volume1/2_small.jpg" alt="Glass Effects - Painted toi toi image on glass splashback" />< /a>< /li>
< li>< a href="http://www.glasseffects.co.nz/assets/volume1/3_large.jpg" class="zoomBox" title="Glass Effects - Uniformed lines on Effects glass splashback">< img src="http://www.glasseffects.co.nz/assets/volume1/3_small.jpg" alt="Glass Effects - Uniformed lines on Effects glass splashback" />< /a>< /li>
< li>< a href="http://www.glasseffects.co.nz/assets/volume1/5_large.jpg" class="zoomBox" title="Glass Effects - Textured Effect splashback using GlassArt colour #25 Iridium">< img src="http://www.glasseffects.co.nz/assets/volume1/5_small.jpg" alt="Glass Effects - Textured Effect splashback using GlassArt colour #25 Iridium" />< /a>< li>
< li>< a href="http://www.glasseffects.co.nz/assets/volume1/6_large.jpg" class="zoomBox" title="Glass Effects - Stencilled Effect – toi toi. GJ Gardner Show Home, Tauranga">< img src="http://www.glasseffects.co.nz/assets/volume1/6_small.jpg" alt="Glass Effects - Stencilled Effect – toi toi. GJ Gardner Show Home, Tauranga" />< /a>< /li>
< li>< a href="http://www.glasseffects.co.nz/assets/volume1/7_large.jpg" class="zoomBox" title="Glass Effects - Painted glass for bar. GlassArt colour #49 Red Red Red">< img src="http://www.glasseffects.co.nz/assets/volume1/7_small.jpg" alt="Glass Effects - Painted glass for bar. GlassArt colour #49 Red Red Red" />< /a>< /li>
< /ul>
< /div>
JS ( In Page ):
window.addEvent('domready', function() {
/* Any other JS needed for your page */
var myZoomBox = new zoomBox();
/* to set options */
var myZoomBox = new zoomBox({
zb_class: '.mootools-ftw',
zb_element: 'big_image',
zb_loader: './loading.gif'
});
});
ZoomBox Class:
// Create the Mootools ZoomBox Class
var zoomBox = new Class({
Implements : Options,
// Editable Settings
options: {
zb_class: '.zoomBox', // class of anchors/images to find on page.
zb_element: 'zb_image', // id of zppmBox pop-up div
zb_loader: '/assets/images/loading.gif', // path to loading image
scale_image: true, // scale large image if it is bigger than our screen size, bool true/false
win_width: 1024, // basic window width, ignore
win_height: 768 // basic window height, ignore
},
initialize: function(options){
// set options and internal settings
this.setOptions(options);
this.setWindowSize();
this.currentIndex;
this.images = new Array();
this.positions = new Array();
// create our loading image
this.zb_loading = new Element('img', {
'id' : 'zb_loading',
'src' : this.options.zb_loader,
'styles': {
'position': 'absolute',
'display' : 'none',
'left' : 0,
'top' : 0
}
}).inject(document.body, 'bottom');
// scan page for our class.
this.thumbs = $$(this.options.zb_class);
var self = this;
// attach each image.
this.thumbs.each(function(zb, index) {
self.attach(zb, index);
});
// add event listener if the user resizes their window to scale max size of images.
window.addEvent('resize', self.setWindowSize.bindWithEvent(this));
},
// attach out image and add event listeners.
attach: function(zb, index) {
var self = this;
// is we manually attach a new element this is needed.
if(index == undefined) {
index = (self.length + 1);
}
// set our basic width/heights.
var zb_fx;
var zb_src = zb.get('href');
var zb_org = zb.getElements('img')[0];
self.positions[index] = {};
self.positions[index].zb_left = zb_org.getPosition().x;
self.positions[index].zb_top = zb_org.getPosition().y;
// add out click event.
zb.addEvent('click', function(clk) {
new Event(clk).stop();
// no point opening it, if its already open !
if(!document.id(self.options.zb_element) || !document.id(self.options.zb_element).get('src').match(zb.get('href'))) {
// add out loading gif to the image about to be opened.
self.zb_loading.setStyles({
'display' : '',
'top' : self.positions[index].zb_top,
'left' : self.positions[index].zb_left
});
// if we have one open, let it be gone
if(document.id(self.options.zb_element)) {
self.close(self.currentIndex);
}
// set current index.
self.currentIndex = index;
// create and place on top of the thumbnail. but keep it hidden.
self.images[index] = new Element('img', {
'id' : self.options.zb_element,
'src' : zb_src,
'styles': {
'position': 'absolute',
'opacity' : 0,
'left' : self.positions[index].zb_left,
'top' : self.positions[index].zb_top
}
})
.addClass('shadow') // we don't need this. but its basic styling for large image.
.inject(document.body, 'bottom') // inject at teh bottom of our page.
.addEvent('click', function(clk) {
// bind out close even on clicking the new large image
new Event(clk).stop();
self.close(index);
})
// bind a load event so once the large image has loaded, we open it.
.addEvent('load', function() {
// get our large image size
var zb_width = self.images[index].getWidth();
var zb_height = self.images[index].getHeight();
// see if we need to scale it, so the image fits on screen.
if(self.options.scale_image) {
if(self.options.win_width < zb_width) {
zb_width = (self.options.win_width - 50);
zb_height = (zb_width / zb_height) * zb_width;
}
if(self.options.win_height < zb_height) {
zb_height = Math.floor(self.options.win_height - 50);
zb_width = Math.floor((zb_height / zb_width) * zb_height);
}
}
// set the imahe the size of the thumbnail
self.images[index].setStyles({
'width' : zb_org.getWidth(),
'height' : zb_org.getHeight(),
'cursor' : 'pointer'
});
// hide teh loading gif/indicator
self.zb_loading.setStyle('display', 'none');
// animate it BIG ! and center it on the screen
var zb_fx = new Fx.Morph(self.images[index]).start({
'top' : ((self.options.win_height / 2) - (zb_height / 2)) + window.getScroll().y,
'left' : ((self.options.win_width / 2) - (zb_width / 2)),
'width' : zb_width,
'height' : zb_height,
'opacity' : 1
});
});
} else {
// we have used it before, lets load it up.
self.images[index].fireEvent('load');
}
// bind the 'escape' key to close the current image.
window.addEvent('keyup', function(key) {
if(key.code == 27) {
self.close(index);
}
});
});
},
close: function(index) {
var self = this;
var zb_fx = new Fx.Morph(self.images[index], {
onComplete: function() {
document.id(self.options.zb_element)
.fade(0)
.dispose();
}
}).start({
'top' : self.positions[index].zb_top,
'left' : self.positions[index].zb_left,
'width' : 100,
'height' : 100,
'opacity' : 0
});
window.removeEvents('keyup');
},
setWindowSize: function() {
this.options.win_width = window.getWidth();
this.options.win_height = window.getHeight();
}
});
Download the Full Script:
[download id="11"]
BounceBox Version 1.2 with Mootools 1.3 support
After around 19 months of inactive development I have updated my Mootools BounceBox class to support The current selector method and fix an Event issue in some browsers when opening the Box.
Try out the demo at http://bouncebox.lendrum.co.nz and download it on the original BounceBox post.
Use PHP to find your mobile browser
I needed a quick way to include different files based on the if the visitor to a site is on a mobile device or a regular browser/computer.
Every browser has a user agent depending on the operating system, browser and system.
below are some common use agents, they can be found by echoing the server variable HTTP_USER_AGENT
< ?php echo $_SERVER['HTTP_USER_AGENT']; ?>
FireFox
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7
Safari Mac
Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-en) AppleWebKit/523.10.3 (KHTML, like Gecko) Version/3.0.4 Safari/523.10
Safari Windows
Mozilla/5.0 (Windows; U; Windows NT 6.0; en) AppleWebKit/522.13.1 (KHTML, like Gecko) Version/3.0.2 Safari/522.13.1
Nexus One
Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD56C) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17
Apple iPhone
Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3
Apple iPod Touch
Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A100a Safari/419.3
Internet Explorer
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)
PHP mobileAgent() Function
Here is my function, is it simple PHP function, is expects one paramerter, and array or expected user agents, but by leaving it blank, the function will use the default user agents.
Update: I have added more mobile user agents for older Android models, Blackberrry’s and the iPhone simulator. .
< ?php
function mobileAgent($custom_agents = array()) {
$agents = array_merge($custom_agents, array(
'iphone', // Apple iPhone
'ipod', // Apple iPod touch
'aspen', // iPhone simulator
'nexus', // Nexus One Android
'dream', // Pre 1.5 Android
'android', // 1.5+ Android
'cupcake', // 1.5+ Android
'blackberry9500', // Storm
'blackberry9530', // Storm
'opera mini', // Opera mobile
'webos', // Nokia Browser
'incognito', // Other iPhone browser
'webmate' // Other iPhone browser
));
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
foreach($agents as $agent) if(strpos($user_agent, $agent)) return TRUE;
return FALSE;
}
?>
Usage
< ?php if(mobileAgent()): ?>
< ?php else: ?>
< ?php endif; ?>
Javascript URI Address Segment Selection
I use the great CodeIgniter, PHP Framework a lot, Most site’s now days I create use it. One of the many good things is that way it handles pages request’s and PHP $_SERVER['REQUEST_URI'] to find which page we are on.
Here is how it works;
http://www.sheldon.lendrum.co.nz/posts/my-segment/my-page/15/2009/12
Now the way we do things, is break the site up, based on the ‘segments or the URI.
EG:
I am in the ‘posts ( segment 1 )’ part of the site. from ther directs to to the particular post I am on.
Here is some VERY simple javascript to find out any segment I am in.
var currentLocation = window.location.toString(); // find out what page we are on
var hostName = 'http://'+ window.location.hostname; // find our current domain name
var uriString = currentLocation.replace(hostName, ''); // get our segments minus our domain name
var uriSegment = uriString.split('/'); create our segment array
A simple example of usage would be, if you were using a GREAT MOOTOOLS accordion for your navigation, and having one open, based on the address of your page
// set out Accordion toggler elements
var togglers = $$('h3.toggler');
// set out menu var
var showMenu;
// loop our toggler elements, and see if our URI segment matches their name ( in my example. )
togglers.each(function(item, index){
if(item.get('html').toLowerCase() == uriSegment[1]) showMenu = index;
});
// if our URI segment matched nothing, set a default ( closed in my example )
if(showMenu == undefined) showMenu = -1;
// create our Accordion
new Accordion(togglers , $$('ul.element'), {
duration: 250,
display: showMenu,
initialDisplayFx: false,
onActive: function(toggler, element) {
toggler.set('class', 'active');
},
onBackground: function(toggler, element) {
toggler.set('class', '');
}
});
Use PHP and the GD Library to make CSS Sprites
I came across some neat free Icons a couple of day’s ago. I found 178 free icons by WooThemes.
They suited my needs for some navigation icons I was after, so after a quick download, I have them all. Great.
Now, when I code, I’m all about speed of page loads with our reducing quality of course. So more and more and with that I have been using CSS sprites for images, the Less requests, the faster a page loads. there are hundreds of articles explaining this sort of thing, like only use 1 CSS file, putting your Javascript at the bottom, I use them, I even have written a Mootools extensions for embedding Google Analytic in to my sites, that secretly embed the GA code after the page has loaded so its doesn’t slow down the rest of your site from loading, tracking external links and form submits, but any how that is for another post.
178 PNG icons
After extracting the ZIP, I found 178 separate icon files, and I wanted a gray-scale version of each for a hover state, that would mean up to 356 requests plus all of the rest of the images on that page.
Now of course I’m not going to use every Icon, but you never know !
Using PHP & the GD Library to make my Sprite
I must Credit Sandy for his awesomeness and contribution to this script.
< ?php
function spriter($dir = '*.png', $dest = 'sprite.png', $spacing = 0) {
// define icons sizes
$icon_width = 32;
$icon_height = 32;
// start height of my sprite canvas
$height = 0;
// select all the icons and read theri height to build our canvas size.
foreach (glob($dir) as $file) {
list($w, $h) = getimagesize($file);
// make sure out icon is a 32px sq icon
if ($h == $icon_height)
$height += ($h + $spacing);
}
// double our canvas height to allow for a gray-scale versions.
$height = ($height * 2);
// create our canvas
$img = imagecreatetruecolor($icon_width, $height);
$background = imagecolorallocatealpha($img, 255, 255, 255, 127);
imagefill($img, 0, 0, $background);
imagealphablending($img, false);
imagesavealpha($img, true);
// start placing our icons from the top down.
$pos = 0;
foreach (glob($dir) as $file) {
$tmp = imagecreatefrompng($file);
if (imagesy($tmp) == $icon_height) {
imagecopy($img, $tmp, 0, $pos, 0, 0, $icon_width, $icon_height);
$pos += ($icon_height + $spacing);
}
imagedestroy($tmp);
}
// place all of our icons on again, but this time convert them to gray-scale
foreach (glob($dir) as $file) {
$tmp = imagecreatefrompng($file);
if (imagesy($tmp) == $icon_height) {
imagefilter($tmp, IMG_FILTER_GRAYSCALE);
imagecopy($img, $tmp, 0, $pos, 0, 0, $icon_width, $icon_height);
$pos += ($icon_height + $spacing);
}
imagedestroy($tmp);
}
// create our final output image.
imagepng($img, $dest);
}
Sample Usage
< ?php
// IMPORTANT: REMEMBER TO MAKE SURE THE WEBSERVER HAS WRITE ACCESS TO YOUR DESTINATION DIRECTORY.
spriter('icons/*.png', 'icons/sprite.png', 10);
Show our Sprite
?/>)
