A powerful comment system from scratch – Part 1

In this post I’ll be detailing how to use AJAX coupled with jQuery to build a comment system. Part 1 will be building the actual comments. Go to Part 2 to see how to add in a rating system.

The finished system will look like this:

comment system

Okay, some notes about this comment system:

  • Parent and child comments can be posted
  • jQuery will be used to hide/show the reply box for child comments
  • All comments will be contained in one table, called ‘comment’
  • The column ‘parent’ will be used to distinguish between child and parent comments
  • I use Bootstrap for my form styling, if you don’t use this your styling will turn out slightly different
  • This will utilise an MVC pattern and as such you may need to modify the code if you are not using this design pattern (although you should be using it)
  • By definition, this is not a stand alone feature and should supplement a module you already have, such as products. I’m using comments to be used on topics, but this will apply to anything.

Preparation

Copy the following SQL into your DB to get started:

 NOTE: create a foreign key to link ‘user_id’ to a user table. I’ve left this out as I want to solely focus on the comment system. Also, take out ‘topic_id’ and replace with whatever you are implementing this system for.

Implementation

Now we have the table set up, we can start to implement the functionality we want. I like to start with the basic HTML structure, so let’s dive right in.

Parent Comments

This is the parent comments section and the main reply box above that – it is pretty bare bones at the moment. We set up the initial structure and then we can fill this in from the controller next. We also have a form which will be used to reply to the comment. At the moment this is set to display on the page but we will hide it on page load and then show it when ‘Reply’ is pressed.

Now let’s look at the controller code. This may differ depending on what framework you are using. I’m using one I built myself – Nova – but the logic is the same no matter what so it won’t differ too much.

In my use case of this, I’m assigning comments to a particular topic. If you do not wish to do this then replace topic with whatever you are linking it to, such as product. Here I also get the total comments for the whole post and pass that through to the view as well.

I have a method there called getCommentsByTopicId which is an database query to get all the comments based on the topic id, so change as appropriate.

Once you have all the necessary data from the controller and we have passed it through to the view we can start displaying it. So back to our HTML. This is the completed parent comments section.

Here we loop through all the comments in the database and display them one by one. Two more things for the parent comments: CSS and jQuery. Let’s start with the CSS. I hope you’ve kept the class names the same else don’t forget you’ll have to change the CSS selectors to match your class/id names.

Finally, some simple jQuery which shows/hides the reply form.

Let’s have a quick recap on what we’ve done here.

  • We’ve got all the comments relating to the particular page we are on (topic, product, etc)
  • We’ve passed these comments through to the view
  • Next we loop through them to display them to the user
  • jQuery is used to show/hide the form

If you have done everything correctly, and have some data in the comments table, you should be able to display some comments on the page now.

Child Comments

Child comments are very similar to parent comments implementation. However, the logic in the controller is more advanced so I will explain a bit more. The HTML is pretty much the same, and is as follows:

I’ve left the PHP in here as it is explained in the parent comments section up top. Next is the completed controller, including the parent comment code from earlier.

This looks quite daunting at first, but it’s really not. Let’s break it down:

  1. We call the getChildComments method, which basically queries the database and looks in the ‘parent’ field I mentioned earlier, matching that column with the ID of one of the comments. If there is a match, then we have child comments.
  2. We then pass this straight through to the view.
  3. We want a total amount of all comments, which now has to be amended to include child comments as well. So we take the $childComments variable and loop through it, counting it each time and then assigning it to a new array, $countChildren. We then sum this array with array_sum and then add it to the parent comments count to give us a total count.
  4. We also need to be able to save any posted comments to the db. How this is done will be specific to your framework vendor, but mine works by checking for a post value, and if one is found then it saves the post values to an array and then saves this array to the db. This is similar to the Zend way of doing this as well.

Next, add the child comments CSS to your stylesheet.

This gives it some indentation to differentiate the child comments from the parent ones.

Conclusion

