How can I populate Zend_Layout variables with backend data? - php

When trying to adhere to established best practices like avoiding singletons, registry, static properties and base controllers, how I can populate my layout(and partials used by the layout) with data that is only used by the layout and common across all actions?
The typical scenario is menu which is built on variable data, like an database. Keeping separation of concerns in mind, the views/layout should never talk to an backend directly, but rather be told what to contain.
Using a front controller plugin is simply not possible without using the singleton "feature" in Zend_Layout. The plugin only knows the request and response object, neither has access to controllers, views or the layout.
Zend's action helpers have init/preDispatch/postDispatch methods. One can add action helpers to the HelperBroker (ex. using the bootstrap) and these will be executed in the normal application flow.
Using the init-method to inject data into the view is not possible since it's trigged before the controller/view is ready. preDispatch/postDispatch is possible, but not perfect, since these methods are always triggered when executing a controller action.
That means that all uses of the Zend_Controller_Action::_forward() will also execute the preDispatch/postDispatch in all action helpers. This doesn't have any big implications for the code except speed, I really do not want to be setting a view (or an view helper) variable several times. One can code around this issue using some sort of $firstRun variable, but I really don't want to track this in my own code.
Another method is doing this in the bootstrap, but in my opinion it really does not belong there.
So, how can I populate my layout/view helper with data from the database, doing it only once and still keep a good separation of concerns?

I've followed the ActionHelper approach, setting the view variables on the preDispatch method. It was the most logical place, in my opinion. In addition, my projects weren't using Zend_Controller_Action::_forward(), so I didn't have any speed concerns about multiple triggering of the helper.
Hope that helps,

You could go with Action Helpers as stated in this answer (take a look at the question too, its pretty much similar to yours)

I'd use action helpers too. Just fill the view variables and display them using plain PHP/partials/render/viewHelper (depending on complexity).
Your problem with multiple runs using preDispatch could be solved using
if (!($this->view->myVar)) { // or array_key_exist or isset - depending on your use case
$this->view->myVar = $someModel->getSomeData();
}
Which is just fine IMO.

Related

Calling methods from inside views in an MVC framework

This is a general question and I'm asking for design patterns, approach, or what terms to even properly search for to determine the best approach. More specifically, I am working on a project in Laravel 4.2, with standard blade file views with a master.blade.php, a header, footer etc.., and they just get built with the View::make('location.of.template', ..) method, passing the parameters as needed.
The views have very little "logic" in them and just present the collection of data provided. I somewhere recall that a model should not know what a view does with the data provided, it was up to the view to manage this presentation.
But what is the rule for using calls to methods inside the view? This seems extremely useful to me and gives the view authority to call an HTML string based on a single element's $id, and relieves the view of having to prepare every possible scenario for the view's sake. This seems very useful for a page that is 100% server-side, and even better if the methods the view would call are also available as APIs using AJAX secondary calls. Is there a generally accepted guideline on when and what type of methods to use in views?

Attaching data from controllers to views in PHP frameworks, standardization

