Database data within the BasePresenter

Se7en
Member | 13
+
0
-

Hi all.

I am trying to load a database table within my BasePresenter so that the data can be used via all the child presenters.

Here's the BasePresenter:

<?php
namespace App\Presenters;

use App\Data;
use Nette;

abstract class BasePresenter extends Nette\Application\UI\Presenter
{
    private $globalSettings;

    public function __construct(Data\GlobalTable $globalSettings)
    {
		parent::__construct();
		$this->globalSettings = $globalSettings;
    }

  	protected function startup()
	{
	    parent::startup();
		// Here we'll add some global settings from the database to make them available via other presenters
	}

}
?>

And here is an extended presenter example:

<?php
namespace App\Presenters;

use App\Data;
use Nette;

final class TestPresenter extends BasePresenter
{
	private $anotherTable;

	public function __construct(Data\AnotherTable $anotherTable)
	{
		parent::__construct();
		$this->anotherTable = $anotherTable;
	}
}
?>

But I get the following error:

ArgumentCountError

Too few arguments to function App\Presenters\BasePresenter::__construct(), 0 passed in /home/test/app/presenters/TestPresenter.php.........

Can anybody explain where I'm going wrong?

nightfish
Member | 472
+
+2
-

Se7en wrote:

Too few arguments to function App\Presenters\BasePresenter::__construct(), 0 passed in /home/test/app/presenters/TestPresenter.php.........

Can anybody explain where I'm going wrong?

When extending a class, you must pass all required parameters to parent's constructor.

There are two main ways of doing it:

  1. Add GlobalTable dependency to TestPresenter.php and pass it to parent, while leaving BasePresenter.php unchanged:
public function __construct(Data\GlobalTable $globalSettings, Data\AnotherTable $anotherTable)
{
 		parent::__construct($globalSettings);
 		$this->anotherTable = $anotherTable;
}
  1. In abstract presenters you can use dependency injection via @inject annotation. In BasePresenter.php change private to public, add @inject annotation:
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
    /** @var Data\GlobalTable @inject */
    public $globalSettings;

    // the rest of your code (constructor needs not be here, unless you do stuff other than assigning dependencies in it)
}

This way you can add dependencies to your BasePresenter without the need to explicitly pass them from child presenters.

See docs for more information.

Last edited by nightfish (2019-04-19 10:00)

Se7en
Member | 13
+
0
-

Thanks for the clear reply. That makes a lot of sense.

I still find it hard to find exactly what I'm looking for via the docs at times.

CZechBoY
Member | 3608
+
0
-

So start with some php tutorial and you learn that.