PHP Recursive Function to Build a Site Tree / Site Map

A problem faced fairly regularly is the need to generate a site tree either for a menu or a site map.

Assuming your page structure in your database is along the lines of:

intPageId strPageName intParentId
1 Top Level Page X 0
2 Top Level Page Y 0
3 Child Page X 1
4 Grandchild Page X 3
5 Grandchild Page Y 3

Giving you a visual structure of:

Site tree structure

I’m a developer, not a designer. Don’t judge me

You can achieve this fairly simply in with the following PHP recursive function to get your page structure into an array. Note, I have used the Laravel query builder in this example as the project I wrote this for was a Laravel project, but this can be swapped out with a query builder from whatever framework you are using or with PHP’s PDO (or any of the lesser PHP APIs for working with databases).

function generateSiteTree($startAt)
{
	if ($children = \DB::table('cms_pages')->where('intParentId', '=', $startAt)->get())
	{
		$thisLevel = array();
		foreach ($children as $child) 
		{
			$thisLevel[$child->intPageId] = $child;
			$thisLevel[$child->intPageId]->children = generateSiteTree($child->intPageId);
		}
		return $thisLevel;
	}
 
}
 
$tree = generateSectionSiteTree(0);
 
 
print_r($tree);

That’s it.

Bonus recursive function

The project I wrote this function for required me to be able to reel off the site tree only for the top level parent of the current page, regardless of however deep you currently are.

This is easily achieved with this function:

function recurseToFindSectionParent($pageId)
{
	$current = \DB::table('cms_pages')->where('intPageId', '=', $pageId)->first();
 
	if ($current->intParentId == 0) //we've reached the top of the chain
	{
		return $current->intPageId;
	}
	else //keep going
	{
		return recurseToFindSectionParent($current->intParentId);
	}
}
$topParentID = recurseToFindSectionParent($currentPageId);

You can now feed the ID of the top level parent into the generateSiteTree function:

$tree = generateSiteTree($topParentID);

Upload Progress Bar with jQuery

Another quick post detailing a method for creating an upload progress bar with jQuery for file uploads. More for self reference than anything.

This example is using XHR.upload.onprogress to return a loaded (bytes uploaded) and total (total bytes of the file) value so an upload progress can be computed. We are using the jQuery form plugin for uploading files. We take the “loaded” and “total” values to display and update a progress indicator (status bar and the displayed percentage). Once the AJAX upload has completed, we reset and hide the progress indicator.

Boom.

$(this).ajaxSubmit({
    target: '#output',
	xhr: function()
	{
		myXhr = $.ajaxSettings.xhr();
        if (myXhr.upload)
        {
            $('#progressBar').show();
            myXhr.upload.addEventListener('progress', function(ev){
            	if (ev.lengthComputable) {
	                var percentComplete = Math.round((ev.loaded / ev.total) * 100);
			$('#percentage').text(percentComplete + '%');
			$('#status').css('width', percentComplete+'%');
	        }
            }, false);
            myXhr.upload.addEventListener('load', function(ev){
            	$('#progressBar').hide();
            	$('#percentage').text('0%');
		$('#status').css('width', '0%');
            }, false);
        }
        return myXhr;
	},
	dataType: 'json',
        success:  afterSuccess
});

HTML for the progress indicator:

<div id="progressBar">
	<div id="status"></div>
	<div id="percentage">0%</div>
</div>

CSS for the progress indicator:

#progressBar{
	width: 350px;
	text-align: center;
	height: 16px;
	position: fixed;
	left: 50%;
	margin-left: -175px;
	z-index: 9;
	border:1px solid #9d9d9d;
	border-radius: 5px;
	overflow: hidden;
	top: 45px;
	display: none;
}
#progressBar #status{
	width: 0%;
	background:#00bd67;
	height: 16px;
	transition:1s linear width; /*this gives a smooth effect as the progress increases*/
}
#progressBar #percentage{
	position: absolute;
	text-align: left;
	z-index: 11;
	top: 0;
	left:0;
	font-size: 12px;
	color: #ffffff;
	width: 350px;
	padding-left: 5px;
	line-height: 15px;
}
Upload progress bar with jQuery