Whey, that’s a lot of code! Tweak, tweak, tweak so you get this working before moving on to Part 2. In the next part I will be showing how to add a rating system to each comment so logged in users can vote on comments they think are good or bad.

As always, if you have any problems leave a comment and I’ll make sure to get back to you.

 

 

facebooktwittergoogle_plusredditfacebooktwittergoogle_plusredditby feather

Read More

Big O algorithms in PHP

In this post I’ll be detailing simple algorithms with their respective big O complexity and showing use cases in PHP.

What is Big O?

Big O notation is actually a lot simpler than it looks. In Computer Science, we need to define how complex a block of code is, to define its approximate run time. There are many factors that can affect how quickly a piece of code can run on a machine: CPU power, compiler used, operating system, etc. When generating run times for algorithms we need to have a level playing field where these factors are not considered. We also need a notation to denote these run times.

I find I learn better when I actually write code out, so I did with the most common big O complexities.

O(1)

O(1) is referred to as a constant. It defines a piece of code that will take the same amount of time regardless of the input size n. Let’s assume we have an arbitrary array of n elements. It does not matter if n = 3 or n = 205, the code will execute in the same amount of time. Any piece of code that does not have any loops in is O(1).

 

So we can see, because this function is just checking if the first element is set to null, it runs in O(1) (or constant) time.

O(n)

O(n)  is referred to as linear notation. This is again very simple, it says that the time taken to run the algorithm will increase proportional to the input size of n such that T(n) = O(n). Let’s see this in code.

So, to explain. This function takes one param, $array, and loops through it, setting all the values to one. Because of this need to go through all the elements in the array (unlike O(1)), this function’s time grows proportional to its size. An array containing ten values will take a shorter time to execute compared to an array containing one thousand. n simply denotes the number of times the loop executes.

O(n2)

O(n2) is a quadratic formula. This is exactly the same as O(n) but with one more nested loop. The below piece of code runs two for loops, which is O(n2).

You can run this code on your machine to test it. You’ll see the load times of your browser increase dramatically as n does.

O(n3)

O(n3), following the same thread as the previous two, is cubic. The astute reader will realize that this is two nested loops. Let’s have a look at the code for this.

To give you an idea of how quickly this code scales in time proportional to n, when n = 10 $total = 210, and when n = 1000 the code reaches the maximum execution time of 30 seconds. Quadratic run times take the longest to complete, so bear that in my mind when writing code.

O(log n)

O(log n) is a logarithmic function. The code gets a little more complicated here, and the uses cases for these complexities will be far less than the previous ones listed. I will be showing a classic logarithmic function in computing, the binary search. A binary search is a classic algorithm which utilises the divide and conquer method to determine where a specific value in a list is.

 

This function takes an array and a needle to be searched for as params. Then, it breaks the array down based on the middle value and checks to see if the needle is greater than, less than, or equal to the needle. In either of the first two instances, it repeats the steps of breaking down the array further and checking again. It is this process of breaking each sub array down into two arrays that gives this algorithm the name binary search.

 

Conclusion

Hopefully this has provided some basic grounding as to what big O notation is used for and some use cases in PHP to relate to. To get a firmer grasp of these notations, check functions you write against them and see what the run time is in big O format. You will get to stage where you can glance at a function and know exactly what the run time is. This is useful preliminary material before you start to delve deeper into algorithms, if of course this is something that interests you. Any questions or need things explaining clearer? Post in the comments and I will make sure to get back to you.

 

 

 

facebooktwittergoogle_plusredditfacebooktwittergoogle_plusredditby feather

Read More

Nova Paginator

This is a paginator I made for the Nova framework. It’s called from the controller, taking the data to be paginated as a param. It can then be displayed in the view like any other PHP var.

 

facebooktwittergoogle_plusredditfacebooktwittergoogle_plusredditby feather

Read More

GoPHP name change

Today I made the decision to change the name of the GoPHP framework to Nova. The reason was that there were multiple repos on GitHub with the same name as well as the Go language which will cloud the exposure of it.

