Bootstrap, MVC, Ajax, Smarty Php - php

Okay, I'm learning all about MVC, Bootstrap, Ajax and Smarty and I understand the basic principles of MVC. I am having one major issue however and I just cannot wrap my head around it, no matter how much I try and no matter how much reading I do.
At it's very core the thing I cannot seem to get my head around is how to pass variables from view to controller from controller to view.
If I want to assign a variable, I can simply $view->assign('variableName', 'variableValue') No issues there, then in the view if I want to call it, it's as simple as $variableName and it's in the view.
My issue is, I want to be able to minipulate data, for example let's say I want to have a list of items, numbers for the example, a list of 1-10, the user chooses 6, I want a way to be able to "POST" that back to the controller without actually having use POST/GET, I want to be able to essentially let it call an Ajax to send the users selection but I do not know the best way to do so.
If I was doing this without MVC, or Smarty it would be as simple as form, action post, I know that but unfortunately that isnt something I can use in this instance.
Any help you can offer would be appreciated.

I will begin with the normal workflow, e.g. without the MVC approach.
Let's say, in a certain moment you are seeing a web page in the browser and let's call it MAIN PAGE.
When you are submitting a form from main page without using ajax,
the whole page refreshes, no matter if the form action points to the
main page or to another one.
When you are submitting values using an ajax call (as part of the
main page code), then the main page will not be reloaded. E.g. an
ajax call targets ANOTHER PAGE to fetch some data in some format
(html, json, etc) and prints the data on screen, in a specified
container inside the main page.
Now, let's see what happens in a web MVC architecture.
You must understand, that an MVC application consists of only one page: index.php. This page serves as the MAIN PAGE, but ALSO as the ANOTHER PAGE, targeted when using ajax calls. The index.php page is therefore processed each time when you are sending a request to the web server - be it through manually changing the url in the address bar of the browser, through posting a html form, or through starting an ajax script.
All other components of the MVC structure (classes, template files, etc) are serving only one purpose: to build the structure of the index.php page - as main page or as ajax response page.
So, in principle, in the index.php page you'll have something like this:
Read the URL, e.g the url components: controller name, action name, action parameters (HTTP GET query string). For this you can use an instance of a Router class.
Create an object of type Request, passing and saving the url components into it. Here are read and saved the other server request variables too, e.g. HTTP POST, HTTP cookies, etc.
Create an instance of the View class.
Based on the url's controller name instantiate the corresponding Controller class, passing the Request object and the View instance to it. Here you'd give the model layer constructs (like a model factory object) as constructor parameter(s) too.
Based on the url's action name call the corresponding controller method, e.g. the controller "action". Exactly here, inside the controller action, are taking place the processing of the server request variables (saved in the Request object), the loading of the template files and their rendering, including transferring the processed server request variables into them.
In the last step, the rendered template files will be directly printed or further passed to an object of type Response, which in turn prints them.
In the end, you'll have a fully "constructed" index.php page, which will be either printed on screen by the browser (if index.php has the role of a main page) or processed by the browser as the result of an ajax request.
Note that I used the description of the steps found in the classical MVC approach. There are also other... types of this concept, best presented in Architecture more suitable for web apps than MVC?
Other very good resources:
MVC for advanced PHP developers (contains a list of great resources)
How should a model be structured in MVC?
Understanding MVC Views in PHP
Understanding MVC
MVC (Model-View-Controller) in PHP tutorial (Part I...IV)
Model-View-Confusion (Part I+II)
James Mallison - Dependency Injection and Dependency Inversion in PHP
Good luck.

Related

What's the best way to call a controller with MVC?

I'm fairly new to the MVC architecture but I'm picking it up nicely, having my own framework almost done.
Nonetheless, I'm having a 'design issue', how to call the controller?
The controller, as in the function that checks if the user hit the submit button.
Example of controller:
$class->login($_POST['username'], $_POST['password']).
I know a lot of MVC frameworks and apps call it by the URL with $_GET params, but I think it's stupid to have one method or one class for each page that needs a function like logging in.
How do you guys do it? What's your method for this?
Any help is appreciated!
You might want to look up the Front Controller concept (and inversion of control), which you are probably already using in some form, but may not know it. The Front Controller analyzes the URL and current state of things, and determines what controller to load.
In my framework I have "routes" that have attributes, one being "require login". The Front Controller determines what "route"/controller needs to be run and checks for pre-requisites for that route, like login requirement. If the user isn't logged in, then the login "route"/controller is loaded instead of the requested "route"/controller. If login is successful, then control is passed to the appropriate "route" controller.
It shouldn't be the job of each controller to manage logins, only one controller should do that, usually the front controller. Any controller should be able to be loaded under any URL since it's the front controller that determines what controller to load. The sub-controllers don't know "why" they are loading, only that they are loading to do their 1 job.
You could have a base controller which contains a function, requireAccess($access_level). Other controllers would extend this controller. requireAccess() would redirect to the login page if the correct access level is not present.
As for redirection using GET variables for clean urls in MVC, I would not recommend this. It could cause problems down the line with wanting variables that contain slashes in them. Instead we would typically want to get the original request uri, and parse it ourselves.
Typically MVC urls follow the pattern /Controller/Action/Id/etc

How PHP MVC should look like with jQuery/javascript code?