Upload progress bar with jQuery

Note: When developing this, I had an issue with the progress being reported waaaaay too fast. On file uploads of ~70Mb the progress would shoot to 100% in a couple of seconds and the upload would churn away in the background until it was complete. I made a post on Stack Overflow and someone suggested that it could be due to antivirus on my machine. I tried on a machine without AV and sure enough it worked great. I’ve tried turning off AV on my work dev machine and it behaved as expected (I’m unsure if it’s anything to do with the brand of anti virus but I have avast on my work machine).

IE8 prompting to download jQuery JSON response

I had a few JSON calls which IE8 was prompting me to download/save the response rather than simply hand it to jQuery to do it’s thing.

The returned JSON had the “correct” header and no other browsers were experiencing any issue:

header('Content-type: application/json');

To get around the IE8 issue, I had to change the header of the returned JSON to return text/plain:

header('Content-type: text/plain');

and ensure that my JSON calls had the dataType “json” specified. Without this explicitly specified, the browser was unable to parse the returned JSON.

$.ajax({
	type: "POST",
	dataType: "json",
	url: URL,
	data:data,
	success: function(data){
		alert(data.status)
	}
});

Boom!

As an extra note, I was also using dropzone.js for drag and drop file uploads. Dropzone.js doesn’t allow you to force the datatype of the response so I had to convert the response to JSON before doing anything with it with:

JSON.parse(responseText);

(Note, JSON.parse is only supported in modern browsers, this was not an issue though for me though as only modern browsers were able to use the dropzone functionality anyway and I had a fallback in place for older browsers)

PHP sessions not setting in Internet Explorer (IE)

I just made a pretty interesting discovery in that PHP sessions do not set in IE when there is one or more underscores (_) in the URL.

IE was the last browser I checked an almost completed project in, having developed in Chrome and Firefox. My heart sank when I found I was unable to log in. I hadn’t experienced this issue on any other browser and didn’t have a clue where to even start.

I was able to log in on the staging environment (where I show progress to the client) but not on my local dev so it had to be an environment issue. The only difference between the environments was the URL. I had a play around and found that removing the underscores from my local dev environment URL fixed this issue and I was able to log in. Boom.

jQuery $ is undefined in IE iFrame

I have a very jQuery heavy app which I am including in an iFrame on a site I am working on. Developing in Firefox and Chrome, it was only at the last minute when I came to test the site in Internet Explorer. Much to my dismay I was getting “$ is undefined”. There were no issues when running the site directly in IE (not through the iFrame).

I tried numerous fixes recommended by Stack Overflow including delaying the loading of the iFrame until the main content had loaded, but in the end, it was simply fixed by hosting jQuery from my own server rather than pulling it in from the CDN.

Cookie Clicker AutoHotKey script

I’ve been stupidly addicted to Cookie Clicker for the last few days. There are a few of us in the office with sore fingers from our in house competition to see who can get the highest rate clicks per second (CPS). At the time of writing, I’m firing at 1,853,140,156.5 CPS.

To gain a leg up on the competition (albeit an unethical one), I went after an AutoHotKey script to take care of some extra clicking for me while I’m out of the office. To save me learning AHK and writing my own, I came across this post: http://www.autohotkey.com/board/topic/97540-cookie-clicker-game/

Here’s the Cookie Clicker AutoHotKey:

$~m::
if (IsCookieActive()) {
	Loop, 9
	If stop = 1
		Break
	Else
	{
		WinGetActiveStats WindowName, WindowW, WindowH, WindowX, WindowY
		if ErrorLevel
			sleep 0
		else
			click 267, 460
	}
}
return

Shift::
If stop = 1
	stop = 0
Else
	stop = 1
return


IsCookieActive() {
	WinGetActiveTitle, title
	titleContains := "cookies"
	; MsgBox %title%
	IfInString, title, %titleContains%
	{
		return true
	} 
	else 
	{
		return false
	}
}

To Use: Change the loop value (currently set to 9) to the number of cookie clicks you wish to execute. Run the AHK script. Start it by pressing ‘m’ and stop it by double pressing ‘shift’.