I liked the name; I came up with it because of my original design philosophy of having a target audience of novice developers. The Go came from the premise of having little configuration to do, essentially being able to transition quickly onto the development stage. While working on Zend as an intern (which at the time of writing I am still on, however no more Zend), I was confused with the complexity of setting up the framework and coding with it. Granted, this was just as much to do with my lack of knowledge as it was the framework’s advanced skill requirement, but that is where creating GoPHP really appealed to me.

Introducing the new name: Nova. Why Nova? Well, it stems from the “nov” in novice. Nova naturally followed on from that and I liked it.

facebooktwittergoogle_plusredditfacebooktwittergoogle_plusredditby feather

Read More

There is no price on education

We have to consider that society teaches us from a young age that you have a limited time. That is a profound message garnered when growing up – especially when it comes to learning. There is a notion of toxicity that we put upon ourselves in adult years that our learning days are over. This is simply not true. There are resources on the internet that allow you to learn content from the early days of pre high school maths to courses from the top universities in the world. And it’s FREE. There is no excuse not to learn any more. The Internet’s sole purpose of the sharing of information combined with the goodwill of intellectual establishments and individuals has turned this ideology into a reality.

 

For some people this isn’t such a problem, as they simply don’t value education. I find this a shame personally, but each to their own.

 

Below are some links that I have found incredibly useful.

 

https://www.khanacademy.org -  One of the best resources out there. Provides content from pre-school to early university.

 

http://ocw.mit.edu/index.htm – I regard this as being in the same tier as Khan Academy. Full courses from one of the best universities in the world.

 

More to come…

facebooktwittergoogle_plusredditfacebooktwittergoogle_plusredditby feather

Read More

Example GoPHP Controller

This is a pretty standard Register Controller for my GoPHP framework.

facebooktwittergoogle_plusredditfacebooktwittergoogle_plusredditby feather

Read More

jQuery with AJAX – Bulk Delete

 

facebooktwittergoogle_plusredditfacebooktwittergoogle_plusredditby feather

Read More

Backwards relationships in Django 1.6

The Django template system, by design, limits the amount of programmatic code that can be written. The major advantage of this is that front end developers don’t have to understand, or even write, back end code. I can relate to this, as I was in a PHP job where the front end developer would comment out or even remove PHP code because he simply didn’t understand it. It forces back end developers to try and find an elegant way to write all the logic in the views.py file and is, in my opinion, a good separation of concerns.

This does have its drawbacks though, the major one being that sometimes you just have to write something in the template. The Django developers have tried their best to accommodate for a lot of the issues developers were having. One of those was looping through some data loaded from the view and then having a nested loop inside pulling some more data relevant to the current loop, referenced through an FK. That may sound confusing, so let me give an example.


 

You have two tables: User and Address.

Each user has an address assigned to them through a FK, address_idNow say we want to display all the users on the site, with their associated addresses. In good ol’ PHP, we could write something similar to this:

 

The key thing here is how we get the address: We can look for it based on the user’s ID. This requires some more work in the controller and model, but that’s beyond the scope of this post. The key here is the view structure. It took me a while to find out you can do this in Django as well, in the form of a backwards relation.

Because of Django’s ORM, using a nested for loop in the correct way will allow you to pick up the FK relation and display just the data for that particular loop. Using the table structure above, here’s what a normal nested for loop would look like:

This would require passing the addresses through from the view. When the nested for loop is encountered, it will simply display all addresses for every user. So if there’s four users and four addresses, each user name will be displayed with all the addresses.

Here’s how to do this correctly, with a backwards relation:

The key difference here is this

This looks for the addresses relating to the particular user. This now displays all the addresses relevant to each user, whether that be one or seven. Also, you don’t need to pass anything from the view. That’s right, you can just pass the user object, all the relations are handled automatically by Django’s ORM.

facebooktwittergoogle_plusredditfacebooktwittergoogle_plusredditby feather

Read More

Programming – how it changes the way you think

