Creating components

A component is a reusable object that should contain only logic, and it is callable from every point of the app. In a component, we put all the functions that are usable in more than one place of the app.

Technically, a component extends yiiaseComponent that implements the property, event and behavior features. We can have two kinds of component: component and application component. The only difference between them is that the second has to be also configured in the configuration file of the app in the components property and it is available as a property from the Yii::$app object. Examples of application components are db, user, and so on.

Usually, components are stored in the components folder starting from the root folder of the project.

Let's see how to create a simple custom component:

namespace appcomponents;
 
use Yii;
use yiiaseComponent;
 
class MyComponent extends Component
{
..
..
}

We can instantiate this component as follows:

$myCmp = new appcomponentsMyComponent();

Then, we will have a new instance of the MyComponent object.

If we want to render this component into the application component and access to it through Yii::$app->myComponent, we must update the configuration file, web.php, at basic/config:

'components' => [
    ..
    ..
        'myComponent' => [
            'class' => 'appcomponentsMyComponent'
        ],
]

At this point, we can call myComponent using:

Yii:$app->myComponent

Note

Remember that an application component is a single and shared instance of the same object.

We can make custom initializations when a component is instantiated by overriding the init() method of the component.

A concrete example of the component (or the application component, according to our needs) could be sending an SMS to the SMS gateway for the app.

The component could be:

namespace appcomponents;

use Yii;
use yiiaseComponent;
 
class SmsGateway extends Component
{
    public function send($to, $text)
    {
        ..
        ..
        ..
    }
}

This example is suitable to use this component as an application component:

'components' => [
    ..
    ..
        'smsgw' => [
            'class' => 'appcomponentsSmsGateway
        ],
]

That is usable directly from:

Yii:$app->smsgw->send('+3913456789', 'hello world!');

Another common example for an application component could be an object to send push notifications to mobile devices, which is made in the same way as the previous SMS gateway object.

Example – creating a component that creates a backup of the MySQL database and sends an e-mail to the administrator

This example will show a common task concerning the creation of backup copies for the main database and the alert messages that the administrator receives once complete.

A backup will be taken using the command line MySQL tool.

Maintenance operations should be executed in a console environment since they can be scheduled (every day, every week, two days a week, and so on), and they could cause a web server timeout (usually, if an operation is not finished, the web server will return a timeout error after 30 seconds) if this operation takes longer than the maximum time available. So we will start by creating a console controller in the advanced template that we previously installed.

Remember that the project root folder for the advanced template is yiiadv.

Create a new component in Maintenance.php at yiiadv/common/components with this content:

<?php
namespace commoncomponents;
 
use Yii;
use yiiaseComponent;
 
class Maintenance extends Component
{
    public function launchBackup($database, $username, $password, $pathDestSqlFile)
    {
        $cmd = sprintf('mysqldump -u %s -p%s %s > %s', $username, $password, $database, $pathDestSqlFile);
        $outputLines = [];
        exec($cmd, $outputLines, $exitCode);

        return ['cmd' => $cmd, 'exitCode' => $exitCode, 'outputLines' => $outputLines];        
    }
}
?>

The launchBackup() method will launch mysqldump (which should be installed in the system) by passing the username, password, database, and the destination file path where the SQL output of this command is to be stored.

Then, it will return an array with these values: command, exit code of command, and its possible output text. Now let's create the console controller that we will use to launch the command. We could also launch it from a web controller, for example after clicking on a button.

Let's create the console controller in MaintenanceController.php at yiiadv/console/controllers:

<?php

namespace consolecontrollers;

use yiiconsoleController;
use yiihelpersConsole;
use commoncomponentsMaintenance;

class MaintenanceController extends Controller
{
    public function actionBackupDatabase()
    {
        $tmpfname = tempnam(sys_get_temp_dir(), 'FOO');
        $obj = new Maintenance();
        $ret = $obj->launchBackup('username', 'password', 'database_name', $tmpfname);

        if($ret['exitCode'] == 0)
        {
            $this->stdOut("OK
");        
            $this->stdOut(sprintf("Backup successfully stored in: %s
", $tmpfname));        
        }
        else
        {
            $this->stdOut("ERR
");
        }
        
        // equivalent to return 0;
        return $ret['exitCode'];
    }
    
}

?>

Let's make some considerations:

  • We could set the launchBackup() method of the maintenance component as static by avoiding to create an instance of the object; however, if we keep it nonstatic, we could also use it as application component. Otherwise, if we mark the method as static, and then use it as application component when calling the static method launchBackup() from the object, we will receive a warning from PHP.
  • We could move the file creation inside the launchBackup() method because in this case it is a temporary file, but generally we could use a specific file path.
  • We could avoid passing database info and get it from Yii parameters, if we store them in the parameters file.

A more complete action is to back up and send an e-mail to the administrator, containing the backup result and eventually, if needed, also the backup file:

    public function actionBackupDatabaseAndSendEmail()
    {
        $tmpfname = tempnam(sys_get_temp_dir(), 'FOO'); // good
        $obj = new Maintenance();
        $ret = $obj->launchBackup('username', 'password', 'database_name', $tmpfname);

        $emailAttachment = null;
        if($ret['exitCode'] == 0)
        {
            $this->stdOut("OK
");        
            $this->stdOut(sprintf("Backup successfully stored in: %s
", $tmpfname));
            
            $textEmail = 'Backup database successful! Find it in attachment';
            $emailAttachment = $tmpfname;
        }
        else
        {
            $this->stdOut("ERR
");
                    
            $textEmail = 'Error in backup database! Check it!';
        }
        
        $emailMsg = Yii::$app->mailer->compose()
            ->setFrom('[email protected]')
            ->setTo('[email protected]')
            ->setSubject('Backup database')
            ->setTextBody($textEmail);
            
        if($emailAttachment!=null) $emailMsg->attach($emailAttachment, ['fileName' => 'backup_db.sql']);
        $emailMsg->send();            
        
        // equivalent to return 0;
        return $ret['exitCode'];
    }
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.180.76