Passing Secondary Database Connection from Controller to custom Class

Permalink
Hi Everyone,

I have been trying to develop a little importable class that will simplify calls to the database for my website, currently I have hit a wall.

Im trying to give the custom class access to a different than default database connection similar to what is documented here:https://documentation.concrete5.org/developers/database-management/c...

While trying to pass my database to the custom class I followed a few ways of doing so, first I tried this (documented on this pagehttps://documentation.concrete5.org/developers/database-management/a...
Controller
/* namespace and block controller */
require('application/wanikani/wkuiapi/wkuiapi.php'); // use and require im not 100% with this
use Application\Wanikani\Wkuiapi\Wkuiapi;
defined('C5_EXECUTE') or die(_("Access Denied."));
class Controller extends BlockController
{
 /* Standard Code */
    public function view()
    {
        $WKUIAPI = Core::make('Application\Wanikani\Wkuiapi\Wkuiapi');
        /* call to functions in the class*/
     }
/* other code */


Class file
namespace Application\Wanikani\Wkuiapi;
use Concrete\Core\Database\Connection\Connection;
class Wkuiapi {
  protected $connection;
  public function __construct(Connection $connection)
      {
            $this->connection = $connection; // Calling this returns the concrete database 
        //  $this->connection =  \Database::connection('wanikani_accounts'); // Calling this results in Divide by 0
      }
   /* Rest of functions*/
}


Is there something im missing when initializing the class with ::make that sends the wrong database info?

Another way i tried was sending the db connection using a function but that resulted in divide by 0 again.
Controller
// Set connection
$db = \Database::connection('wanikani_accounts');
// Call Function to set DB
$WKUIAPI->setDB($db);

Custom Class
public function setDB ($db) {
  $this->connection = $db; // results in divide by 0
}


So any help would be greatly appreciated as this has completely stumped me.

Thanks in advance :3

View Replies: View Best Answer
jero replied on at Permalink Reply
jero
Rather than passing the connection, why not simply pass the database name? e.g. 'pricing'?

Then, in the class, just do $db = \Database::connection($passedDB); wherever you need a connection.

I built a site recently where it needed a second database (a legacy db) and I simply added the database config and then loaded it with $db = \Database::connection('external_db');
drago2308 replied on at Permalink Reply
Hi Jero,

Thanks for the suggestion however I have tried this before and results are exactly the same as the second method i tried (which is binding it to a public variable available to the whole class. (divide by zero)

Was there anything special you did to initiate the custom class to not get this error?
jero replied on at Permalink Reply
jero
Nope - nothing particualry exciting. Most of the code shared a base controller which had its own connection method, but that was simply this:

<?php
namespace Concrete\Package\MyPackage\Src\Lib\Controller;
use Concrete\Core\Page\Controller\PageController;
use Config;
use Database;
use Concrete\Core\Error\Error;
use Core;
defined("C5_EXECUTE") or die("Access Denied.");
class SearchController extends PageController {
   protected function Connection(){
      return Database::connection('externaldb');
   }
}


Then any class that extended it, would call $db = $this->Connection(); and that would be all it needed to do.

I did of course change application/config/database.php so it had the other db definition in it:
<?php
return array(
    'default-connection' => 'concrete',
    'connections' => array(
        'concrete' => array(
            'driver' => 'c5_pdo_mysql',
            'server' => 'localhost',
            'database' => 'c5',
            'username' => '*****',
            'password' => '****',
            'charset' => 'utf8',
        ),
   'externaldb' => array(
      'driver' => 'c5_pdo_mysql',
      'server' => 'localhost',


This is all using 5.7.5.13
drago2308 replied on at Permalink Reply
Hi Again,

Thanks for the insights but I still seem to be stuck....
The Database is definitely defined in the global settings as it can be called anywhere in a controller or view.

I tried extending the Block controller to see if this could get the Database, unfortinatly it has the same issue of Division by zero whenever $something = Database::connection(); is called.
(im sure extending the block controller from here is wrong but it was worth a shot)
namespace Application\Wanikani\Wkuiapi;
use Concrete\Core\Database\Connection\Connection;
use Concrete\Core\Block\BlockController;
use Database;
use Core;
defined("C5_EXECUTE") or die("Access Denied.");
class Wkuiapi extends BlockController {
  protected $connection;
  public function __construct()
      {
          $this->connection =  Database::connection('wanikani_accounts');
      }
/* Other Stuff*/
}


I'm initiating the class using the following
$WKUIAPI = Core::make('Application\Wanikani\Wkuiapi\Wkuiapi');
// Calling a function
$users = $WKUIAPI->getUser("%");

Is this wrong??

Thanks for the help
jero replied on at Permalink Best Answer Reply
jero
It seems a slightly strange way to be loading things up. In my project everything was within a package hierarchy and as such the appropriate use statement meant everything loaded when required. You're somewhat outside the expected with application/Wanikani etc.

I'd suggest you try creating a package, which will make everything portable. But you could also try putting your API class into application/controllers/wkuiapi.php with a namespace of Application\Controller and then in every piece of code that needs to use it, add:

use Application\Controller\Wkuiapi;
...
$WKUIAPI = new Wkuiapi();
$WKUIAPI->myfunc();
drago2308 replied on at Permalink Reply
Hi Again,

So found the issue and it was not located near where i thought it was.

Turns out the database WAS connecting fine using Database::connection('database'); And somewhere else in my code previously working code produced a value of 0 which caused a division by zero error in my View. So turns out i was looking in the wrong place for longer than i needed too.

This also made me curious, what is the difference of calling a class using the Core::make function compared to the standard new Class(); function. since both seem to do similar things.

Thanks for all the help and sorry to waste your time on this. Turns out I was just shortsighted in the end.