As a novice programmer, back in my first year of university, I hated programming. I literally hated it. We had a Javascript module which was taught terribly bad by a tutor who was more interested in powering through the slides so he could get on with some serious procrastination rather than actually teach the module that was most foreign to most of us there. I scored a low mark, along with most of the class, and no surprise the tutor wasn’t there for the next year.

A lot of the students in that class haven’t been able to advance very much with their coding skills, and have migrated over to other specialisms within the industry such as front end design and databases.

It made me think programming was seriously hard, which, if any of you code, you know is simply not true. This doesn’t mean that anyone can code to a high standard, far from it, it just means that the people that possess the correct thinking patterns will not find it hard. I think this was the hardest part for me – training myself to think like a programmer, or, more abstractly, a mathematician. Once I grasped this, which really was just taking my mindset back to maths in school, I found things come to me surprisingly easy.

So, to the title, how does programming change the way you think? Well, first of all, you will find you can dissect things down to a great level. I can take people’s arguments apart because of the level of detail I see things in now. Some people don’t like it, because suddenly their arguments they put forward are taken apart down to the word level. Most of the time I refrain from saying anything simply because it unnerves some people and quite frankly it’s not the best way to make friends. However, I regularly find myself smiling to myself at some apparently intellectually impressive statement someone has said. You’ll find it too; you’ll find you’ll be standing their taking apart every sentence in your head in real time and probably concluding with an argument that undermines them. Probably best you do what I do and refrain, heh.

This way of thinking isn’t limited to social situations, either. I find this happens to me in just about every situation I encounter. When I walk down the street, I don’t see a sliding supermarket double door, or a bus – I see the parts that make these up, all the inner workings. The flow of electric going through the cables powering the door, the pressure pad underneath the mat, the microcomputer powering the bus ticket machine. Everything I see will be broken down to around that level of detail. I think this isn’t just because of programming, I think it’s because of an innate desire to learn how things work. However, I can’t argue that the two seem intrinsically linked.

I’ve always had a good memory, and rarely have to write things down, but now I can go into meetings and never bring a notepad as I can remember the conversation almost word for word if I’m paying attention.

One thing programming lets you do without any side work is apply this way of thinking to the actual machine you’re working on. To abstract your thinking to an almost parallel state where you are thinking of the machine’s functions while at the same time thinking of what you are coding up garners the best results, as you are able to know what is going on as you are typing. For example, if I’m typing in a bash script into the terminal and I can see how the computer is going to compile this code, I can actually rectify code that would of otherwise failed. As you program more and more, this will become second nature for you.

You’re going to start writing code in your head, too. I find myself round friend’s houses and they’ll encounter a problem – maybe a page is taking ages to load, and you’ll instantly think of the code that is going on in the background. The HTML headers being processed, the newly upgraded site server processing the millions of requests per second and yours being stuck, the PHP being rendered, the jQuery page being called (and the resulting request to the server, etc), everything is seen to this level.

You’ll also become opinionated. At the start, you do whatever the tutor or online tutorial says. You follow the 56k reputation person’s answer on Stack Overflow precisely, you don’t question it. After a while though, you develop your own preferences, where the starting brace should go, which order the imports go in on a Python script, and that’s when you start becoming passionate. You find yourself having harmless debates with colleagues about these little things, and that’s when the programming world really opens up.

People are going to think you’re weird, people are going to scowl at you because they are paying you X amount and don’t know what you are doing. I’ve worked in a company for a year and have had this multiple times. I’ve had managers say they think we are just messing around all day, we take too long to do things, the list goes on (any Google search will bring up many more examples of this). I pay no attention to their arguments, and consider it all major ignorance on their behalf. If you find yourself in a company like this, my advice is to get out and go to a company that specialises in what you do.

And don’t be pressured into thinking this is a geek’s world where people don’t talk to girls and no one actually knows what’s going on. I’m sorry, but that’s just utter shit.

I also want to note this is all within a span of three years: one of those being commercial work, two being university. I’m fairly certain I will level myself off at some point in the near future, but we’ll see.

 

facebooktwittergoogle_plusredditfacebooktwittergoogle_plusredditby feather

Read More