Using $this when not in object context with LocatorAwareTrait

Hi,

When i use the deprecated TableRegistry in a component to log the user login with Ip adres everthing works.
But if i use the new LocatorAwareTrait is get the error “Using $this when not in object context”.
What do i wrong and what can i do to let it work with the new way?

use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use Cake\ORM\Locator\LocatorAwareTrait;
use Cake\ORM\TableRegistry;
use Cake\Http\ServerRequest;

/**
 * Logs component
 */
class LogsComponent extends Component
{
    /**
     * Default configuration.
     *
     * @var array
     */
    protected $_defaultConfig = [];

    public function saveIP($user_id)
    {
        $request = new ServerRequest;
        //$logTable = TableRegistry::getTableLocator()->get('Logs');
        $logTable = LocatorAwareTrait::getTableLocator()->get('Logs');
        //$logTable = $this->getTableLocator()->get('Logs');
        $log = $logTable->newEmptyEntity();
        $log->user_id = $user_id;
        $log->ip = $request->clientIp();
        $logTable->save($log);
    }
}

You’re loading the trait incorrectly. Here is the php documentation explaining traits.




    use Cake\ORM\Locator\LocatorAwareTrait;

    class LogsComponent extends Component
    {

        //This is the proper way to load a trait
        use LocatorAwareTrait;

        protected $_defaultConfig = [];

        public function saveIP($user_id)
        {
            $request = new ServerRequest;

            //Then you use the trait methods as though they are
            //  methods of your class
            $logTable = $this->getTableLocator()->get('Logs');

            $log = $logTable->newEmptyEntity();
            $log->user_id = $user_id;
            $log->ip = $request->clientIp();
            $logTable->save($log);
        }
    }

It might also help to know that the Controller that is currently using your Component is available inside the component at:

$this->getController();

So things like the request will already be available off the controller.

$this->getController()->getRequest();
//or
$this->getController()->request;

Thanks it is working.
I read the documention on php and now it’s clear.
Maybe it is 100% on me, but the documentation on cakephp example give an other solution that not works for me.
Is that my fault or a fault in the documentation? (database access & ORM and then Saving data)

use Cake\ORM\Locator\LocatorAwareTrait;

$articlesTable = $this->getTableLocator()->get('Articles');
$article = $articlesTable->newEmptyEntity();

$article->title = 'A New Article';
$article->body = 'This is the body of the article';

if ($articlesTable->save($article)) {
    // The $article entity contains the id now
    $id = $article->id;
}

Well, the documentation assumes a high degree of familiarity with php.

The challenge using a framework (regardless of the language) is the framework documentation will always assume you already know the language and all the concepts associated with the language. So there is always the possibility of having to learn on two fronts to get things working.

The documentation code is actually correct but it doesn’t show you the context of each of the example lines as I did in my snippet.

You can submit an improved example for the documentation if you like. But again, this process will assume a familiarity with git and the process of making a pull request :slight_smile: . The learning never ends!