jQuery Coverflow inspired Slider plugin

A fun project I’m working on required the use of a jQuery Coverflow type content slider. I searched high and low for a plugin to do the job but nothing quite fit the bill so I set out to write my own. I already had a jQuery content slider plugin that I wrote about a year ago which I decided to use as my starting point.

This coverflow plugin is inspired by Apple’s popular coverflow seen the iPhone, iPad, OSX – just about all their devices. When a “cover” is selected, either by clicking on it or by being navigated to with the arrows, it is centered and brought into focus.

jQuery Coverflow slider

DEMO HERE | GRAB THE PLUGIN ON GIT HUB

The plugin, while far from a one size fits all implementation, suits my requirements perfectly and should be a good starting point to anyone wanting similar functionality.

Installation

Installation of the jQuery plugin is relatively simple…

1. Include the CSS in the head of your document:

<head>
....
<link rel="stylesheet" type="text/css" href="jquery.coverflow.slider.css" />
</head>

2. Specify the cover images in an unordered list (ul) wrapped in a div:

<div id="contentSlider">
	<ul>
		<li><img src="cover1.jpg"></li>
		<li><img src="cover2.jpg"></li>
		<li><img src="cover3.jpg"></li>
		<li><img src="cover4.jpg"></li>
		<li><img src="cover5.jpg"></li>
		<li><img src="cover6.jpg"></li>
		<li><img src="cover7.jpg"></li>
		<li><img src="cover8.jpg"></li>
	</ul>
</div>

3. Include jQuery and jquery.coverflow.slider.js before the closing body tag of your document.

....
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="jquery.coverflow.slider.js"></script>
</body>

4. Initialise the plugin below the inclusion of the coverflow js file

$('#contentSlider').coverFlow()

5 (optional). Options:

$('#contentSlider').coverFlow({
	'initialFocus' : 0, //the index of the slide you want to be focused on load
	'speed' : 200, // the speed of the animation
	'addClasses' : "", //classes to add to the slider
	afterChange: function(index){
		console.log('Slide in focus: ' + index);
	} //executes after the slide has changed
});

Feel Free to ask any questions below. I’ll try and help where I can.

Pure CSS3 Tooltips

pure-css3-tooltipVery simple pure CSS3 Tooltips using :hover for the tip itself, the CSS3 ‘transition’ property for a nice effect when the tooltip comes in, rgba for the background property for slight transparency on the tooltip and the :after pseudo class for a small arrow to complete the effect.

SEE THE DEMO HERE

The HTML is very simple. Just put your tooltip trigger text/image/other content within a standard <a> tag (with the toolTip class so we know to target it) and put the tooltip text in a nested <span>:

<a href="#null" class="toolTip">(?)
<span>There are many variations of passages of Lorem Ipsum available, 
but the majority have suffered alteration in some form, by injected 
humour, or randomised words which don't look even slightly 
believable.</span>
</a>

You must relatively position the <a> so the toolTip knows where to base itself as it will be absolutely positioned:

.toolTip{
	position: relative;
        text-decoration:none;
}

You will want the toolTip to be hidden initially, so when you declare it’s appearance in the CSS, you must also hide it. You also set up the transition here to allow the animation to occur when it opens. When I put this together, safari still required the -webkit prefix for transition. Chrome and Firefox were fine, however for peace of mind, I put in all the prefixes. At sometime in the near future these will not be needed:

.toolTip span{
	/*hiding it by moving it behind the main content*/
	z-index: -5;
 
	/*Set the start opacity to 0 so we can fade it in nicely using transitions*/
	opacity: 0;
 
	background: rgba(0, 0, 0, 0.8);
	border-bottom: 30px none transparent;
	border-radius: 5px 5px 5px 5px;
	bottom: 25px;
	color: #FFFFFF;
	font-size: 12px;
	padding: 10px;
	position: absolute;
	left: -10px;
	text-align: justify;
	width: 300px;
	transition: all 0.3s ease-out 0s;
        -webkit-transition: all 0.3s ease-out 0s;
	-moz-transition: all 0.3s ease-out 0s;
	-ms-transition: all 0.3s ease-out 0s;
	-o-transition: all 0.3s ease-out 0s;
}

