[owncloud-devel] Injecting services and variables to App constructors and calling them

Josef Meile jmeile at hotmail.com
Wed Aug 5 17:14:54 GMT 2015


Dear all

I have developed the AgreeDisclaimer App and it is working as it should;
however, I got the feedback from another developer that I should avoid this
things:
1) \OC::$server calls
2) Using "\OCP\Util::writeLog" for the logger or "\OCP\Util::getL10N" for
translating things

The recommendation was to inject them into the constructors. I have tried to
do this, and in some cases I succeeded, but in others don't. First, I tried
to inject the L10N service in my controller:

class SettingsController extends Controller {
    private $trans;

    public function __construct($AppName, IRequest $request, IL10N $trans) {
        parent::__construct($AppName, $request);
        $this->trans = $trans;
    }

   /* Some more code comes here */

}

Then I called the constructor as follows in Application.php:
class Application extends App {
    private $appId;

    public function __construct($appId, array $urlParams=array()) {
        parent::__construct('agreedisclaimer', $urlParams);

        $this->appId;
        $this->registerServices();
        $this->registerHooks();
        $this->registerSettings();
    }

    public function registerServices() {
        $container = $this->getContainer();

        $container->registerService('L10N', function($c) {
            return
$c->query('ServerContainer')->getL10N($c->query('AppName'));
        });

        $container->registerService('SettingsController', function($c) {
            return new SettingsController (
                $c->query('AppName'),
                $c->query('Request'),
                $c->query('L10N')
            );
        });
    }

   /* Some more code comes here */
}

Then I tried to use the $trans variable in a method of my controller as
follows:
    public function getFile($userLang, $defaultLang, $basePath, $fileExt,
            $getContent = false, $maxFileSize = 2, $getFallbackLang = true)
{

       /* Some code comes here */

            $errorMsg = $this->trans->t('%s doesn\'t exist.',
                $userLangFile . '<br/>') . ' ' .
                $this->trans->t('Please contact the webmaster');

       /* Some more code comes here */
    }

I got an error exactly on that line:
"Call to a member function t() on a non-object at
\var\www\html\owncloud\apps\agreedisclaimer\controller\settingscontroller.ph
p#227"

The function getFile gets called from another function called "getFiles",
which is a route called through an ajax request:
    function getFiles($isAdminForm = false, $defaultLang = null) {

       /* Some code comes here */

        $fileInfo = $this->getFile($userLang, $defaultLang,
$txtFileBasePath,
            'txt', true, $maxTxtFileSize, $getFallbackLang);

       /* Some more code comes here */
}

And here the routes:
<?php
return ['routes' => [
    ['name' => 'settings#get_settings',
     'url' => '/settings/get_all', 'verb' => 'GET'],
    ['name' => 'settings#get_files',
     'url' => '/settings/get_files', 'verb' => 'GET'],
]];

I think that the problem is that "getFiles is a route, so it doesn't really
needs an object instance to the SettingsController class. It is some kind of
static function, so, that's why "$this" can't be used. My original code is
using:
\OCP\Util::getL10N($appId)->t('%s doesn\'t exist.', $userLangFile . '<br/>')

and it works. But it isn't the way of doing it according to the Developers
manual, so, how can I solve this problem?

The second problem I'm facing: on the class "Application", I defined a
private variable called "$appId". I would like to inject it to the admin
page, but I don't know how to do this. First I registered the admin page on
the "Application" class:

\OCP\App::registerAdmin($this->appId, 'admin');

Then in the "agreedisclaimer/admin.php" file, I render the template:
agreedisclaimer/templates/admin.php

\OCP\User::checkAdminUser();
$data = [];
$templateResponse = new TemplateResponse($appId, 'admin', $data, 'blank');
return $templateResponse->render();

How can I get the Application object from "agreedisclaimer/admin.php" and
push the $appId variable into the $data array? Here again, my workaround was
a static class variable instead of a private one:

class Application extends App {
  const APP_ID = 'agreedisclaimer';

       /* Some more code comes here */
}

Then I called it like: Application::APP_ID, but this isn't the way it should
be. How can I avoid using this static constant?

Thanks in advanced.

Best regards
Josef



More information about the Devel mailing list