The Fundamentals

Module structure

As a plug and play tool, should be very simple to start coding. So, as our first example, let’s create a simple module named Clients extended from the Module Library.

You can create the following structure:

modules/Clients
modules/Clients/controllers
modules/Clients/views
modules/Clients/Clients.class.php

<?php

namespace modules\Clients;

use Bossanova\Module\Module;

class Clients extends Module
{
    public function __default()
    {
        echo 'hello world';
    }

    public function myname()
    {
        echo 'My name is: Bossanova';
    }

    public function add()
    {
        echo 'new client';
    }

     public function delete()
    {
        // Get the second parameter in your URL
        $id = $this->getParam(1);

        // Do something
        echo 'delete client: ' . $id;
    }
}

Based on the example above, you can run your methods by simply calling the following URLs:
http://localhost/clients/add, http://localhost/clients/mynamehttp://localhost/clients/delete

The __default() method will be called when the requested URL has no second argument or does not match any of the available methods within your code. So, for the following examples:
http://localhost/clientshttp://localhost/clients/testhttp://localhost/clients/name

The BF will return ‘hello world’.

 

Controllers

All controllers must be placed in the controllers' folder inside your module structure. So, following the example above, let's create a simple controller named Profile extended from your module Clients, for example:

You can create the following file:

modules/Clients/controllers/Profile.class.php

<?php

namespace modules\Clients\controllers;

use modules\Clients\Clients;

class Profile extends Clients
{
    public function __default()
    {
        echo 'my controller';
    }
}

The URL to run the controller above will be:
http://localhost/clients/profile

 

Get the URL arguments

The getParam([integer]$position) method returns the equivalent argument from your URL, starting from zero.

Considering the following request:
http://localhost/clients/open/1

<?php

namespace modules\Clients;

use Bossanova\Module\Module;

class Clients extends Module
{
    public function __default()
    {
        echo $this->getParam(0); // It will return clients
        echo $this->getParam(1); // it will return open
        echo $this->getParam(2); // It will return 1
    }
}

Get posted variables

The getPost([array]$filter) method returns all content from the $_POST or only the specified variables by the argument $filter, for example:

<?php

namespace modules\Clients;

use Bossanova\Module\Module;

class Clients extends Module
{
    public function __default()
    {
        // Copy from $_POST['username'] and $_POST['password']
        $posted = $this->getPost(array('username', 'password'));
    }
}

Routing

The Bossanova PHP Framework has different ways to deal with routing. It varies from automatically interpreted rules to custom definitions. For the custom URL definition, you must use your config.inc.php or the Routes Administration tool described further in this document. But firstly, let’s talk about the automatic routing that does not require any settings.
 

Basic Automatic Routing

The easiest way to have a valid URL access to run your code, is simply creating your own module. For example, if you create a module Clients (application/Clients/Clients.class.php), then BF will give you some options, such as:

1. Run a public method within your module

http://localhost/clients
http://localhost/clients/newclient
http://localhost/clients/anyothermethod

 

2. Load a HTML view file

If you would like to load a view, your second URL parameter must match an existing file name inside the views folder, for instance:

To load the file:
modules/Clients/views/form.html

You can simply request the URL below:
http://localhost/clients/form
 

IMPORTANT
1. A view can be loaded only by any GET requests.
2. No template will be loaded when performing AJAX requests.

 

3. Run a method within a controller:

In order to organize your code and keep your project in line with best practices standards, you might want to use controllers. So, if the second argument from the URL request matches an existing file name inside the controllers folder, a controller method will be executed, for instance:

If you have the file below:
modules/Clients/controllers/Profile.class.php

<?php

namespace modules\Clients\controllers;

use modules\Clients\Clients;

class Profile extends Clients
{
    public function __default()
    {
        echo 'default function';
    }

    public function search ()
    {
        echo 'searching for a profile';
    }
}

Then you will be able to call following URLs to run a method within your controller, such as:
http://localhost/clients/profile, http://localhost/clients/profile/search
 

IMPORTANT: In summary, when the first argument from the requested URL is matching an existing module name then the second argument could mean: run public method, load a view file or run a public method within a controller.

 

Advanced automatic routing

As explained in the previous topic of this document, when an URL is requested, the first action that the BF will perform is to check if your request matches an existing module name. If there is no match and, depending on the configuration of your environment, the BF might perform other automatic actions in order of priority:

  1. Verify an existing URL definition in your config.inc.php;
  2. Verify an existing URL definition in your Routes Administration;
  3. Verify an existing URL definition bind to an CMS object in your Nodes Administration;
  4. Verify an existing username in case the Social Network tools are enabled;


In this last example, if the user request the URL http://localhost/jonhlennon and no URL definition is found then the BF will search for an existing entry in the database [users.user_username]

So, if a user login is found then run the module Me (application/Me/Me.class.php).
 

NOTE: To learn more about the Social Network tools you can find more in our article at
http://www.bossanova-framework.com/articles/the- social-network-tools

 

RESTful requests

Basic Requests