When the <a> is hovered, we need to show the toolTip, we also change the position and the opacity from those declared above so we get a nice animation when it appears:

.toolTip:hover span{
	bottom: 30px;
	box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
	display: block;
	opacity: 1;
	left: -5px;
	z-index: 9;
}

And finally, to complete the effect, use the :after pseudo class to apply a small arrow:

.toolTip span:after {
	border-color: rgba(0, 0, 0, 0.8) transparent;
	border-style: solid;
	border-width: 15px 15px 0 0;
	bottom: -15px;
	content: "";
	display: block;
	position: absolute;
	left: 20px;
	width: 0;
}

And you have pure CSS3 tooltips. Any questions or comments? I’d love to hear them!

Removing default input styles in iOS Safari

iOS Safari (and other mobile device browsers) apply their own default styling to HTML form input elements with rounded corners, drop shadows and bevels.

If you want to remove this styling, leaving you with a blank canvas to apply your own styles, you will struggle to using just the standard CSS properties such as “border”, “border-radius”, “box-shadow”, etc.

You can simply use the CSS “appearance” property to remove these styles:

-webkit-appearance: none;
-moz-appearance: none;
appearance: none;

How to get in to web development

Quite often when telling people what I do for a living, the other person will take interest and ask me how to get into web development. I’ve also responded to a few forum posts with advice for fledgling developers looking for their first step on the web development ladder so decided to put together an advice for anyone looking to get started with this career.

I’m writing this post assuming that you are competent with a computer and will outline what I suggest you learn and some other steps to take to get yourself your first job as a web developer.

Tools

If you already have access to a computer (and let’s face it, these days, who doesn’t?) you don’t need to spend a penny.

  • You’re going to need a computer. Either a mac, PC or Linux machine. There is huge debate all over the internet of mac vs PC vs Linux, but at the end of the day, either is more than good enough for web development. I use a 13″ Macbook Air for private projects and home use and I use a PC running Windows 7 at my full time job. So it really does come down to your personal preference or what you already own. In my opinion Macs look nicer so I’m happy to pay the “Apple tax” for their products because I spend so much time looking at them.
  • A web browser. In fact, you need to get your hands on as many different brower/version/OS combinations as you can. You will find very early on that different browsers handle HTML, CSS and even JavaScript in their own way and you need to make sure what you build works everywhere. Chrome, Internet Explorer (this is the one that will give you the most issues), Safari, Firefox.
  • A text editor. There are hundreds of different editors out there, many of them Free. When I started as a dev in 2000, I used Dreamweaver. At the time it was the big “buzz word” programme for web development and I’d not heard of anything else. Dreamweaver was my go to editor up until about 18 months ago when I started investigating other light weight options. I’ve tried Notepad++, Coda, Netbeans, TextMate, but have settled on Sublime 2 as I like the features, search is faster than any of the others and it’s nice being able to use the same editor on Mac and PC. It also looks pretty.
  • A dev environment. I use MAMP Pro on my Mac for my dev environment. It’s just quicker and easier to set up, run and configure than it is to set up the native environment that ships with OSX – they also do a free, non-pro, version which will do you fine to begin with. On windows, there is WAMP (I can’t vouch for WAMP however as I’ve not used it before. At my job, we have a centralised dev server that we do all our dev on)

Skills

Firstly, I should say that it can be quite intimidating when trying to skill yourself up for web development when you look at all there is to learn. There are literally thousands of different technologies and frameworks that you can learn. Even to this day, looking through job boards there are jobs requiring technologies that I’ve never even heard of. I’ll try and steer you to the major ones, the ones that I’ve chosen or been required to devote my time to as these are the skills that have got me a decent job and as much freelance work as I choose to take on the side.

Also worth noting is that you don’t need to know these things inside out. Even with the technologies I use most often and dedicate the majority of my time to, rarely will half an hour go past where I don’t turn to Google or Stack Overflow for some help or a reminder. There is so much to learn, it’s impossible to know and remember everything. The more you learn, you more you discover there is to learn. That is what keeps this job interesting.

