Build a forum with CakePHP (part 1)

CakePHP official site provides a simple yet powerful comprehensive tutorial about building a blog using CakePHP. However a lot of developers are wondering how to build a forum with CakePHP. In this series of tutorials, we are going to build a very simple forum with features like list topics, view topics as well as posting replies to topics. It is not a production ready forum. Its purpose is to demonstrate how easy to build a forum with CakePHP, with its built-in features such as authentication, MVC structure and rich view helpers.

In this tutorial we will setup CakePHP properly and use Twitter's Bootstrap for the design. For simplicity, we are going to call the forum application as "CapForum". Let us get started.

Download link of entire source code is provided in part 4 of this series.

Preparation

  • Download Bootstrap framework from this URL. We are using version 3.0.2 by the time of writing this tutorial. Extract downloaded zip file and remove original CSS and JavaScript files, we only need to keep their minified version.
  • Download CakePHP from this URL. We are using CakePHP 2.4.3 for this tutorial.
  • Download DebugKit from this URL. It is a good habit to use DebugKit for CakePHP development. It logs information we need in a nice UI bar.
  • Create a database for the forum. In our case, we have created a database called "capforum", this will be the placeholder for our forum's db.

Create database

Let us design a database structure for CapForum. We need a "users" table to store users' login credentials, a "forums" table to store forum's information, a "topics" table to store topics across forums, a "posts" table to store replies to each topic. And their relationship is identified as well:

cap forum erd

Import the tables to your database using the script below. It will as well add some dummy data since we are not going to build a backend system in this series.

--
-- Table structure for table `forums`
--
 
CREATE TABLE `forums` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(250) NOT NULL,
  `created` date NOT NULL,
  `modified` date NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
 
--
-- Table structure for table `posts`
--
 
CREATE TABLE `posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `topic_id` int(11) NOT NULL,
  `forum_id` int(11) NOT NULL,
  `created` date NOT NULL,
  `modified` date NOT NULL,
  `content` text NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
 
--
-- Table structure for table `topics`
--
 
CREATE TABLE `topics` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(250) NOT NULL,
  `content` text NOT NULL,
  `created` date NOT NULL,
  `modified` date NOT NULL,
  `forum_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
 
--
-- Table structure for table `users`
--
 
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(250) NOT NULL,
  `password` varchar(250) NOT NULL,
  `email` varchar(250) NOT NULL,
  `created` date NOT NULL,
  `modified` date NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
 
--
-- Dumping data for table `users`
--
 
INSERT INTO `forums` VALUES(1, 'General Discussion', '2013-12-06', '2013-12-06');
INSERT INTO `posts` VALUES(1, 1, 1, '2013-12-10', '2013-12-10', 'Test1', 1);
INSERT INTO `topics` VALUES(1, 'Test', 'Test Topic', '2013-12-06', '2013-12-06', 1, 1);
INSERT INTO `users` VALUES(1, 'caker', '080a38b5f8259776ec5ca984488af588d063932a', 'caker@gmail.com', '2013-12-06', '2013-12-06');

Note that the script above will create an user account with the username "caker" and password "password". Keep them in mind, because we will need them later.

Install Bootstrap and DebugKit

Now we need to relocate downloaded Bootstrap resources (Javascript files and CSS files) to CakePHP directories.

  1. Copy "fonts" folder from downloaded Bootstrap files to CakePHP's directory "app/webroot".
  2. Copy "bootstrap.min.css" file from downloaded Bootstrap files to CakePHP's directory "app/webroot/css".
  3. Copy "bootstrap.min.js" file from downloaded Bootstrap files to CakePHP's directory "app/webroot/js".

Now CapForum "app/webroot" directory should look similar as below:

CapForum webroot

The highlighted parts are what we have added.

Lastly, follow this link to install DebugKit.

Edit layouts and create navigation element

Now we have Bootstrap resources in CakePHP directory. We need to edit the layout files to include them in the view.

Copy following files to "app/View/Layouts/default.ctp":

<!DOCTYPE html>
<html>
<head>
    <?php echo $this->Html->charset(); ?>
    <title>
        Cap Forum
    </title>
    <?php
        echo $this->Html->meta('icon');
 
        echo $this->Html->css('bootstrap.min.css');
 
        echo $this->fetch('meta');
        echo $this->fetch('css');
        echo $this->fetch('script');
    ?>
     
    <style>
        body {
          padding-top: 70px;
        }
    </style>
</head>
<body>
      
    <?php echo $this->element('navigation');?>
   
    <div class="container">
      <?php echo $this->Session->flash(); ?>
 
      <?php echo $this->fetch('content'); ?>
       
      <hr>
      <footer>
        <p>Developed by <a href="https://www.startutorial.com">Star Tutorial</a></p>
      </footer>
       
    </div> <!-- /container -->
     
     
     
    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
    <?php echo $this->Html->script('bootstrap.min'); ?>
</body>
</html>

In the layout file above, we used an element "navigation". It is a good idea to keep navigation in an element, so later when you extend this application, you can easily add the navigation to other layout files. Copy the following to file "app/View/Elements/navigation.ctp":

<div class="navbar navbar-default navbar-fixed-top" role="navigation">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <?php echo $this->Html->link(__('Cap Forum'),'/',array('class'=>'navbar-brand'));?>
        </div>
        <div class="navbar-collapse collapse">
          <ul class="nav navbar-nav navbar-right">
            <?php if(!$this->Session->check('Auth.User')):?>
            <li><?php echo $this->Html->link(__('Login'),array('controller'=>'users','action'=>'login'))?></li>
            <?php else: ?>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"><?php echo $this->Session->read('Auth.User.username');?> <b class="caret"></b></a>
              <ul class="dropdown-menu">
                 <li>
                    <?php echo $this->Html->link(__('Profile'),array('controller'=>'users','action'=>'profile'))?>
                 </li>
                 <li>
                    <?php echo $this->Html->link(__('Logout'),array('controller'=>'users','action'=>'logout'))?>
                 </li>
              </ul>
            </li>
            <?php endif;?>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
</div>

You probably have not edit CakePHP database connection file yet. Copy "app/Config/database.php.default" to "app/Config/database.php", and supply correct database access information. You should be familiar with this step; this is an essential step on installing CakePHP.

Before we end this tutorial, there are two important config values you will have to change. Open file "app/Config/core.php":

  1. Change "Security.salt" to "123G93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi": Configure::write('Security.salt', '123G93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
  2. Change "Security.cipherSeed" to "12359309657453542496749683645": Configure::write('Security.cipherSeed', '12359309657453542496749683645');

The reason we are doing this is that Auth component uses these values to match passwords.

The end

Now we have completed the first tutorial. Navigate to CapForum index page, you should be able to see the page as below:

CapForum Part 1

This page simply tells us that CakePHP has been installed properly and as you can see it is using Bootstrap's CSS properties.

If your page does not look like above, that means you do not follow some parts of the tutorials correctly, please review and try them again.

Next tutorial, we are going to build authentication system for CapForum.

Hopefully this simple tutorial helped you with your development. If you like our post, please follow us on Twitter and help spread the word. We need your support to continue. If you have questions or find our mistakes in above tutorial, do leave a comment below to let us know.