most of the modern PHP frameworks use data attaching method, for example:
View->render('login', $errors); // or
View::make('login')->with(array('errors'=>$errors);
I'm trying to establish a convention, where even if the View designers and the Controller developers do not have a direct communication, they can expect what data to put, and what data to receive,
I have thought of two methods, first using a class that takes care of rendering the views including the data, and this class would contain all types of data which will be used among the platform, second method is to have a naming convention to follow, I personally find the first method better, but I have to note that I'm not a skilled developer, I'm not sure what implications can that method have, which method would you choose?
perhaps another method?
For direct view rendering, you can use View::composer method.
View composers are callbacks or class methods that are called when a view is created. If you have data that you want bound to a given view each time that view is created throughout your application, a view composer can organize that code into a single location.
It is about auto rendering.
You communication convention with designers should be easily done through Separation of concerns pattern.
Blade templating syntax is ideal for that, since it separates logic out of your view. By logic, I mean all data that comes from you domain layer (model,db...).
Using {{$data}} syntax is pretty straightforward and easy to understand to designers.

PHP Form Processing - Distributed or Centralised?

I've searched around but there doesn't seem to be a clear consensus on which one is better. Currently, all the HTML forms on the site point to a single PHP file. Each form has a hidden input specifying the action (e.g. 'user-login', 'user-logout'), and the PHP file calls methods from that.
So my question is: Should I point each form back to itself, related forms to a single file or all forms to a single file? And in terms of MVC, should processing take place in the controller or form?
Should I point each form back to itself, related forms to a single file or all forms to a single file?
You should point everything to index.php, which then delegates other components (controllers in MVC terms) to take care of the processing. The controller will then decide which view it wants to render. index.php would be in this case something we call the front controller. (note: below I am recommending ZF1 as a learning platform. ZF1 has a "front controller" class. Some people may argue that THAT one is the front controller and index.php is what they call the entry script. In my opinion, that is only the second "front" controller. Nevertheless, both opinions are controversed, so make your own opinion).
And in terms of MVC, should processing take place in the controller or form?
In terms of OOP first and foremost: the object is the only one who knows how to validate its own data (the principle of self-containment), so the form should validate itself. If it's about a model, the model should be called by either the controller, or the form - it's a matter of taste. No matter which way, the same principle applies: you feed the Model with data and call its validation method.
As you may have noticed, the Form class is a Model.
Don't let yourself fooled by the hype called MVC. Respect the OOP principles above all.
Regarding MVC: the MVC pattern says: the controller only coordonates the other components, for instance it takes the input, creates a Form instance, and calls the Form's validation method.
I advise you to use a framework to better see how all these pieces work together. The best would be zend framework 1, which has little to do with real life requirements, BUT which is a masterpiece in terms of patterns and practices.
Maybe ZF2 will change that mistake with the extra front controller.
Looking at the other answers, I feel the need to clarify some terminology used in my answer:
Model is a model. There's plenty of documentation about MVC
Form is a subclass of Model. It takes care of the validation. It may also have a method Form::__toString() which renders the HTML form in the view (the V in MVC)
view is the html file, and it's rendered under the supervision of the controller (C in MVC)
To recap, the overall execution flow would look like this:
<form action ...
entry script (a front controller)
router (it decides which Controller to forward the request to)
the Controller coordinates all the actions, calling the Model::validate() of one or many models (including Form, which is also a Model)
in the end, the Controller choses to render() a view (a html file), which could contain a call to Form::__toString(), in which case the Form is a hybrid of Model and "renderer".
Fun
Profit
That's it, basically. Different frameworks have different data/execution flow. ZF1's looks like this for instance: http://www.slideshare.net/polleywong/zend-framework-dispatch-workflow
In MVC terms your processing should take place in the controller. You shouldn't have any processing logic in your form (the view). Whether you have a different controller for each form is up to you. You could, for example, have a single controller that accepts all form submissions and performs some common processing (such as csrf detection) and then invokes your other controllers for each form. Alternatively, you could have a single controller that loads validation requirements from a database and behaves differently depending on which form has been submitted.
In MVC terms, making all form point to a single script means you've got a Front-Controller for Forms. There is one controller that deals with form requests.
Should I point each form back to itself, related forms to a single file or all forms to a single file?
That depends on your needs and the design maybe even architecture of your site.
And in terms of MVC, should processing take place in the controller or form?
Processing in MVC normally takes place within the controllers (lightly only) and the models (heavy processing). So if you're looking for an exemplary MVC design implementation you most probably will have Form Models that are used by the Controller(s).
This will ensure that you can make use of forms more flexible and you don't duplicate code for form processing within your application.
In my opinion you should use one file for each purpose. Same as mvc structure, this is a good approach for programming and it will be helpfull when your code gets really complicated.
You question closely relates to the Front Controller Pattern. In my opinion you lose nothing with pointing verything to a certain script, but win the flexibility do execute certain actions without having to repeat (and probably foget at some place) those actions.
So I would recommend to point all forms to one script.
Btw. it is the controller who handles the form processing in terms of web MVC.
Following on from my comment on Flavius' answer.....
The object encapsulating the form should be used for both presenting the form to the user and retrieving data sent back from the user. Using 2 different codesets to operate on the same dataset undermines the principle of encapsulation. Consider if your login form has a name and a password field. If you decide you want to process a sha1 hash of the password in place of the original value, you may have to modify 2 bits of code in 2 different places!
This does not mean that both instances of the form object need to be implemented within the same URL path; consider PHP's 'require' and auto_include constructs.
Where multiple input sets are multiplexed via the same URL path, this is referred to as a Front Controller pattern.
There are benefits and issues with Front Controller vs the more distributed approach.
Front Controller:
allows common processing to be implemented in one place only (e.g. authorization, logging)
moves structure of the application away from filesystem layout and into code, therefore control over application structure implemented within code
simplifies handling of bookmarks
Non Front Controller:
much easier to support
application structure evident from webserver logs
more robust - since breaking one script deos not break whole site
better performance - no need to load huge amounts of redundant code / deferred loading of processing target

Beginner CodeIgniter concepts - Reusable view code, where to go? (Helper?)

I am a beginner with CodeIgniter still struggling to get a complete grasp on how to use the MVC ideology most cleanly.
I am writing a basic CMS system with the ability to vote on entries and follow people etc, consequently, I have found myself using the same or similar pieces of code across multiple views here and there consisting of various pieces of html and logic such as:
Voting panel
Follow/Unfollow panel
Login/Logout panel
Code to check if a user is logged in etc...
I am wondering where to put this code so it can be unified? I am thinking a helper is the way to go? If I declare the helper in the controller, it can be called from the corresponding view right?
Some of the elements are dynamic - such as a follow/unfollow button - It would need to check if you are already following the user or not and display the appropriate button, which would require a model to check. What I have now is that all the logic is in the controller and it returns an appropriate button, but it seems weird to be returning formed html code in a controller return as well. Should it be more like:
controller checks if you are following someone
the controller passes a boolean to the view
the view calls the helper with this value to draw the appropriate button
Also, as a secondary question, I have been doing a fair bit of looping through mysql arrays in foreach loops to process mysql results returned from the view. It seems like my views are getting somewhat complicated, but I can't think of another way to do it, although perhaps this should be done in another helper as well?
Apologies if this is a naive or repetitive question, there is indeed a lot of discussion surrounding this subject but it is not always easily relatable to another project.
Helpers are certainly one way to modularize anything that isn't DRY. Another is to use Partial Views. CodeIgniter looks like it supports partial views. Here's a good breakdown - not PHP specific but the discussion should be agnostic.
As far as handling user logins is concerned, you will probably want to use a static class and the singleton design pattern, which will allow you to check to see if a particular user is logged in or not anywhere in your application. There is a good tutorial here
http://www.phpandstuff.com/articles/codeigniter-doctrine-scratch-day-4-user-login
Loading the helper, I don't believe loading it in your controller will automatically load it in your view. I think you have to re load the helper in your view file, or you have to autoload the helper. (cant remember off top of head but Im pretty sure).
Regarding looping through the mysql results, you should be using a model for this, always. Any functions which are grabbing or sorting information from your applicaiton, should be done within the model. Then, in your view file you loop through the results and format the data how you choose to.
When developing http://newspapair.com which has the vote functionality you mentioned I used helpers and custom classes to spread the functionality across multiple views.
Helper - has functions without a class. So a standalone function or group of functions can be placed in a file and saved as a helper.
For instance I used a helper with generic form processing functions for NewsPapair, instead of a static class. But this is not the "best practices" thing to do. I did it this way because I already had the functions from a previous project.
As far a looping through MySQL results, try to write a query that allows the DB Server to do the heavy lifting. This will make your code more efficient. Perhaps ask a question about a specific query with example code. Plus do all of the data gathering in your Model.

Way to bypass the controller in CodeIgniter?

I've been using the CodeIgniter framework for PHP and am enjoying it, but I notice that it seems to require a controller for every view. I'm wondering if there is a way to call a specific model from the view itself, rather than route through a controller. I understand that use of a controller is best practice in most cases, especially where the data from the model needs to be modified in some way, but I have cases where I just need to do a strict data pull to the view (which is loaded via ajax), and setting up a controller for that seems superfluous.
Any thoughts? Thanks in advance!
You're fundamentally misunderstanding MVC, at least as implemented in CI.
All URLs on your site (at least those that utilize the CI framework) are mapped to functions (methods) within controllers.
http://myCIsite.com/controller/method[/var1][/var2]...
It doesn't matter whether the URL is accessed via regular HTTP or via AJAX. This is always a one to one mapping. Because of this, you should think of the controller/method combination as the "web page". Do not think of the view as the web page.
Models and views are subordinate to controllers. The controller delegates specific responsibilities to them - database interaction for models, and page output to views.
Because models and views only serve to perform delegated responsibilities, their use is not required in any given controller/method. Help pages, for example, generally have no need to interact with a database, so there is no model utilized by the controller/method combination that serves a given help page. Likewise, form handlers frequently redirect to another page upon completion of processing. As such, there is no view corresponding to the form handler (but there is (likely) a view called from the controller/method in the redirected to page).
Furthermore, models and views do not necessarily correspond on a one to one basis with individual controllers/methods. Any given model can be loaded and used from within several controllers. Similarly, a controller could have a single monolithic view that is used by all methods, or each method could be assigned its own view. (Or, as I just said, a given controller/method could utilize no view at all.)
Finally, CI does not enforce strict MVC separation. You can interact with the database and echo HTML all from within the controller and CI will not complain. Nevertheless, this separation and delegation of responsibility is followed because logically separating the responsibilities makes the code easier to read and helps you follow the DRY principle in your coding.
The fundamental Understanding is that the "web page" corresponds to the controller/method. The view and model, when used, handle delegated responsibilities for the controller/method.
I'm wondering if there is a way to
call a specific model from the view
itself, rather than route through a
controller.
That's not possible as of what I know, the main abstract class of the CI controller imposes restriction to use a controller otherwise you will get a fatal error.
And actually what you say will break the best practice of MVC design pattern. You got to go to model through a controller not view.
I'm a bit confused as to exactly what you're trying to achieve. The controller's value, aside from just being a clean way to handle incoming requests, is to manage the interaction between the models and the views and to determine which views to load. It's also entirely reasonable to load model data directly from your views, but how did you get to your view in the first place?
I guess I'm just having a hard time seeing the context here..
To run a query via Ajax you still need to provide a URL / path in the javascript call. You can not get around the fact that a controller function has to "catch" this call; you can not map a url directly to a model. All you need is 3-4 lines of code in your controller.
Via URI routing you can map a URL to a different controller, so you don't "require a controller for every view". I always create a controller called "ajax" to handle those requests.
A basic ajax call with jquery can be something like this
$('#prod_img').load( "http://domain.com/ajax/get_img", {'color': 'blue', 'url_title': 'bla' } )
You can echo stuff in your controller, so rather than trying to bypass the controller you should be looking into how to do away with the views. This will actually be easy, you can load the db class in the controller just as you can in a model.
But if you really don't want to use MVC perhaps Codeigniter is not the framework for you.
You should read more into the principles of MVC.
Views are strictly for presentation of data, the model shouldn't communicate with views directly.
But still if that's what you want then just pass $this->db from the controller to the view and use it in the view.
Then again, this is NOT a good practice.

Categories