When you are learning these skills, make sure you learn by doing, not just by reading. The information will sink in and you will have something physical to show potential employers/clients. It can help if you have a project in mind so you’ve an end goal to work to. If you don’t have one, here’s one for you. Develop a contact directory, in which you can add, edit, delete and search for contacts.

The first thing you should learn is HTML (Hyper Text Markup Language). HTML is what you mark up your content with so the browser understands it and can present it in the appropriate manner. If you right click on any web page and select “view source”, you will see the HTML behind a page. Learn how to create basic layouts with headings, text, links and images. A great resource for learning HTML is W3Schools and this is where I always point people who are new to the field.

Once you have a good understanding of HTML – as mentioned above, you don’t need to know it inside out – you should learn CSS. CSS (Cascading Style Sheets) define how your content is presented. That is your fonts, font sizes, colours, alignment, position, etc. Again, for learning CSS I’d point you to W3Schools. Another good CSS resource is Chris Coyier’s CSS tricks. Chris is pretty much considered the “man” when it comes to CSS and a search for just about anything CSS related will find him right at the top, though for an absolute beginner, the content on his site may seem a little advanced.

Once you’ve a good understanding of HTML and CSS, and it may take you only a few months, I’d recommend you put yourself out there and start applying for work. Seriously! Get onto the online job boards and search for “Junior Web Developer”. There are loads of positions. For those roles, companies are just looking for someone with the basics who is able to display initiative and a willingness to learn. The development agency I work for is constantly advertising for junior devs and we can’t find them anywhere. There is a huge skills shortage in our industry. As a proactive junior dev, you’d be a great asset to a company. For a relatively low investment, they can have their low level work such as minor updates taken care of. Freeing up the experienced devs for heavier work. In the process, you’ll be in web development 40hrs a week surrounded by experienced devs and your learning will sky rocket. Within a couple of years, you’ll be commanding good money.

I’m not guaranteeing you will find work straight away, it may take a while but you’ll be in a position to be employed.

Now you have HTML and CSS, the forest opens up slightly with a few more routes. You will need PHP/.net/Ruby and JavaScript/jQuery. Which you decide to learn first depends on if you are more interested in Front End Development (that is, what is displayed and goes on in the browser) or Back end Development (what goes on on the server and databases).

They are not mutually exclusive and even if you decide to specialise in the Front or Back end, the skills from the other are still necessary to have an understanding of. Once you have an understanding of one, the other will come to you much easier.

Keep applying for work!

For the front end you will want to learn Javascript/jQuery. There are other scripting languages and other libraries but none are as established as these 2 and in all my years as a dev, I’ve never encountered the others.

Javascript is a scripting language that allows you to interact with the browser and the content of the web page.

jQuery is a JavaScript library. You write simple jQuery commands (you actually write these in JavaScript) which it then takes and executes the complicated JavaScript behind the scenes. jQuery is a lot more simple (especially now you have CSS under your belt) than learning raw JavaScript so I’d suggest just jumping right into jQuery. While you are learning jQuery, unbeknownst to you, you will also be learning JavaScript so when you do decide to launch an assault on JavaScript, you will have already laid the groundwork. For jQuery, I’d again recommend W3Schools. I came across a website a few years back which I was hoping to locate again to link to in this post but couldn’t find it. I did however stumble across this: http://ejohn.org/apps/workshop/intro/#0 which looks a really good, simple and straightforward resource. You should also read the docs at jquery.com

Keep applying for work!

For the back end, you have a few more options. I listed PHP, .net and Ruby. While I understand Ruby is on the rise, I’ve never encountered a situation where I’ve had to touch it. This may not be the case for the job market in your area so do a bit of research on the job boards to see what companies are looking for. This leaves PHP and .net.

The development agency I work for started out in Classic ASP which is now pretty obsolete. When we decided we needed to update our technologies a number of years back we weighed up PHP vs .net and settled on PHP for a number of reasons; It’s openness, it’s free, the strong community behind PHP and open source and also because it would have been a smoother transition from Classic ASP. As an added benefit, when I think of .net developers I think of a shirt and tie and I’m more of a jeans and t-shirt kind of developer :)