Well, I've read this tutorial if I could say: http://www.symfony-project.org/book/1_1/02-Exploring-Symfony-s-Code
And, actually, I write my code very similiary. But my question, where should I insert my jQuery code? I am sure it should be in the part of the View, but are there any good examples on how should I combine it to make "live" websites?
Edit: By saying live, I mean, for example, send POST request through Ajax and get information and similar. So, no refreshes for people.
Thank you.
jQuery as a part of javascript resources should be included in html.head or in-place, depending on what should jquery do and if the code is reusable for more views.
So it has to be part of View and you're choice is to set it up in layout or action view itself
If you need the javascript on every page then add it to your master view if not then just include it to the particular view files.
In context to codeigniter:
I extend the controller with MY_Controller and initialize a property as array which would hold the scripts that are added dynamically to the view.
eg.
var $templateData['scripts'] = array();
The controllers then pass $this->templateData to the views
And the views load the extra scripts( available as $scripts) as directed by the controllers in the head tag
This way you can even avoid loading the main jquery file when not needed.
Loading jquery.js only for the controller that need it.

Where to put PHP files for AJAX in MVC architecture?

I'm creating site using MVC architecture and get stunned when I came to AJAX. I create simple feedback form with AJAX. When user submit it there is called PHP file that inserts given values into the database using 'database' class.
Where to put that PHP file (so it would be somehow hierarchic)?
I tried to put it in /models/ajax/file.php, but it seems to me stupid and, of course, 'database' class wasn't found.
It's no different than how you do any other page of your site. That this page's output goes to an AJAX request instead of directly to a web browser is irrelevant. Its logic goes in the controller, the database code goes in the model layer, its response goes in a view.
You should call controller from AJAX request. And response will probably use different (for example JSON) view

php- new way of posting form

im designing a way the form posts its data.
e.g if we have a login.php, if the user submit we normally post it back to login.php and process it. which means if we have other pages like register.php, editprofile.php, we have to redo the process again. so normally we would do something like this in each page:
if($_POST["btnsubmit"]) {
//do smth
}
Im thinking of doing a common postForm.php which accepts all post requests, pass the data to the respective library and process it.
is this a good idea??
It is definitely a good idea! What you're describing is called a controller, from the Model View Controller pattern. I recommend checking out Symfony, which is a great MVC web framework for PHP.
A single Symfony controller (with a name like actions.class.php) can handle all of the posts and gets, plus the routing to get you there. By Symfony convention, a call to http://mywebsite.mydomain.com/home will run the executeHome function in the main controller. A form on that page could, for instance, post to /attemptLogin, and (again, by convention) Symfony would run the executeAttemptLogin function in this same controller file.

Action View Helper in Zend - Work around?

I'm working on building up an interface that I want to function as a "tabbed browsing" sort of function. Each of these tabs has already been written as an action and the tabbed interface works fine as links to the individual tabs. I decided to try writing the "index" page for this controller - putting the content of all the tabs into hidden divs and swapping between them with jQuery, but once I started to use the action view helper - I ran into a lot of people saying that its bad practice. (see this article)
Some of these actions build up forms - grab some data from the model, etc to display. I want each of the actions to continue to function on their own (some parse forms as well).
Browsing to /item should give you the tabbed menu, plus all of the div's contents in a hidden tag - where /item/tab2 is a specific action (form submit for instance).
Another complication/caveat - Some of the actions will throw Access Exceptions if the user doesn't have access to that "tab". I'd prefer not to build access checking into the system twice (thus showing a tab with empty content).
I'm just trying to figure out what the best practice is to handle this sort of thing, and I thought that the action helper might be it. If I try to use View Helpers - I start wondering if that is the right place to assemble a Zend_Form.
Does anyone have any suggestions on the "proper" way to work around not using the Zend_View_Helper_Action ?
The Correct way to work around the action view helper, as I stated in the article you cited, is to create partials which access the model directly to fetch the data they need. This can be through a view helper (you make this yourself ;)) if this would involve a lot of logic in your view.
The action view helper is plagued with more than just performance issues, but also creates horrendous debugging nightmares, and if you need it, then your application is probably not following MVC, and therefore, you are using the controller for reuse, instead of the model, which is the patterns intention.
You can render partials from within your layout or current actions view with the render or partial methods of the view object.
If you have multiple actions to deal with multiple possible posts from your tabs, then you should set all of these actions to render the same view script, which will then render all of the tabs with data direct from the model.
If you're not generating the tab/tab panes from existing markup, and you're loading the content on demand, then you simply must check whether the user has permission to access the tab before displaying the tab itself, and again when attempting to load the tab's content.
Checking whether the user has these access permissions should be an acceptable mode of operation and should not be expensive to perform.
If these actions produce content that works in some standalone page, in addition to the tabs, then the Action view helper is the corrent way to proceed. Simply perform the same ACL (or other) check performed in the action when generating the tab.
I'm not entirely sure what your exact problem is, however you can disable the layout:
$this->_helper->layout->disableLayout();
Then the requested Action will just display it's view script, which you can load into the tab.
Any authorisation code you have will function as normal and you can display the requested view script for the Action, or not depending on if they have access.
You can catch any access exceptions by using a try/catch block:
try { // action throwing exceptions } catch (Exception $e) { // catch silently }

Categories