HMVC framework for WordPress plugin development Download

HMV(C) for Controllers

Controllers


What is a controller?

Controller is a class that can be reached through the URL and executes the action. A controller is a PHP class that takes information from the HTTP request and sets the HTTP response. Response can be XHTML, JSON string, XML, HTTP error or anything else.

Controller uses models, helpers and other libraries to process and fetch the domain logic and it passes information to a view for output. If a URL like www.yourdomain.com/foo/bar is requested, the first segment "foo" will be the controller and the second segment "bar" will be the action method.

Creating a controller

In WordPress Fuel, Controllers are put in the wp-content/plugins/yourplugin/mvc/controls directory. Controller must be prefixed with “[pluginslug_]” and postfixed with "_controller" and they should extend the absController. Below is an example of the controller "foo":

class [pluginslug]_foo_controller extends absController
{
    public function index()
    {
        //default method
    }

    public function action_bar()
    {
    }
}

Methods that can be requested through the URL are prefixed with "action_". Controller method that should be called using URL must be a public method. Default method 'index' doesn't need to be suffixed with 'action_'

Controller prepares a response object representing the content. A controller must set a response.

[pluginslug] - Your WordPress plugin slugin to be replaced.

If your plugin slug is 'mycustomplugin' then the controller class name should be mycustomplugin_foo_controller.

class mycustomplugin_foo_controller extends absController
{
    public function index()
    {
        //default method
    }

    public function action_bar()
    {
    }
}

Controllers in Sub-Directories

You can also put a controller in a sub directory, like wp-content/plugins/yourplugin/mvc/controls/jobs/admin. In this case, the controller must include the directory name in the classname like this: yourplugin_jobs_admin_controller. You can maintain as many nested directories depending on your development needs.

Example

class mycustomplugin_jobs_admin_controller extends absController
{
    public function index()
    {
        //default method
    }

    public function action_bar()
    {
    }
}


A Simple Controller

//wp-content/plugins/mycustomplugin/mvc/controls/simple.php
class mycustomplugin_simple_controller extends absController
{
    public function index()
    {
      $this->setResponse("<html><body>Hello World<body></html>");    
    }

    public function action_simplest()
    {
      $this->setResponse("Simplest method called");    
    }

}

  • Line 1: Controller class name must be prefixed with 'pluginslug_' i.e. mycustomplugin_ to maintain the namespacing as there may be other plugin with the same controller class.
  • Line 3: index() is a default controller method which is called by default. It's is an abstract method and therefore must be implemented.
  • Line 5: Controller uses its 'setResponse' method to create response object.
  • Line 6: Each action in a controller class is prefixed with 'action_' and is referenced in the routing configuration by the action's name (simplest).


Common Controller Tasks

Tasks such as processing GET/POST requests, redirecting, injecting data to views, rendering views, forwarding sub requests, setting response are commonly performed by a controller over and over again.

Rendering View & Injecting Data to View

class pluginslug_example_controller extends absController
{
    public function index()
    {
        //injects 'name' variable and render the view
         $this->ViewData('name', 'John Doe') 
               ->View('example/sayhi');
    }

    public function action_sayhi()
    {
         $view_data = array();
         $view_data['name'] = 'John Doe';

         //pass data
         $this->ViewData('view_data', $view_data);

         //renders the 'sayhi' view in the 'example' folder
         $this->View('example/sayhi');
    }
}

  • $this->ViewData() returns the controller object. It allows you to use method chaining.

View - example/sayhi.php

<p>Hi, <?php echo $name; ?></p>


Parameters

class pluginslug_example_controller extends absController
{
    public function index()
    {
        // Assuming URI: portfolio/?id=21
         $post_id = $this->_request->getParam('id');
    }
}

Redirecting

class pluginslug_example_controller extends absController
{
    public function index()
    {
        $this->redirect('http://www.yoursite.com',301); // Permanent redirect
    }
}

Pushing Flash Messages

