How to automatically set and attribute to controller - zend-framework

Maybe the question is not self-explanatory, so I will explain it through.
The deal is: I got the variable $conn in the bootstrap class file. I'd like to make it global for every controller so that I just have to call $this->conn in the controller action scope in order to access the data inside. How would I do it?
Thx

One fairly straightforward way is to create your own base class form which your controller's inherit:
<?PHP
class My_Controller_Action extends Zend_Controller_Action {
public $conn;
public function init(){
//set $this->conn
}
}
class Some_Real_Controller extends My_Controller_Action {
//$this->conn exists!
}
class Some_Other_Real_Controller extends My_Controller_Action {
//$this->conn exists here too!
}

Matthew Weier O'Phinney posted a blog entry recently with some examples of how to use action helpers to do this, see:
http://weierophinney.net/matthew/archives/235-A-Simple-Resource-Injector-for-ZF-Action-Controllers.html
this will achieve the same thing without having to use a base controller class.

Related

Normal function in Extbase controller

Is it possible to write a normal function in the controller?
I want to clean up my code a bit, so I want to write some methods for repeated code segments, but I don't want to create a special class.
How is it possible to do this?
If I do a normal
private function xyz () {}
I got a function not found error.
You should use protected, not private unless you have very good reasons to do so. Anyway, defining additional methods work fine for me.
You need to call this method with $this->xyz().
A good solution might be using an abstract class if you want to share methods accross controllers:
abstract class AbstractController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController{
protected function myFunction(){}
}
Your controllers inherit from the abstract class and will have all methods available:
class FirstController extends AbstractController {
public function firstAction(){
// has access to myFunction()
}
}
class SecondController extends AbstractController {
public function secondAction(){
// has access to myFunction()
}
}

Variables available in all controllers?

Where and how to set variable value that is available in all controllers. I don't wont to use zend registry and don't want to extend Zend_Controller_Action. Is there is another way? I just want for example to set:
$a = "test";
and in Index controller to dump it:
class IndexController extends Zend_Controller_Action {
public function indexAction(){
var_dump($a);
}
}
Global vars ruin the purpose of object oriented programming... use namespace or custom configs.
Solution 1
Use session Zend_Session_Namespace, here is documentation on how to Zend_Session_Namespace.
Set set the value in namespace in bootstrap or something (wherever you see fit)
Retrieve the value from namespace in you controller/model/other
Solution 2
Alternatively, you can create some new class with static properties and use it's setters/getters to set and retrieve values.
E.g.
class SomeClass
{
static $hello = 'world';
}
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
var_dump(SomeClass::$hello);
}
}
You can add variables to the request object:
$this->getRequest()->setParam('a', 'hello');
Then retrieve it using:
$this->getRequest()->getParam('a);
But that is not the best way of doing it as you might accidentally overwrite a parameter a needed parameter.

Zend Framework - How can i share common code between some of a controller's actions?

To keep my controllers as DRY as possible i need to share some common code (a big chunk of code) between say 2 of my controller's actions and not all of them and i need access variables in this shared code in my actions.
For example:
class FirstController extends Zend_Controller_Action {
public function firstAction() {
//common code here: contains an array $columns
}
public function secondAction() {
//common code here: contains an array $columns also
}
//other actions
}
so how can I refactor this to put the common code in one place and be able to access $columns and in firstAction() and secondAction().
Thanks.
I don't recommend you to use a base controller. It's overkilling and heavy for such a small task. Since you want to share common code within one controller, use instead an action helper and a class attribute $columns that you can send as argument to your action helper.
Read more about action helpers here.
Action Helpers allow developers to inject runtime and/or on-demand
functionality into any Action Controllers that extend
Zend_Controller_Action. Action Helpers aim to minimize the necessity
to extend the abstract Action Controller in order to inject common
Action Controller functionality.
You can create new class and extend Zend_Controller_Action then extend your newly created class not Zend_Controller_Action
example:
class CommonactionsController extends Zend_Controller_Action {
public function firstAction() {
//common code here : contains an array $columns
}
public function secondAction() {
//common code here : contains an array $columns also
}
//other actions
}
and then:
class FirstController extends CommonactionsController {
// here you can use all your common actions...
}
second controller..
class SecondController extends CommonactionsController {
// here you can use all your common actions...
}
and so on...

ZendFramework Send variables from Controller to View (Best pactice)

I have been working in Zend Framework for a while and I am currently refactoring some parts of my code. One of the big thing I would like to eliminate is my abstract controller class which initiate a lot of variables which must be present in all my controller such as $success, $warning and $error. This part can be done in controller pluggins but what would be the best way to send these variables to the related view. Currently I am using a custom method in my abstract controller class which i call from within all my controllers.
protected function sendViewData(){
$this->view->success = $this->success;
$this->view->warning = $this->warning;
$this->view->error = $this->error;
}
which is then called in all the actions of all of my controllers throught
parent::sendViewData();
I was looking to automate this process through a plugin controller or anything better suited for this
You could set a postDisplatch method in your abstract controller to initialize the view data (See section "Pre- and Post-Dispatch Hooks").
That way, in each actions, you could initialize your $this->success, $this->warnning or $this->error variables, and it would be pass to the view after the action is executed.
The Best pactice is, define a base controller and let other controllers to extend this, instead of directly calling the Zend_Controller_Action method
// Your base controller file ApplicationController.php
class ApplicationController extends Zend_Controller_Action {
// method & variable here are available in all controllers
public function preDispatch() {
$this->view->success = $this->success;
$this->view->warning = $this->warning;
$this->view->error = $this->error;
}
}
Your other normal controllers would be like this
// IndexController.php
class IndexController extends ApplicationController {
}
Now these (success, warning & error) variable are available in all views/layout files, In ApplicationController.php you can also hold shared functionality of other controllers.

how to parametrize an import in a View?

I am looking for some help and I hope that some good soul out there will be able to give me a hint :)
I am building a new application by using MVVM Light. In this application, when a View is created, it instantiates the corresponding ViewModel by using the MEF import.
Here is some code:
public partial class ContractEditorView : Window
{
public ContractEditorView ()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
}
[Import(ViewModelTypes.ContractEditorViewModel)]
public object ViewModel
{
set
{
DataContext = value;
}
}
}
And here is the export for the ViewModel:
[PartCreationPolicy(CreationPolicy.NonShared)]
[Export(ViewModelTypes.ContractEditorViewModel)]
public class ContractEditorViewModel: ViewModelBase
{
public ContractEditorViewModel()
{
_contract = new Models.Contract();
}
}
Now, this works if I want to open a new window in order to create a new contract... or in other words, it is perfect if I don't need to pass the ID of an existing contract.
However let's suppose I want to use the same View in order to edit an existing contract. In this case I would add a new constructor to the same View, which accepts either a model ID or a model object.
"Unfortunately" the ViewModel is created always in the same way:
[Import(ViewModelTypes.ContractEditorViewModel)]
public object ViewModel
{
set
{
DataContext = value;
}
}
As far as I know, this invokes the standard/no-parameters constructor of the corresponding ViewModel at composition-time.
So what I would like to know is how to differentiate this behavior? How can I call a specific constructor during composition time? Or how can I pass some parameters during the Import?
I really apologize if this question sounds silly, but I have only recently started to use MEF!
Thanks in advance,
Cheers,
Gianluca.
You CAN do this. Check out the Messenger implementation in MVVM-Light. You can pass a NotificationMessage(Of Integer) to send the right ID to the view model. The view model has to register for that type of message, and load it when a message is sent.
MEF Imports by default only have a parameterless constructor.