Build your own CMS with PHP and Mysql from scratch- Part-4 (core files and theme)

All tutorials in this series till now

In this part, we will make interface of your CMS. We will write our core files in includes directory. First we will make a Base.php file which contains an abstract Base class. This class will be extended by other core classes. Whatever we will define here will be available in our whole CMS.

File in included directory | PHP CMS from scratch
There are three more core files: Application.php, Widget.php and TemplateFunctions.php. Each of these files have one class (Application, Widget and TemplateFunction respectively). These classes are extending Base class. TemplateFunction is the class which handles the flow of the CMS. It integrates all other parts. Application is another abstract class which is extended by our applications (in applications folder). Widget class is also an abstract class which is used to write new widgets.

Read more about abstract classes or inheritance in php.

Base class:

In todolist/includes create a file Base.php. In this file, first we will check our security variable. Then we include core libraries and finally we will write our Base class. Lets start :)

  1. <?php
  2. if(!isset($security_check))
  3. {
  4. echo "This is restricted directory";
  5. exit();
  6. }
  7. require_once('libraries/core/database/'.$driver.'_database.php');
  8. require_once('libraries/core/http/routes.php');
  9. abstract class Base{

Here we are including Mysql_database.php and routes.php files. We have defined $driver variable in root index.php. It is available here because we are including this file via index.php file.

We need five things in our whole CMS:

  1. A database connection
  2. Check if user is logged in or not
  3. Array of all routes from routes.php files
  4. Get urls using their names
  5. Run application for output

Including same files and classes again and again is an overheat. So, we need not to make instances for database and routes every time. These variables must be static. Our Base class is very simple and does not need much explanations.

Database connection:

  1. /**
  2. * create a instance of database class
  3. * Open a database commenction
  4. * @return instance $db_object MysqlDatabase
  5. */
  6. public function get_dbo()
  7. {
  8. static $db_object = null;
  9. if (null === $db_object) {
  10. $db = DATABASE;
  11. $db_object = new $db();
  12. }
  13. return $db_object;
  14. }

Here I am using OOP concepts, if you are not familiar with OOP then please read OOP tutorials.

In line 8, I am defining a static database connection. In next line, I am checking if it is null or not. It will be null only first time. If it is null then I am creating an instance of database class (MysqlDatabase class).

Check if user is authenticated or not:

  1. /**
  2. * chcek if user is logged in
  3. * @return boolean
  4. */
  5. protected function is_login()
  6. {
  7. if(isset($_SESSION['user_session']))
  8. {
  9. return true;
  10. }
  11. return false;
  12. }

I am authenticated user using sessions. $_SESSION is an array of the variable stored in session. We will define 'user_session' in auth application. $_SESSION['user_session'] is defined only for logged in user. If user is logged in then is_login() will return true else false.

Load all routes in a variable:

  1. /**
  2. * get an instance of Route class
  3. * load all routes
  4. * @return instance $route Routes()
  5. */
  6. protected function get_routes()
  7. {
  8. static $routes = null;
  9. if (null === $routes) {
  10. $routes = new Route();
  11. $routes->load_routes();
  12. }
  13. return $routes;
  14. }

Similar to get_dbo() function, get_routes() is also setting and returning a static variable. This function will load all routes from all routes.php files to $routes variable.

Get url from names:

  1. /**
  2. * it is used for named urls
  3. * @param string $name
  4. * @param array $args
  5. * @return string url
  6. */
  7. protected function to_url($name, $args=null)
  8. {
  9. $r = $this->get_routes();
  10. if($args!==null)
  11. return $r->to_route($name,$args);
  12. else
  13. return $r->to_route($name);
  14. }

This function takes the name of an url and returns then absolute url. If you have read the last tutorial properly then it does not require more explanation.

Abstract run function:

Finally we have an abstract function which will be called for execution.

  1. /**
  2. * abatract function run for executing applicaiton
  3. */
  4. abstract function run($arg = null, $param = null);
  5. }

Our complete file look like this code on github.

Render first web page:

It is time to test our application till now.

  • Create a folder "default" in todolist/templates directory and a file index.php inside it.
  • Create a new file in todolist/includes with name TemplateFunctions.php.

What are we going to do?

  • We will execute TemplateFunctions class from root index.php file.
  • TemplateFunction class will return index.php file from todolist/templates/default directory.

For adding TemplateFunctions class add these lines in the end of todolist/index.php.

  1. // include template
  2. require_once('includes/TemplateFunctions.php');
  3. $tmpl=new TemplateFunctions();
  4. $tmpl->run();

