Instantiation of component class Yii - php

I'm trying to understand a sequence of instatiation component class. As I understood an application component class has a lazy initialization (I've logged starting invokation of init() method). Let I've created a simple test component called document:
class Document extends CApplicationComponent{
private $_width='150';
public function init(){
echo "This is document component init method.";
}
public function getWidth(){
return $this->_width;
}
}
I've add a corresponding component's array to the config.php:
'components'=>array(
'document' => array( 'class' => 'document')
)
And it works, but I dont understand the sense. Actually, let we renamed component's file from Document.php to DDocument.php. Exception is raised after this renaming. Why? We doesn't renaming component's class name which specified in config.php. And what does keys of components array mean? Is it just property of Yii::app() object which are instances of CApplicationComponent?

Related

Extending SilverStripe method in SS4

I am trying to extend a method of a class but having no luck. I am doing this as part of an upgrade from 3.7 to 4.5. In 3.7 it was working fine without using traits. Reading documentation, i used ‘Extensible’ trait. Now i am getting the following error. Checked all my method access levels. All are public but still gets this error
Fatal error : Access level to SilverStripe\Core\Extensible::defineMethods() must be public (as in class SilverStripe\View\ViewableData)
class MyOpenController extends Controller {
use Extensible;
private static $allowed_actions = array(
'login',
'logout'
);
public function login($data = array()) {
//code here
$this->extend('customFunction');
//more code
}
}
I have an Extension class that has definition for this method.
class MyOpenControllerExtension extends Extension
{
public function customFunction() {
//some code here
}
}
cant seem to get why i am having this error. Can someone please help me figure out what is wrong here.
Thanks
DR
ViewableData in SilverStripe 4 already implements the Extensible, Injectable, and Configurable traits that make up the common foundation you are used to from SilverStripe 3. You only need to add the Extensible trait for custom classes - anything extending Controller or DataObject already has them.
The error you are getting is caused by applying this trait twice in your class's hierarchy. ViewableData applies it, and essentially redefines the defineMethods() method at a public level. When you apply the trait again further down the hierarchy, it tries to define the defineMethods() method again at protected visibility, which is what is causing your error.
Removing use Extensible; from your controller will fix your problem.
Also, ensure you have applied your extension to your controller in YAML config:
# File: app/_config/extensions.yml
MyOpenController:
extensions:
- MyOpenControllerExtension

symfony router library not find controller

I have This folder structure for my mvc project:
application
---admin
--------controller
--------model
--------view
--------language
---front
--------controller
------------------BlogController.php
--------model
--------view
--------language
core
public
I work With symfony router library and route my url like this:
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$routes = new RouteCollection();
$routes->add('blog_list', new Route('/blog', array(
'_controller' => [application\front\controller\BlogController::class, 'index']
)));
return $routes;
BlogController.php is:
namespace application\front\controller;
class BlogController extends Controller
{
/**
* Construct this object by extending the basic Controller class
*/
public function __construct()
{
parent::__construct();
}
public function index()
{
echo 'fine';
}
}
But In Action I can't see Any output. I think syfony can find my controller. Can I fix this problem ?!
You didn't define which symfony version you are using. But checking from similar example on https://symfony.com/doc/current/routing/custom_route_loader.html for latest one (4.1), it looks like the controller value should be a string instead of an array (I haven't needed to use this kind of 'manual' route definition myself so I don't really know whether the constructor supports several different ways of defining the controller value - meaning that this is more of an educated guess what your issue could be :)).
$routes->add('blog_list', new Route('/blog', array(
'_controller' => 'application\front\controller\BlogController::index'
)));

create shared view model in zend framework 2 project

I want to assign generic variables to the view renderer outside the controller action.
I'd prefer to handle this in the module class bootstrap.
My question is, how do I create a view model in the module class bootstrap that can be shared with the controller .
My end result is to have the ability to add variables to the view model before we create a new instance of one inside the controller action.
Here's something I started on, however i cannot add variables to the declared viewmodel and have it persist to the controller's new instance of a view model.
Is there a way to create a view model and have it set as the renderer before dispatch.
Here's something i started but if i can get it in the module class bootstrap instead id prefer that.
I dont think this works though.
class BaseController extends AbstractActionController
{
protected $viewModel;
public function onDispatch(MvcEvent $e)
{
$this->viewModel = new ViewModel([
'module' => 'modulename',
'controller' => 'controllername',
'action' => 'actionname'
]);
parent::onDispatch($e);
}
}
In the Module.php you have access to the event object.
In this event you can set some variables like this :
$event->getViewModel()->setVariable('isAdmin', $isAdmin);
$event->getViewModel()->setVariable('var', $var);
$event->getViewModel()->setVariable('form', $form);
$event->getViewModel()->setVariable('uri', $uri[0]);
If you want to test more you can also do :
$widgetTemplate = new ViewModel();
$widgetTemplate = $widgetTemplate->setTemplate('widget/container');
$event->getViewModel()->addChild($widgetTemplate, 'widget');
Those variables are available in your layout.phtml. I didn't test if it's the same viewModel available in your controller, give me a feedback if you test this solution.
For a variable defined in module.php, you can also use the Zend\Container\Session component to modify it in controllers

