How to Create Custom Drivers in CodeIgniter

How to Create Custom Drivers in CodeIgniter

How to Create Custom Drivers in CodeIgniter

Filling in as a CodeIgniter Developer, you may have gone over the idea of a library that advances the center structure usefulness, and CodeIgniter itself gives bunches of valuable libraries in the center.

Thus, a driver is an exceptional sort of library that enables you to include custom highlights with the goal that the primary driver example worth following as a parent class and the connectors are dealt with as youngster classes.

The most ideal approach to comprehend the idea of drivers is to take a gander at how reserving is actualized in the center CodeIgniter structure. The primary Cache example of true excellence as a parent class and expands the CI_Driver_Library class. Then again, you’ll wind up discovering kid classes for APC, Memcached, Redis and so forth, executed as pluggable connectors. The kid classes broaden the CI_Driver class rather than the primary driver class.

The excellence of this methodology is that you could without much of a stretch expand the driver’s usefulness by including another connector as required. As on account of reserving, in the event that you have to include a custom storing system, you’re only a stage far from executing it as a custom connector.

Making a custom driver in the CodeIgniter Application is the point of the present article. Over the span of that, we’ll experience a genuine precedent that makes a MediaRenderer driver used to render the media from various administrations like YouTube, Vimeo and comparable. The diverse administrations will be actualized as connector classes.

Also Read:- PayPal Standard Payment Gateway Integration in PHP

File Setup
The name of the driver that we’re going to implement in this article is MediaRenderer. Let’s have a quick look at the list of files that are required for the desired setup:

1. application/libraries/MediaRenderer/MediaRendererInterface.php: It’s the interface that the adapter needs to implement.
2. application/config/mediarenderer.php: The configuration file that holds our custom driver related settings.
3. application/libraries/MediaRenderer/MediaRenderer.php: It’s the class that extends the CI_Driver_Library and is used to operate the different adapters available in the application.
4. application/libraries/MediaRenderer/drivers/MediaRenderer_youtube.php: It’s the class that implements the YouTube adapter.
5. application/libraries/MediaRenderer/drivers/MediaRenderer_vimeo.php: It’s the class that implements the Vimeo adapter.
6. application/controllers/Media.php: It’s the controller class that we’ll implement to demonstrate the usage of our custom driver.

Create Drivers
In this section, we’ll create the base files of our custom driver.

The first thing that we need to do is to define the configuration file of our custom driver. Let’s define the application/config/mediarenderer.php file as shown below.

<?php
$config['media_services'] = array('youtube', 'vimeo');
$config['media_default'] = 'youtube';

It indicates that we’re going to implement two adapters?—?YouTube and Vimeo. The default adapter is set to YouTube.

Go ahead and create a file application/libraries/MediaRenderer/MediaRendererInterface.php with the following contents.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
/**
 * MediaRendererInterface
 */
interface MediaRendererInterface
{
    public function display($id);
}

As you can see, it's a pretty basic interface that makes sure that the adapter that implements this interface must implement the display method.
Next, let's have a look at the MediaRenderer driver file.

Go ahead and create a file application/libraries/MediaRenderer/MediaRenderer.php with the following contents.

<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
interface_exists('MediaRendererInterface', FALSE) OR require_once(APPPATH.'/libraries/MediaRenderer/MediaRendererInterface.php');
 
/**
 * MediaRenderer Class
 */
class MediaRenderer extends CI_Driver_Library {
     
  public $valid_drivers;
  public $CI;
  protected $_adapter = 'youtube';
 
  /**
   * Class constructor
   */
  public function __construct()
  {
    $this->CI =& get_instance();
    $this->CI->config->load('mediarenderer');
    $this->valid_drivers = $this->CI->config->item('media_services');
    $this->_adapter = $this->CI->config->item('media_default');
  }
 
  /**
   * Overrided __get method to check if the adapter implements MediaRendererInterface interface
   * @see CI_Driver_Library::__get()
   */
  public function __get($child)
  {
      if (in_array($child, $this->valid_drivers))
      {
          $object = $this->load_driver($child);
           
          if ($object instanceof MediaRendererInterface)
          {
              return $object;
          }
          else
          {
              show_error("MediaRenderer: Adapter '".$child."' doesn't implement MediaRendererInterface. Aborting.");
              return;
          }
      }
      else
      {
                show_error('Unable to load the requested adapter: '.$child);
                return;
      }
  }
 