That’s not to say that PHP is better than .net though. I know some .net developers that are making great money and are involved in exciting projects, but my experience and personal preference is in PHP. I can only list good reference sites for PHP as I’ve not a lot of experience with .net. So again, W3Schools. I also watched a series of videos on Lynda.com a number of years back when I was first learning PHP that I found hugely beneficial (the company I was working for at the time had a paid subscription).

Keep applying for work!

Along with PHP/.net/Ruby, you’ll need to learn how to manipulate a database so you’ll want to teach yourself MySQL (Structured Query Language). There are tutorials all over the web and if W3Schools has been working for you so far, stick with them, if not, a simple Google search will put you in the right direction.

Keep applying for work!

Once you have all of the above under your belt, I’d recommend getting your hands dirty with some of the MVC frameworks out there. MVC (Model View Controller) frameworks have been around for years and they are really taking off. Because of the way the front end (View) is separated from the back end (Controller and Model), it allows for easily maintainable code and makes it easy to farm off the front end to the front end developers, allowing them to work on the project without interfering with the back end.

There are numerous frameworks out there. I regularly use Code Igniter and Laravel and occasionally Silverstripe which was my first foray into the world of MVC. The docs and forums for these frameworks are your best place to get acquainted with the frameworks. Also (mentioned below) Stack Overflow is an amazing resource for everything web development. Out of the 3, right now I’d suggest Code Igniter. While it is a little behind Laravel in terms of features, there is a much bigger community behind it which is a huge bonus when you will have a lot of questions. Laravel’s following is quickly on the rise though and it is a relatively simple transition from Code Igniter to Laravel.

Keep applying for work!

Source control will also come in handy. SVN (Subversion) and GIT are the obvious ones. If you are to pick between the 2 I’d say go for GIT. SVN is fairly dated and where it hasn’t already been,  is being replaced by developers with GIT. Source control is one area I personally need to shape up on. I’m fairly comfortable with SVN but definitely need to spend some time learning GIT.

Other info

When you get called for an interview, go smart. That means a shirt and tie at least. You’ll likely end up being able to wear jeans to a web dev job but turning up to an interview like that makes you look lazy and like you don’t care about the job. Set a good impression.

Take your laptop so you can show your work and your learning journey.

In an interview, if you don’t know the answer to a question, say so. They don’t expect you to know everything, they just want to suss out what stage you are at with your learning.

You’ll likely be on a short probation when you first start your job. Keep setting a good impression. Don’t be the guy (or girl) that turns up on the dot and then leaves on the dot. That guy exists in every single office and everyone thinks bad of them for it. I have a friend (not a developer) who is that guy. He can’t understand why I’ll be at work at least half an hour before I’m contracted to start and at least 15 minutes after I’m contracted to finish. He regularly tells me “They’re not paying you for that extra time. You should be out the door dead on 5.30. That’s your right”. Yes, it is my right but it doesn’t set the best possible impression. I may be working extra for no immediate financial gain, but come pay review time, the boss is going to be well aware of my time keeping and will no doubt reflect this in his decision.

More tips for developing your skills and getting work

Keep a blog of your progress. Did you struggle with something and work it out? Blog about it. Not only will writing about it help you remember, but you’ll have something else to show prospective employers, it’s a great way to interact with other developers. You may even get job offers come through to you. I only started blogging around a year ago and have had a number of people contact me with employment opportunities.

Get an account on Stack Overflow. If you’re stuck with something, post a question. Also spend some time trying to help those with issues you know the answer to. You’ll quickly build a reputation and you can tie it to a Stack Overflow Careers profile which is another way to get in touch with prospective employers and for them to find and contact you.

Get on twitter and start using it. I’ve only joined the twitter in the last 18 months or so and have to admit that this is one of my flaws. I should be more active. If you want to interact with me on twitter, you can find me @fraserhartdev

Talk your code over with other developers. Seek out tidier and more efficient ways of achieving your end goal. If you don’t know any other developers and have some questions, fire me an email (fraser@fraser-hart.co.uk), I’ll be glad to give you some pointers.

If you have any questions at all about anything below. Please ask below or get in touch via email. Good luck in your new careers!