silverstripe init() function

Can someone explain this code in Silverstripe:
public function init() {
RSSFeed::linkToFeed($this->Link() . "rss");
parent::init();
}
What exactly is init function?
what parent::init();
exactly do in code
in php classes when you overwrite a method of parent class you still can call the parent class with this code, it will help you to put some code at the beginning of the real method without removing it.
you can find out more about it at php documentation
The upmost init() method is defined in the Controller class.
Then ContentController extends Controller, which overrides the Controller class's init() method, but it's also calling parent::init() on the first line. Then usually you define all your page controller classes like this (for any new page type), in the example below for the default Page_Controller class:
class Page_Controller extends ContentController {
public function init() {
parent::init();
// do your own stuff here
}
}
So this is the traditional PHP based class extension mechanism, but Silverstripe also allows you to use Extensions and Data Extensions, which is basically extending the functionality of already existing controllers, data objects. I won't go into details with this... You can find out more about this here: https://docs.silverstripe.org/en/4/developer_guides/extending/extensions/
I usually have something like this in my controller classes:
class Page_Controller extends ContentController {
public function init() {
parent::init();
// do your own stuff here
$this->extend('updateInit');
}
}
Notice the $this->extend('updateInit'); line above.
I can have another extension defined for the Page_Controller class inside a YAML config file somewhere, and than have the updateInit() method defined in that class. Example:
class Page_Controller_Extension extends Extension {
public function updateInit() {
// do some more stuff here
}
}
...and in this case you would have something like this in a YAML config file:
---
Name: siteextensions
After:
- 'framework/*'
- 'cms/*'
---
Page_Controller:
extensions:
- Page_Controller_Extension
Note that this is not really the traditional way of extending classes, like in PHP, it's more like defining some decorators for a controller class. Also, to refer to the parent, or object being decorated, you can't use just $this, you'll need to use $this->owner. Example below:
class Page_Controller_Extension extends Extension {
public function updateInit() {
// do some more stuff here
if ($this->owner->IsFeatured) {
// do something here
}
}
}
You usually decorate controllers extending the Extension class, and you extend the DataExtension class if you want to decorate DataObjects - works the same way as explained above.

zf2 view helper across module

I created a helper in the application module, and it works perfectly. When I try to load it from another modules, such as user, it tells me that it can not find the class.
Class 'Application \ View \ Helper \ Footertable' not found
I tried to put this code in module.config.php well as the application module even in the same file of the user module.
'view_helpers' => array (
'invokables' => array (
'footertable' => 'Application\View\Helper\Footertable'
)
),
I think it's a problem autoloading class but I can not find information on how to load this helper when you are in another module
I invoke helper in view file using
$this->footertable()
work perfectly in application module but not in user module
any idea?
Hello,
but my code is correct
<?php
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
class Footertable extends AbstractHelper{
protected $inizioFine;
protected $numero;
public function __invoke($inizioFine,$numero){
$this->inizioFine = $inizioFine;
$this->numero = $numero;
echo sprintf('Mostra %d a %d di %d record',$this->inizioFine['start'],$this->inizioFine['end'],$this->numero);
}
}
the space in config is an copy & past errors.
I still have the same problem: can't load helper from another module
update full error
Fatal error: Class 'Application\View\Helper\Footertable' not found in D:\www\httpdocs\test\vendor\zendframework\zendframework\library\Zend\ServiceManager\AbstractPluginManager.php on line 170
path is
D:\www\httpdocs\test\module\Application\src\View\Helper\Footertable.php
The path you posted doesn't look right. All the files in src for your Application module should be inside a folder called Application, since that's your top level namespace. So the path should be:
D:\www\httpdocs\test\module\Application\src\Application\View\Helper\Footertable.php
That would explain why the helper can't be autoloaded, but I don't understand how it works in the application module if this is the case.
Your configuration seems good. Probably the problem is in your helper class signature.
Since PhpRenderer composes a HelperPluginManager instance to manage helpers, your helper should implement the HelperInterface (1) to be registered correctly. Also you should write an __invoke() method within your helper to invoke it by method call. (2)
So, in your Footertable class, simply extend the AbstractHelper and make sure you have an _invoke() method. This is recommended way to write custom view helpers in documentation.
For example:
<?php
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
class Footertable extends AbstractHelper
{
public function __invoke()
{
return 'bar';
}
}
And use it in your views like this:
echo $this->footertable();
It should work.
Note: You also have to register all helpers (and other classes) in your module configuration's invokables section without spaces between the backslashes:
Wrong:
'footertable' => 'Application \ View \ Helper \ Footertable'
Correct:
'footertable' => 'Application\View\Helper\Footertable'

Categories