  /**
   * @param string $adapter Adapter name
   * @return MediaRenderer
   */
  public function setAdapter($adapter)
  {
      $this->_adapter = $adapter;
      return $this;
  }
 
  /**
   * @param string $id Media ID
   */
  public function display($id)
  {
      return $this->{$this->_adapter}->display($id);
  }
 
}

At the beginning of the file, we include the MediaRendererInterface interface that we’ve already defined earlier in this section.

As per the CodeIgniter driver standards, our class MediaRenderer extends the CI_Driver_Library class that makes sure that we could easily access driver adapters using the load_driver method defined in the CI_Driver_Library class.

Next, let’s have a close look at the constructor.

public function __construct()
{
  $this->CI =& get_instance();
  $this->CI->config->load('mediarenderer');
  $this->valid_drivers = $this->CI->config->item('media_services');
  $this->_adapter = $this->CI->config->item('media_default');
}

Recall the mediarenderer configuration file that we defined earlier and that’s exactly loaded in the constructor in the first place. It’s required that you set the list of adapters that are supported by the driver to the valid_drivers property, so we just did that as well. And finally, we’ve set the value of the default driver to the _adapter property for our convenience.

Also Read:- How to Integrate Payumoney Payment Gateway in Laravel 5

Moving further, let’s pull in the code of the __get method.

public function __get($child)
{
    if (in_array($child, $this->valid_drivers))
    {
        $object = $this->load_driver($child);
         
        if ($object instanceof MediaRendererInterface)
        {
            return $object;
        }
        else
        {
            show_error("MediaRenderer: Adapter '".$child."' doesn't implement MediaRendererInterface. Aborting.");
            return;
        }
    }
    else
    {
            show_error('Unable to load the requested adapter: '.$child);
            return;
    }
}

I would say that you’re not required to override this method, and our driver would work just fine without it as well. The reason behind the implementation of this method in our case is to enforce the implementation of the MediaRendererInterface interface, and thus it’ll make sure that each driver must implement the display method.

Next, let’s take a look at the setAdapter method.

public function setAdapter($adapter)
{
    $this->_adapter = $adapter;
    return $this;
}

As you can see, it’s just used to override the default adapter settings in case you want to use a different adapter for the time being.

Finally, there’s a display method that calls the display method of the corresponding adapter.

public function display($id)
{
    return $this->{$this->_adapter}->display($id);
}

Again, I would say that you can skip the implementation of the display method as you could always call the display method of the adapter directly, as we’ll see later in this article. However, I would like to access the adapters via the display method of the MediaRenderer class as this is the place where you could refactor the common code the adapter may implement.

Also Read:- Laravel vs Codeigniter, Which is Better PHP Framework?

So that was the MediaRenderer class at your disposal.

Create Adapters
We’ve been discussing the driver adapters for a while, and now it’s time to actually implement them.

Let’s start with the YouTube adapter file at application/libraries/MediaRenderer/drivers/MediaRenderer_youtube.php.

<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
/**
 * MediaRenderer_youtube Class
 */
class MediaRenderer_youtube extends CI_Driver implements MediaRendererInterface {
 
  /**
   * @param string $id Media ID
   * @see MediaRendererInterface::display()
   */
  public function display($id)
  {
    if ($id)
    {
      return '<iframe width="420" height="315" src="//www.youtube.com/embed/'.$id.'" frameborder="0"
allowfullscreen></iframe>';
    }
  }
 
}

It’s important to note that the adapter name is prefixed with MediaRenderer_, and it also extends the CI_Driver class. Also, it implements the MediaRendererInterface interface to make sure that we adhere to the standards we discussed earlier.

The reason our adapter class extends the CI_Driver class is to avail all the parent methods and properties. You’ve heard it right, you can access methods and properties of the MediaRenderer class from within the MediaRenderer_youtube class even though it doesn’t extend the MediaRenderer class directly.

Apart from that, it’s fairly easy to understand the implementation of the display method, which returns the embed code provided that the media ID is passed as an argument of the method.