Here we are just calling run() function of TemplateFunctions class. Open todolist/includes/TemplateFunctions.php and paste this code. Code is explained in comments.

  1. <?php
  2. /**
  3. * This is base template controller file.
  4. * The purpose of this file is to provide php functions to the template files
  5. * This file contains helpers for template files.
  6. * All CMS template management related functions will be here.
  7. */
  8. require_once('Base.php');
  9. class TemplateFunctions extends Base{
  10. // default theme
  11. private $template_name = null;
  12. /**
  13. * initialize template
  14. */
  15. function __construct()
  16. {
  17. if($this->template_name == null)
  18. {
  19. $this->template_name = 'default';
  20. }
  21. }
  22. /**
  23. * run whole CMS and render generated html page
  24. */
  25. function run($arg = null, $param = null)
  26. {
  27. require_once('templates/default/index.php');
  28. }
  29. }

Finally in todolist/templates/default/index.php add:

  1. welcome this is first page

Now open link http://localhost/todolist :) We have rendered first page. But it is not what we want. We have to create a complete dynamic application.

Create template:

In a dynamic webpage has various components like header, sidebars, footer and main-content. We can write all of the components in a file but for the large web pages (web page with 1000+ lines of codes), it is messy to manage all things in one file. It is specially when you are writing very custom webpage (web page with a number of logic and conditions). For example, you are using different widgets in sidebar for different types of pages. So, we are distributing code in files. Because our application is very small, you will not feel the need of such distribution. But In professional development, you will always need it.

Create these files in todolist/templates/default directory:

  • header.php
  • sidebar.php
  • footer.php

Header:

In header.php paste this code:

  1. <?php
  2. /**
  3. * This is header of the default theme.
  4. * THis header contains logo, main menu and search box in the top section of the web page.
  5. * @author Harish Kumar
  6. * @copyright Find All Together | Programming and web development
  7. * @link http://www.findalltogeher.com
  8. * @version 1.0
  9. */
  10. ?><!DOCTYPE html>
  11. <html>
  12. <head>
  13. <title>MyCMS from screech</title>
  14. <meta name="viewport" content="width=device-width, initial-scale=1">
  15. <link type='text/css' rel='stylesheet' href='<?php echo STATIC_PATH;?>css/bootstrap.min.css' />
  16. <link type='text/css' rel='stylesheet' href='<?php echo STATIC_PATH;?>css/style.css' />
  17. <script type="text/javascript" src="<?php echo STATIC_PATH;?>js/jquery-2.1.1.min.js"></script>
  18. </head>
  19. <body>
  20. <div class="hfeed site">
  21. <div id="header" class="header col-sm-12">
  22. <header id="masthead" class="site-header" role="banner">
  23. <div class="site-branding">
  24. <h1 class="site-title"><a href="<?php echo ROOT; ?>" rel="home">My To Do List</a></h1>
  25. </div><!-- .site-branding -->
  26. </header><!-- .site-header -->
  27. </div><!-- .header -->
  28. <div class="container-fluid">

Here you can see that we have used one undefined constant STATIC_PATH.

Footer:

In footer.php paste this code:

  1. <div class="footer col-lg-12">
  2. 2015 © <a class="credit-link" href="http://www.findalltogether.com/wp/about-us">Harish Kumar</a> @ <a class="credit-link" href="http://www.findalltogether.com/">Find all together| programming and Web Development</a>
  3. </div>
  4. </div>
  5. <script type="text/javascript" src="<?php echo STATIC_PATH;?>js/bootstrap.min.js"></script>
  6. </body>
  7. </html>

Static files:

We are using three css (we will use one later) and two js files. Make two folder css and js in default folder. Download these files from here: STATIC FILES. Extract it and put css files in css folder and js files in js folder.

Update index.php

Now integrate all parts. Edit todolist/templates/default/index.php as:

  1. <?php $this->get_header(); ?>
  2. <div class='content col-md-8 col-lg-10'>
  3. Here we will push our content
  4. </div>
  5. <div class="sidebar col-lg-1"><?php $this->get_sidebar(); ?></div>
  6. </div>
  7. <div class="clear"></div>
  8. <?php
  9. $this->get_footer(); ?>

TemplateFunctions class:

