Welcome to the third part of our voyage into the world of MVC. Our mission: To build an MVC framework that is:
- Simple
- Extensible
- Lightweight
- Versatile
- Fast-loading
- Self Templating
- Reusable
Note that all the code in this article is downloadable HERE, You will need a MySQL database to run it on, and you will have to setup the connection in application/db.ini.php
. My example should guide you. You should not have to do much else than create the database and connect to it. The application will build its own tables. How it does that is something we will get to in due course. Please note this is an open source application, but a mention of my name or a link back to this article would be greatly appreciated should you decide to try and use it. The code in that framework represents many, many hours of coding and architecture. Part One can be found HERE while Part Two can be found HERE.
gException
If you open up the file “library/gException.php
” in your text editor you will see the following:
Figure One
The whole point behind this is to generate an exception when something goes wrong with the script. For debugging this is rather useful too. You will notice that my class “gException
“– it could have been called anything, really–extends a class called Exception
. This class Exception
is part of PHP, and simply provides all the tools we need to generate the information we need in order to debug properly. Thus, as you look through the code you will see things like
This means that should the required class in this instance not be found, the script will die and report which class could not be found, as well as where it was looking for that class.
Can we have an Hello World Example Please?
This is a question I have been getting quite a bit on my own site, so let us begin by creating a hello world application.
The first thing we need to do is decide what the controller and action is going to be. So we in effect need to see what the URL after the site name is going to look like. Something like http://sitename.com/helloworld means that the controller is “helloworld” and the action is “index”. A URL like http://sitename.com/helloworld/something means that the controller is “helloworld” and the action is “something”. For the sake of simplicity we will say that our controller will be “helloworld” and our action will be “index”. Now, for those who do not really understand MVC, Our controller is the “THING” that will actually be looking at what the MODEL is doing and passing that information on to the VIEW, or screen, if you must. I have built the controller to be pretty stable in the way that you don’t really have to do much in it but declare the PAGE TITLE and tell it to actually print the VIEW data to the screen. I prefer a controller that doesn’t really do too much whenever possible. Others prefer the controller to do the thinking. In my mind this is a little beyond the whole point of MVC.
Ok, so we know what out controller will be, and we know what our action will be. Now what? Well, let’s build the controller!
In the application directory there is a folder called controller. Open that folder and inside, create a new file called “helloworldController.php”. Very inportant here is the captital “C” in Controller. This must always be the case. In MVC–and any coding language, style or design pattern–the most important issue is ALWAYS CONSISTENCY. If we do something one way somehwere, we need to do it the same way EVERYWHERE. Anyhoo, back to the code.
So what we need to realize is that our controller defines the class name and our action defines the function within that class. As a rule, every Controller must have an “index” action, because forgetting to enter an action in the URL will default to index, and the script will throw an exception if an index action is not defined. So Let us first define our controller and action.
Figure Three
Figure Three shows the simple helloworldController
Class. All controller classes MUST extend the class controller_abstract
because it is that class that actually builds most of the MVC working parts in this framework. Not extending that class will simply break the script because most of what is going on in the background in the controller abstract class will be missing.
Now we can look at the function indexAction. With this function it is always important again to notice the camel hump A. The first variable set inside there simply sets the pagetitle in the <title></title> tags, making it easy for you to do your SEO stuff right here, for each action. The second variable, $this- >mainTitle
, is simply something I created to describe a heading on your page. More on that later. The function call is extremely important: $this->view()
. This is the actuall call that makes the content of the page display in the right place. But we have a few little things to do first.
The next important thing is to set a model for the controller. Go to the application/model directory and create a file called helloworld.php. Our model in this instance is simple, since we are making a static page there is not much logic going on here we can simply just declare the class and then leave it be until a later time that we should use it. Our model class will look like this:
Figure Four
Later, should we need to, we will create methods inside this class that makes things happen. For now this model class is required to exist by the router. Later we will look into detail why. Now we move on to the view. (notice how we built the Controller, Model, and now View?)
The view is where the actual HTML code gets generated. Go to the directory “application/view/scripts/” and create a folder called helloworld. Inside that folder create a file called “index.phtml”. Now, a .phtml file is a PHP file that is meant to handle HTML effectively. In short, it is an HTML PHP template file. I’m hoping that by now you realize that for every controller there is a folder named after that controller in the application/view/scripts directory, and for every action relative to that controller there is a .phtml file inside that folder which handles the display.
Ok, so what we need to do is insert the following code into our application/view/scripts/helloworld/index.phtml file:
Figure Five
Ok, perfect. That’s it then, right? So lets navigate our browser to http://framework/public_html/helloworld. Oh no! What you see is:
But why? What have we done wrong? We created the Controller, Model and the View. It should work? Shouldn’t it?
Well, no, it shouldn’t. We are forgetting about access control. This is generally referred to as Perms or ACL or whatever. In this framework I have called it the Gatekeeper. You do not have to worry about how it works really. All you need to do is know a few things about what it needs in order to work. Open the “application/configs/gatekeeper.ini.php” file. This is where you control the gatekeeper.
Ok, first we see the following:
Figure Seven
There are three clear sections in gatekeeper. These are:
- Roles
- Rules
- Actions
When we work with Roles, think of them as a certain userlevel. In Figure Eight I have already created three roles: guest, with a value of 0, user, with a value of 10, and admin with a value of 100. What the values indicate is which usertype should be given preference over another should a conflict occur. Thus Admin will always be given preference over User, who will be given preference over guest.
Next, we need to realize that rules are very precise things. For every page, in effect, every ACTION
, you will need a clear rule that defines what will happen to each role as that role interacts with that page. Our rule is defined as three words seperated by dots, and a value. The reason is simple. I want to be able to say that I want to allow a certain role to view a certain ACTION
of a CERTAIN CONTROLLER
. Thus, If I wanted to allow Guest Role (In otherwords, a user that is not currently logged in) access to index/index, I would use the definition:
controller.action.role = allow
and a real example would be, to allow Guest Role access to our helloworld Page:
helloworld.index.guest = allow
Or, if I would like to deny Guest Role access to that same page, I would say
helloworld.index.guest = deny
This is where the Actions in terms of Gatekeeper comes in. Be careful not to confuse these actions with controller/action in MVC. The action in gatekeeper is a definition of what you want gatekeeper to do once it has denied a Role access to a page. Obviously we can just let the user redirect to a notification, etc. With actions we define an action as in Figure Eight Below:
Figure Eight
And what we are saying here is:
controller.action.role = redirect.controller.action
Which means that we could say that our hello world application is only accessible if the user is logged in. So we would then create a rule saying:
helloworld.index.guest = deny
helloworld.index.user = allow
And a complimentary Action:
helloworld.index.guest = redirect.user.login
So, if a guest attempts to access the helloworld/index page, he will be redirected to the login page. A logged in user will automatically have access.
Let’s now complete this demonstration by adding the following rule to the gatekeeper.ini.php file, thus allowing guest access to the page:
helloworld.index.guest = allow
And if we now go back to http://framework/public_html/helloworld we will see the result:
Figure Nine
And that completes our task!
Until Next Time