Welcome Guest, Not a member yet? Register   Sign In
Extending a framework (non-core) library
#1

In the docs I see:

Creating Core System Classes - https://bcit-ci.github.io/CodeIgniter4/g...asses.html

and it lists the core classes that one has the ability to extend or replace, and how to do that. But after skimming through the docs, I don't see where it is mentioned the proper way to extend framework libraries. In CI3 we had the MY_ prefixed method, but I understand we will be doing this a different way, just don't see a suggestion on how and where to do it.

So, for example, how would this be done for the Session library ??
Reply
#2

You could specify your own driver in application/Config/App.php (~ line 184), eg App\Session\MySessionHandler which implements CodeIgniter\Session\SessionInterface or which overrides one of the existing Session handlers. I am not sure if it would be better/appropriate to have your code inside application/Libraries, or to place it inside application/Session.
Reply
#3

If you wanted an even more transparent implementation, or if you wanted to override the Session class itself, you might be able to provide your own application/Config/Autoload.php, which mapped the namespaced CI4 class to your own implementation. Not sure how practical this is, and might have to wait for Lonnie to jump in & correct me!
Reply
#4

(09-16-2018, 10:46 AM)ciadmin Wrote: You could specify your own driver in application/Config/App.php (~ line 184), eg App\Session\MySessionHandler which implements CodeIgniter\Session\SessionInterface or which overrides one of the existing Session handlers. I am not sure if it would be better/appropriate to have your code inside application/Libraries, or to place it inside application/Session.

OK, so specifying the driver in config/app is great for sessions, but what if it was one of the other libraries, like Email, or Log?

You've probably noticed I'm starting to ask questions about CI4, and it's because it's only in the last day that I've started looking at the docs and comparing it to CI3. I realize this isn't CI3, but for the multitude of people that have been using CI < 4 for the last 10 years, we're going to want to have some of these things explained.

I asked about sessions because my authentication package has been extending sessions so that I can simply know what the old session ID was if it was regenerated. You might not expect to need that value, unless you're syncing a session with service that is holding the session ID as an identifier for service access. With CI3 I did this:


PHP Code:
public function sess_regenerate$destroy FALSE )
{
    
$this->pre_regenerated_session_id $this->session_id;

    
$_SESSION['__ci_last_regenerate'] = time();
    
session_regenerate_id($destroy);

    
$this->regenerated_session_id $this->session_id;

    return 
$this->session_id;



But yes, I would like to hear from Lonnie, and see what he has to say about extending libraries.
Reply
#5

Extending core libraries in most cases is really simple:

1. Create a new class that extends the old class (or replace it altogether if there's an interface available), and modify it to do what you want.
2. Copy the method from system/Config/BaseServices to application/Config/Services.php, and modify it to return your new class.

Services docs should help clear that I up, I hope.
Reply
#6

In general, instead of instantiating CodeIgniter\Something\Whatever (any of the libraries), you would instantiate App\Libraries\Mything, which extends CodeIgniter\Something\Whatever.

Or, add your custom class to the classmap, replacing or surplanting the built-in one.

At least, that is my take on it Smile

It is good to be asking these questions, btw!
Reply
#7

Oh - and since you're working on an auth package, you should probably read up on [url=https://bcit-ci.github.io/CodeIgniter4/general/modules.html#auto-discovery]how auto-discovery works[/b] for modules. Basically - you could keep a services/routes/etc config files in your package and those would be discovered by the system if it was setup to do so.
Reply
#8

OK, so I thought I'd run this buy you and see if this is right. Haven't actually tried it yet...

In my Config/Services file I copied the session method from system/Config/Services, then replaced "\CodeIgniter\Session\Session" with "\Universal\Auth\Adapters\CI4\SessionExtension" :

PHP Code:
public static function session(\Config\App $config null$getShared true)
{
 
   if ($getShared)
 
   {
 
       return self::getSharedInstance('session'$config);
 
   }

 
   if (! is_object($config))
 
   {
 
       $config config(App::class);
 
   }

 
   $logger self::logger(true);

 
   $driverName $config->sessionDriver;
 
   $driver     = new $driverName($config);
 
   $driver->setLogger($logger);

 
   $session = new \Universal\Auth\Adapters\CI4\SessionExtension($driver$config);
 
   $session->setLogger($logger);

 
   if (session_status() == PHP_SESSION_NONE)
 
   {
 
       $session->start();
 
   }

 
   return $session;


Then my SessionExtension class extends the CI class:

PHP Code:
<?php

namespace Universal\Auth\Adapters\CI4;

use 
CodeIgniter\Session\Session;

class 
SessionExtension extends Session {

    public 
$pre_regenerated_session_id NULL;
    public 
$regenerated_session_id     NULL;

    
/**
     * Class constructor
     */
    
public function __construct(\SessionHandlerInterface $driver$config)
    {
        
parent::__construct($driver$config);
    }

    
// ------------------------------------------------------------------------
    
    /**
     * Regenerates the session ID.
     *
     * @param bool $destroy Should old session data be destroyed?
     */
    
public function regenerate(bool $destroy false)
    {
        
$this->pre_regenerated_session_id session_id();

        
$_SESSION['__ci_last_regenerate'] = time();
        
session_regenerate_id($destroy);

        
$this->regenerated_session_id session_id();

        return 
$this->regenerated_session_id;
    }

    
//--------------------------------------------------------------------



Seems like it would work. I'll be testing in a couple of days when I think I've got it all ready.
Reply
#9

@skunkbad - that's exactly what I would do. Looks good.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB