-
-
Notifications
You must be signed in to change notification settings - Fork 2
8. Controllers
A Controller
is a key entity in an MVC architecture. It is the layer that is responsible for interfacing with both the Model
and the View
. It takes its input from a View
, interfaces with the Model
to either get information or add to the information, it calls upon any other logic that needs to be applied to the information and finally sends it back to the View
to be displayed.
In this video, we will learn how to create a database model, how to link it to Caligrafy and how to perform CRUD operations using Controllers.
Most of the concepts that we covered thus far - Routing
, Request
, Models
, Relationships
, Validation
, Views
- come into play together in the context of a Controller
.
-
All the controllers that you create should be in the
/application/controllers
folder. In this folder, you can organize the controllers to your convenience. If you prefer to have your controllers in a different folder, you can always do that for as long as it is within the/application
folder. -
There is no formal naming convention for a controller. We do recommend that you remain consistent.
Learn more about naming conventions here
- All the controllers that you create should extend the
Controller
class
use Caligrafy\Controller;
class BookController extends Controller {
// your code goes here
}
- The controllers that you create need to have at the very least, an
index
method. Theindex
method gets called by default when no method is specified in theRoute
.
use Caligrafy\Controller;
class BookController extends Controller {
// index method
public function index()
{
// your code goes here
}
}
- Controllers usually cover all the actions that can be taken on the
Model
that it controls. It is therefore common to have several other methods within a controller.
use Caligrafy\Controller;
class BookController extends Controller {
// index method
public function index()
{
// your code goes here
}
public function read()
{
// your code goes here
}
}
In the Routing
section, we covered the basics of how to route a request to a Controller
or to a specific method within the controller. We will summarize them herewith.
The following route will redirect all calls to http://your-app/books
to the index
method in the BookController
:
Route::get('books', 'BookController');
The following route will redirect all calls to http://your-app/books
to the read
method in BookController
:
Route::get('books', 'BookController@read');
Frameworks are meant to help organize and structure code. Some frameworks impose that a Controller
be tied to a Model
and imposes a naming convention that forces developers to have a single controller for a model.
Our framework provides the flexibility to create a controller that is independent of a model and it allows changing its context at any point using the associate
method that takes a Model
and a database table name
arguments and returns a Controller
:
public function associate(Model $model, String $tablename);
Let's consider the books example again. Assume you have a Book
and a Publisher
models in an online library system. In a model-constrained framework, if you need to allow the users to make changes to the Publisher
model, you will need to have a dedicated PublisherController
.
In this framework, you could change the context in methods or even within the same method:
use Caligrafy\Controller;
class MyController extends Controller {
public function readBook()
{
// associate the controller with the Book model and the books table
$this->associate('Book', 'books');
// all controller methods executed below will be in the context of Book
}
public function addPublisher()
{
// associate the controller with the Book model and the books table
$this->associate('Publisher', 'publishers');
// all controller methods executed below will be in the context of Publisher
}
}
-
Methods can be created as needed in a controller provided they don't override the built-in
Controller
methods. From the moment you override these methods, the framework could behave abnormally. -
Despite the fact that there is no prescriptive way on how to organize the logic within a method, we recommend the following logical structure:
use Caligrafy\Controller;
class MyController extends Controller {
public function myMethod()
{
// Context: set the context of the controller by association with model and table
// Retrieve & Validate: fetch any parameters needed from the request when applicable and validate it
// Model: Create a model when applicable based on the retrieved data or the data to be changed
// Act: perform the action on the model
// View: return a view with the output of the action
}
}
- From the moment a
Controller
is a created as previously described, powerful built-in methods and properties are provided out of the box.
protected $request; // retrieves the Request
protected $model; // retrieves the Model
protected $connection; // retrieves the database connection
protected $validator; // The GUMP validator can immediately be used from the controller
protected $payment; // The Stripe payment module can immediately be used from the controller once activated
public function associate(Model $modelname, String $table); // allows the model to switch context
public function activatePayment(); // Activates the Stripe Payment module
public function all($args = null); // Returns all entries of a model unless an array of condition, order and limit are specified to complete the query
public function find($id = null); // returns a specific entry. When id is not provided it is fetched from the request URI
public function save($inputs, $id = null); // saves an input Array or Model to the database. When an id is provided it would update
public function delete($id = null); // delete a specific entry. When id is not provided it is fetched from the requested URI
public function search(String $scope = null, String $keywords = null);
/* returns all entries in a Model with an attribute that matches the keyword search
* There are two wildcards that can be passed on with keywords:
* The percent sign (%) represents zero, one, or multiple characters
* The underscore sign (_) represents one, single character
*/
public function table(); // returns the database table that the model is associated to at any point in time
public function check($data, $rules = array(), $filters = array()); // calls the GUMP validator for validation and /or filtering
public function validate($data, $rules); // calls the GUMP validation method
public function filter($data, $filters); // calls the GUMP filtering method
public function view($viewName, $viewData = array()); // returns a view that renders a Pug template with the data provided
public function api($viewData = array()); // returns a view for api rendering