The BF was created totally oriented to respond to RESTful requests. Therefore, there are several pre-build methods to handle the requests and make development easier. The first very nice feature to mention is the table-module matching name. It happens when you create a module that matches an existing table name, so in that particular case the Module Library have several methods to handle the RESTful requests and the respectfully data.

For example, you have a table such as:

CREATE TABLE clients
(
  client_id serial,
  client_name character varying(64),
  client_email character varying(64),
  client_phone character varying(64),
  client_gender smallint,
  client_status smallint,
  CONSTRAINT clients_pkey PRIMARY KEY (client_id)
)

And you have a Clients module such as:

modules/Clients
modules/Clients/views
modules/Clients/controllers
modules/Clients/Clients.class.php

<?php

namespace modules\Clients;

use bossanova\Module\Module;

class Clients Extends Module
{
}

The Clients Class has some inherited methods from the Module Library to handle your requests. The first method implemented is the __default (), so, based on your HTTP request (GET, POST, PUT DELETE), the BF decides which SQL action will be performed within the related table, for example:

1. If you perform a GET request to the following URL:
http://localhost/clients/45

Then, the clients module executes a SELECT by primary key = 45 and returns an associative array converted in a JSON format.

2. If you perform a POST request to the following URL:
http://localhost/clients

Then, the clients module gets all POST variables, binds the data, inserts into the table as a new record and returns a confirmation message and, in case of success, the ID of the new record.

3. If you perform a POST or PUT request to the following URL:
http://locahost/clients/41

Then, the clients module gests all POST variables, binds the data and updates the record with the primary key = 41.

4. If you perform a DELETE request to the following URL:
http://localhost/clients/45

Then, the clients module executes a delete statement by primary key = 45 to delete the record.
 

NOTE: The table must have a single PK to perform the correct automatic actions.

 

Advanced requests

There a few other methods implemented in the Module Library to handle your RESTful requests, such as: select, insert, update, delete. So if you wish to customize your requests you can overwrite these methods as you wish.

1. If you perform a GET request to the following URL:
http://localhost/clients/select/1

Working as previously explained you can get the record information by primary key = 1 in a JSON format.

2. If you perform a POST request to the following URL:
http://localhost/clients/insert

Then an insert query will be performed to add a new record in the database.
 

NOTE: It is important that all POST variables within your request must match the columns in the table. But let's suppose this is not the case and we are sending more information, because we have a second client table that receives some normalized information.


In this case your module modules/Clients/Client.class.php might need to overwrite the method insert.

<?php

namespace modules\Clients;

use bossanova\Module\Module;

class Clients Extends Module
{
    public method insert($row=NULL)
    {
        // Get only the relevant for the operation
        $row = $this->getPost(array('client_name', 'client_phone'));

        // Insert the record and return the id
        return parent::insert($row);
    }
}

Following the logic from the example above, if you need customize your delete action because you don’t want to exclude the records, but logically changed the status of the record, then you can simple overwrite the method delete, for example:

<?php

namespace modules\Clients;

use bossanova\Module\Module;

class Clients Extends Module
{
    public method delete()
    {
        // Get the id of the record
        $id = (int)$this->getParam(2);
        // Create an instance of the model
        $client = new \models\Clients;
        // Get the record by Id, change the column value and save
        $client->get($id);
        $client->client_status = 0;
        $client->save();
    }
}

Insert, Update and Delete Callbacks

Another useful feature are the callback methods for the basic RESTful requests. So, following all basic methods insert(), update() and delete(), the BF will automatically call insert_callback(), update_callback() and delete_callback() if these methods are implemented in your module.

For example:

<?php

namespace modules\Clients;

use bossanova\Module\Module;

class Clients Extends Module
{
    public method update($row=NULL)
    {
        // Get only the relevant for the operation
        $row = $this->getPost(array('client_name', 'client_phone'));

        // Insert the record and return the id
        return parent::update($row);
    }

    public method update_callback($id)
    {
        if (isset($_POST['user_password']) && $_POST['user_password']) {
            // Bind password
            $password = $this->query->bind($_POST['user_password']);

            // Update user password
            $salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
            $​pass = hash('sha512', hash('sha512', $​password . $salt);
            $column['user_salt'] = "'$salt'";
            $column['user_password'] = "'$pass'";

            // Do other things ...
        }
    }
}

In the code above, after a UPDATE request is performed to change the client information (http://localhost/clients/update/2), the update_callback() method will be automatically executed, so you can run additional custom code.

 

Json returns

The most recommended way to return a JSON string is to call the json_encode([array]) method, for example:

For example:

<?php

namespace modules\Clients;

use bossanova\Module\Module;

class Clients Extends Module
{
    public method show()
    {
        // Get the client with id = 1
        $client = new \models\Clients;
        $row = $client->getById(1);

        // Return the json
        return $this->json_encode($row);
    }
}

 

Command line mode

Bossanova PHP Framework uses the environmental variable ARGV and can be used via command line mode without no further configuration. Basically, the first argument from the command line will work like the URL.

For example:
http://localhost/clients/profile/1

Can be used via CLI mode as:
%php index.php clients/profile/1
 

NOTE: If you try to call a restricted path via command line, you will need treat the authentication in your module. Basically, you will need to implement or bypass the security information according to your needs.