The Vimeo adapter class is pretty identical to that of YouTube. Go ahead and create one at application/libraries/MediaRenderer/drivers/MediaRenderer_vimeo.php.

<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
/**
 * MediaRenderer_vimeo Class
 */
class MediaRenderer_vimeo extends CI_Driver implements MediaRendererInterface {
     
    /**
     * @param string $id Media ID
     * @see MediaRendererInterface::display()
     */
  public function display($id)
  {
      if ($id)
      {
      return '<iframe width="420" height="247" src="//player.vimeo.com/video/'.$id.'"></iframe>';
      }
  }
 
}

And that ends the discussion of adapters.

Putting It All Together
In the last couple of sections, we’ve discussed the driver and adapter classes. In this section, which is the last one in this article, we’ll extend our journey to go through a demonstration of basic driver usage.

Let’s start by creating a controller file application/controllers/Media.php.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
/**
 * Media Controller Class
 */
class Media extends CI_Controller {
  public function index()
  {
    // this will use default adapter as per the config file
    $this->load->driver('mediaRenderer');
     
    // IMP: it must be a lowercase drivername when you use it
    echo $this->mediarenderer->display("0GfCP5CWHO0");
     
    // override adapter settings by setting it explicitly
    echo $this->mediarenderer->setAdapter('vimeo')->display("225434434");
     
    // access the adapter directly
    echo $this->mediarenderer->vimeo->display("225434434");
    echo $this->mediarenderer->youtube->display("0GfCP5CWHO0");
  }
}

The first thing that we need to do is to load our custom driver mediaRenderer, and that’s what the following snippet does.

$this->load->driver(‘mediaRenderer’);

To access the custom driver that we’ve just loaded, you should use the $this->mediarenderer syntax. It’s important to note the name of the driver is in lower case, irrespective of the actual driver name.

Next, let’s examine what the following code does.

echo $this->mediarenderer->display(“0GfCP5CWHO0”);

It calls the display method of the MediaRenderer class in the first place, in that it delegates the control to the display method of the corresponding adapter that’s set as a default adapter in the mediarenderer configuration file. Eventually, it ends up calling the display method of the YouTube adapter as that’s the default adapter in our case.

On the other hand, if you want to call the display method of any specific adapter, you could always do that explicitly, as shown in the following snippet.

echo $this->mediarenderer->setAdapter(‘vimeo’)->display(“225434434”);

As I mentioned earlier, you could also call the display method of any specific adapter directly, without going through the display method of the MediaRenderer class.

echo $this->mediarenderer->vimeo->display(“225434434”);
echo $this->mediarenderer->youtube->display(“0GfCP5CWHO0”);

So that’s how you’re supposed to call the driver and its adapters alongside?—?thanks to the driver structure that allows you to plug in the new adapters on-the-fly as needed.

And that’s pretty much it. I hope that you’ve enjoyed the article, and you could always hit the comment section to express your thoughts and concerns.

Conclusion
A journey through the drivers in the CodeIgniter framework was the recipe of today’s article.

As always, the article started with a basic introduction to the concept of drivers in the CodeIgniter framework. As I promised, we went on to create a custom driver based on a real-world use case, and that I believe is the best way to understand a new concept.

Author Biography.

Lokesh Gupta
Lokesh Gupta

Overall 3+ years of experience as a Full Stack Developer with a demonstrated history of working in the information technology and services industry. I enjoy solving complex problems within budget and deadlines putting my skills on PHP, MySQL, Python, Codeigniter, Yii2, Laravel, AngularJS, ReactJS, NodeJS to best use. Through Knowledge of UML & visual modeling, application architecture design & business process modeling. Successfully delivered various projects, based on different technologies across the globe.

News & Blogs

6ec3fae84857a1f5dc59eebcc6c0775e.png

Building a carousel component in React using Hooks

One of the problems in web development today is the entangling of different layers. Not only do w...

2cda7519f703462a0eabd1c2e84e0001.jpg

Why shouldn’t you wait to jump onto Angular 2?

AngularJs is a JavaScript framework and is widely adopted framework in building Single Page Web A...

8b77d9abe1f73f94ea9f0f008ff988a1.jpeg

Difference between Sets vs. Arrays in JavaScript

The Set object type was introduced in the 2015 ECMAScript specification and is ready to be used i...