class pluginslug_example_controller extends absController
{
    public function action_index()
    {
        $this->error('Your error message'); // Error Message
        $this->success('Your success message'); //Success Message
        $this->info('Any message to serve information'); //Information Message
        
        $this->redirect(..); //reirects to the URL.
    }
}

Displaying Flash Messages - View

<?php
$flash_messages = clsFlashMessages::Instance()->getMessages();
if(count($flash_messages)):
?>
<?php foreach($flash_messages as $type => $messages) ?>
    <div class="notification <?php echo $type; ?> png_bg">
        <a href="#" class="close">x</a>
            <?php $message = (array)$messages; 
         
            ?>
              <?php if(count($message)) : ?>
            <ul>
                <?php foreach($message as $k => $msg): ?>
                <li><?php echo $this->h($msg); ?></li>
                <?php endforeach; ?>
            </ul>
            
            <?php else: ?>
                <div><?php echo $this->h($message[0]); ?></div>
            <?php endif; ?>
    </div>
<?php endif; ?>

Forwarding Requests

You can also easily forward to another controller internally with the forward() method. Instead of redirecting the user's browser, it makes an internal sub-request, and calls the specified controller. The forward() method returns the clsHTTP_Response object.

class pluginslug_example_forwarding_controller extends absController
{
    public function index ()
    {
        $response = $this->forward('sayhi/index',array('name' => 'John Doe'));
        
        //further process the response if needed
        $this->setResponse($respose);
    }
}

Notice that the forward() method uses the string representation 'sayhi/index'. In this case, the target controller class is sayhi and index is the action method called. The array passed to the method becomes the arguments on the resulting controller.


Special controller methods

index(): This method will be executed if the controller is called without a second parameter. In the above example www.yoursite.com/example/index will be the same as www.yoursite.com/example.

before(): The before() method is used as a general pre-method prepping method, to execute code required in every controller method called. This method will always be called before the method from the URL is called on your controller. It's an optional method. If you want this method to be executed before an action, define this method declare it and it should be callable (must be public)

after(): This method will be executed after the method from the URL was called successfully, this will always be called. If you want this method to be executed before an action, define this method declare it and it should be callable (must be public)

  • License
    You can use the before() and after() methods to have code executed before or after the action is executed. For example, you could check if the user is logged in, set a template view, loading a required file, etc.

authenticate(): This method will be executed when you set a controller property '$_auth_needed' to true. Please see the next section, extending controllers for more details.


Abstract controller - User Auth Controller

Thanks to the autoloader, you can extend other controllers. To extend the controller you need to suffixed controller name to 'ctr' Suffix is used to quickly loads the controller without needing to lookup the entire directory structure.

//wp-content/plugins/mycustomplugin/mvc/controls/user/auth.php
abstract class ctrmycustomplugin_user_auth_controller extends absController 
{    
    protected $_auth_needed = true;
    public function Authenticate()
    {
        if ( is_user_logged_in() === false ) 
        {
            $this->redirect('login');
        }
    }
}

User Controller Extending User Auth Controller

//wp-content/plugins/mycustomplugin/mvc/controls/user.php
class mycustomplugin_user_controller extends ctrmycustomplugin_user_auth_controller 
{    
    public function index()
    {
        //do stuff
    }
}

  • Controller 'mycustomplugin_user_controller' extends the core controller 'ctrmycustomplugin_user_auth_controller'.
  • This will make sure that user can only access the functionality if he/she is logged-in.

Examples

Handling POST Request - Post Article

class pluginslug_user_controller extends absController 
{    
    public function before()
    {
        $this->_model = new modArticles();
    }

    public function action_login()
    {
        if ( WPFuel::isPost() ) 
        {
            $data = clsSanitize::safe($data);
            $result = $this->_model->Save(array(
                'title' => $data['title'],
                'description' => $data['description'],
                'status' => $data['status'],
            ));
               
            if($result)
            {
                //handle success
            }
            else
            {
                //handle error response
            }
        }
    }
}