We are using some more functions in our templates like get_header(). Now define them. Change TemplateFunctions.php as:

  1. <?php
  2. /**
  3. * @author Harish Kumar
  4. * @copyright Find All Together
  5. * @link http://www.findalltogeher.com
  6. * @version 1.0
  7. * This is base template controller file.
  8. * The purpose of this file is to provide php functions to the template files
  9. * This file contains helpers for template files.
  10. * All CMS template management related functions will be here.
  11. */
  12. require_once('Base.php');
  13. class TemplateFunctions extends Base{
  14. // default theme
  15. private $template_name = null;
  16. // hook for widgets
  17. private $widget_positions=array();
  18. /**
  19. * initialize template
  20. */
  21. function __construct()
  22. {
  23. if($this->template_name == null)
  24. {
  25. $this->template_name = $this->get_current_template();
  26. }
  27. }
  28. /**
  29. * run whole CMS and render generated html page
  30. */
  31. function run($arg = null, $param = null)
  32. {
  33. require_once(TEMPLATE_PATH.'index.php');
  34. }
  35. /**
  36. * set a template
  37. */
  38. function set_template($template_name)
  39. {
  40. $this->template_name=$template_name;
  41. }
  42. /**
  43. * get currently active template
  44. */
  45. private function get_current_template()
  46. {
  47. // we will improve this function later
  48. return 'default';
  49. }
  50. /**
  51. * return current theme name
  52. * @return string $this->template_name
  53. */
  54. function get_current_theme()
  55. {
  56. return $this->template_name;
  57. }
  58. /**
  59. * return currently active template path
  60. * it is relative path to root index.php
  61. * @return string template_path
  62. */
  63. function get_current_template_path()
  64. {
  65. return 'templates/'.$this->template_name.'/';
  66. }
  67. /**
  68. * return static media path in template path
  69. * it is absolute path
  70. * @return string template_path
  71. */
  72. function get_static_path()
  73. {
  74. return ROOT.'/'.TEMPLATE_PATH;
  75. }
  76. /**
  77. * return header.php file from current template
  78. */
  79. function get_header()
  80. {
  81. require_once(TEMPLATE_PATH.'header.php');
  82. }
  83. /**
  84. * return footer.php file from current template
  85. */
  86. function get_footer()
  87. {
  88. require_once(TEMPLATE_PATH.'footer.php');
  89. }
  90. /**
  91. * return sidebar.php file from current template
  92. */
  93. function get_sidebar()
  94. {
  95. require_once(TEMPLATE_PATH.'sidebar.php');
  96. }
  97. }

Code is well explained in comments. Now the only unknown things are TEMPLATE_PATH and STATIC_PATH.

Improve index.php

Now replace last line of todolist/index.php,i.e, $tmpl->run(); with it:

  1. define('TEMPLATE_PATH', $tmpl->get_current_template_path());
  2. define('STATIC_PATH', $tmpl->get_static_path());
  3. define('THEME', $tmpl->get_current_theme());
  4. $tmpl->run();

Here we are defining constants. Now refresh the page: http://localhost/todolist . You will find a basic theme :). In next part, we will write interface for our applicatoins and also our first application for authentication.

Theme after 4th tutorials | create php cms from scratch


About Harish Kumar

Harish is an interested person in the field of web development and blogging. He works for the need of young web developers in learning various languages, latest technologies and other essential tips and tricks. If you need some help or you have some suggestion then you email him at harish@findalltogether.com without any hesitation. You can also suggest/demand for articles of your own choice.

Related Articles

In this part of free tutorial series, I am telling you about syntax, variables, data types, comments, constants and o...
Introduction to PHP
In this part of free step by step tutorial series I will teach you about for loop, while loop and do while loop of PH...
loops in PHP
In this part of free step by step tutorial series I will teach you about if, if else, nested and switch statements of...
Conditional statements in php

Login or Sign up to leave comment.


4 Comments

  • Ozeh Daniel
    please, when will you continue.... I am really enjoying this tutorial...I have a project and I seriously need you to continue as fast as possible. please....
    January 8, 2016 at 02:01 PM Reply

    Login or Sign up to reply.

  • Ozeh Daniel
    please, when will you continue.... I am really enjoying this tutorial...I have a project and I seriously need you to continue as fast as possible. please....
    January 8, 2016 at 02:01 PM Reply

    Login or Sign up to reply.

  • Nuno
    Mate... you didn't provide link to next part... nr 5
    December 7, 2015 at 04:12 PM Reply

    Login or Sign up to reply.

    • Harish Kumar

      Sorry Nuno, I am busy in building this website (Find All Together). After it I will complete this tutorial series.

      December 7, 2015 at 04:12 PM