Best practice in CakePHP for saving data, using models in component - php

I'm writing a Cake component and it seems to make sense that I use it for saving data rather than doing so in a controller. In the manual it says using models in a component is discouraged, but the other way of doing it would mean I'd be repeating code in the controller.
The component basically analyses a load of data from various sources and will then insert data for various models.

If the component analyses a load of data from various sources, it can probably be written as a behaviour.
If not, and you have no other choice but to use a model in your component, be sure to do it properly:
$this->ModelName = ClassRegistry::init('ModelName');
I personally don't see a problem with this, since the core components (such as the Acl component) do that. As long as your component handles the application logic and models handle data, you'll be just fine.

In my opinion, DRY is the critical path. To that end, I see two options:
Instead of saving the data in the component, return it to the controller in a raw form that can be saved from the controller.
Go ahead and import the model into the component and do what you need to do. It's not encouraged, but they do make it reasonably easy.
If it comes down to a hard choice, I'd err on the side of keeping my application DRY rather than maintaining a strict MVC discipline.

One could argue that if you want to write data generated in a component and have the ability to package the component up for distribution it would make sense to load a model in your component(especially if the model is part of your component).
For example I have a authorize.net AIM (credit card authorization) component.
From my controller I call the components charge function.
Authorize.net sends me a response (within the component) and according to DRY I would want to save the data within the component so I don't have to repeat saving the data from wherever the charge function is called.
Another plus to straying away from convention would be the fact that I could use a model from within the component and not have to have a model in the app.
What do you think?

With the versions of Cake I am familiar with (1.3, 2.0), you can requestAction from another controller. This apparently is also bad practice, but they provide the function for obvious reasons. I have used this in some situations but I have had sketchy results when trying to pass data back and forth. I would avoid using this method as well except for simple functions.

Related

Correct way of implementing a service layer in CodeIgniter applications

Below are two ways a service layer can be implemented in an CodeIgniter application.
1st method
1.send request to the controller
2.calling service layer methods from controller
3.return processed result data set(D1) from service layer to controller
4.then according to that data set controller demand data from model
5.model return data set(D2) to the controller
6.then controller send second data set(D2) to view.
2nd method
1.send request to the controller
2.calling service layer methods from controller
3.service layer demand data from model
4.model send requested data set(d1) to the service layer
5.after some processing return generated data(d2) to controller from service layer
6.then controller send data set(d2) to view.
What is the correct way of implementing a service layer in CodeIgniter? Other than these two methods, are there any other good ways?
if you can provide an example in Code it will be great
Please note, this is not necessarily the correct way of doing it, but I'm going to explain how a framework like might typically do it and then you can learn about other methods and decide the best one for your use-case. Therefore, I do not expect this answer to be the correct one, but I hope it imparts at least a little knowledge on how things are done before someone who actually knows what they're talking about comes along and chimes in (also to those people - please feel free to edit / downvote this answer :D). Finally this also has nothing to do with CodeIgniter but frameworks in general. Your question should not only be framed as framework-agnostic, but language-agnostic also.
So I'm going to offer an opinion here and that is of the fact that all modern frameworks, specifically in PHP, do not do MVC. Why is this important? Because we all need to be speaking the same language, and 'mvc' does not exist in PHP. That's a fact. Accept that and then we can move forward onto the bastardization of the concept that frameworks use; and CodeIgnitor is a particularly great example of 'MVC' bastardization; henceforth known as "mvc" with quotes.
The plus side is that frameworks like Symfony, for example, provide an initial opinionated architecture that at least contains some form of consistency across the application, and it goes something like this:
A standard HTTP request comes in and hits the front-controller, typically app.php or app_dev.php depending on whether or not you are in development or production; one involves a lot of caching that needs to be run on each change and the other doesn't - which is perfect for development.
A router matches the current url to a controller class and an 'action' (method) within that class.
The dependency injection part of the framework figures out what objects are needed for everything from the controller forward into the model layer and back, and either instantiates or prepares to instantiate them when needed.
The controller is instantiated with any required dependencies and the relevant method is executed. This is typically where you would start your development and 'hook your code in' to the framework.
This is where you decide on your architecture, however, the most important thing from both a developer perspective and business perspective (for lower costs for future maintenance) is consistency.
I personally prefer to ensure my code is decoupled from the framework. I pass in scalars taken from the request into an application-layer service, which uses objects from the model layer (passed-in via DI) to use domain objects. The point here is that domain objects are not directly passed into the controller, they are proxied through an application-layer medium, so you can theoretically replace the entire framework surrounding this and still, all you need to do is pass those scalars into this layer before they hit the model layer and it'll all still work (think CLI calls, no more controllers).
The application-level service uses any required Repositories, Services etc (and passes those scalars into them, remember the separation?), which perform business logic, (typically these are where your design patterns come into play on a day-to-day basis), and then return that data to the application-level service.
The service then returns the data to the controller and guess what? This is where frameworks tend to fuck up! Because there is no concept of a "View" in today's frameworks. There is only a template, and you pass that data to a template and bam that's it. So in your diagram, there is absolutely no concept of a view because that's not how things are done. And to be entirely honest, I'm still using templates because they're the fastest way of doing things, but until modern frameworks get their shit together and actually start using Views, we're out of luck and have to remain steadfast when confronting the fact that some (like Laravel) refer to themselves as "mvc" frameworks.
Note, Fabien Potencier explicitly states that Symfony was not an MVC framework - at least he knows what he's talking about there. Again, this is not purist, it's important we're all speaking the same, factually correct language in computing.
So, because you like diagrams so much, here's how some might do it with today's frameworks...
This is for an application that has the concept of a Review and Criteria for each Review. And don't even get me started on Symfony forms, they're so coupled to everything they're not a serious part of any architecture.
How many effing layers do you need? We already have "MVC", in DDD we have the concept of "Application", "Domain" and "Infrastructure" seperation, so get those two working together first, then this "service layer"? Do you really need another layer, or is the above enough? Things to think about...
See, you're not stuck with the framework / http request to get the application going as a result of this separation.
See the "services" in the above diagram? They're separated from the controller so you can throw scalars from anywhere and the application will still work. I think this will give you the separation you need. It's great to do things the right way, learn how to do it, and then learn how to control yourself and be pragmatic about it when it comes to the business and it's needs, but frameworks need to sort their stuff out - and you certainly wont be writing lovely code with CodeIgniter ;)
Dependency Injection and the Adapter pattern would be a good place to start.
CodeIgniter support's neither out of the box, so you would need to write a wrapper or maybe a hook.
Your view could only support xml|html as json would need to be pre-rendered to a .json file and then returned as output but this would need to be done via code, it's easier just to return the object in that case and altered on the frontend. PHP is an embedded language which works with (xml|html)
A service model works best when it is injected(dependency injection)
into a controller/model and is listed as a property of that controller/model.
The service is then bound to an interface
For example facebook/twitter
They both have a request and response function but both follow similar patterns, yet have different endpoints.
interface SocialMediaAdapter{
public request(url);
public response();
}
public class FaceBookProvider implements SocialMediaAdapter
{
public request(url){
}
public response(){
}
}
public class TwitterProvider implements SocialMediaAdapter
{
public request(url){
}
public response(){
}
}
public class SocialMediaServiceProvider{
protected $provider = null;
public function constructor(SocialMediaAdapter $provider){
$this->provider = $provider;
}
public function fetch($url){
return $this->provider->request($url);
}
}
Dependency Injection required here
new MyController( new SocialMediaServiceProvider ( new FacebookService ) )
IMHO there is no right or wrong here:
option #1 -
If you want to re-use the service layer in multiple controllers / actions
and feed it data from different models based on the request it makes sense to go for the first one.
option 2# - However the first option could be problematic if your data model is more complicated. What if a second call to the model is needed based on the data of a first call? Using the controller for this business logic defies the whole purpose of the service layer. In this case it might be better to go for the second one.
I think the second one is the more common one.
You should use first one. Because in MVC web application, controller is used to separate your business logic from view, it's something like a gateway. You need to start processing your info using controller, from controller you should call model or service layer or anything you need & finally you should return back data to any other source from here. Your view or service layer should not directly access model.

Is it possible to separate Controller and View in RESTful Symfony app?

I am thinking about using Symfony to create a RESTful api. I want my app to only accept json and/or xml and just output either. I want my frontend to be completely separate in a separate directory.
Disclaimer: I know most frameworks only claim to be MVC, and that the definition/principles of MVC vary from developer to developer. Therefore, I've laid out my understanding of MVC.
How I picture MVC (taken from Martin Fowler):
Make a strong separation between presentation (view & controller) and domain (model)
Controller and view should (mostly) not communicate directly but through the model.
Have views (and controllers) observe the model to allow multiple widgets to update without needed to communicate directly - Observer Synchronization.
In Symfony, the Controller returns a Response, and there really isn't a View class. They sort of combined the two.
My questions are:
Is it possible to separate the controller into a controller and view?
Can you make the controller not return something?
Possible to not have any html/templates within the app/bundle?
As I stated earlier, I want to keep frontend completely separate, therefore, I wouldn't use twig. I would use JS, SASS, React, etc. for my frontend stuff to make ajax calls to my Symfony api.
What you are trying to do is a pretty standard architecture.
You do not need to use templates but your controllers have to return "something". If you are handling the view in the front-end, this would be just the data needed to create this view, usually in the form of json
Symfony can do this, no problem

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.

Implementing OOP PHP with AJAX, MVC?

I'm new to the OOP paradigm (and AJAX/jQuery), but would like to create a basic site employing MVC architecture, in PHP, with AJAX functionality. I drew up a brief diagram of how I currently 'understand' the architecture.
Presumably when AJAX is used, that acts as the controller to interact with the model directly to retrieve whatever functionality is needed? The filenames I added are just to give you an idea of what I 'think' should be included. e.g. index.php would be a html/css template with includes to modules in the relevant places (whatever they may be) - news.php, navigation.php, etc. database.php/pager.php might house the classes and extended classes that I create for pagination, or connecting/querying the database I'm struggling to see what the controller component could be - it'd surely end up being a 'second back-end view' - calling the classes from the model to be sent to the view?
I've probably portayed my confusion well here - what should go in the view, controller and model... is AJAX functionality technically another controller? Any diagram similar to my one above would be extremely helpful.
OK so AJAX is a transport method and not a piece of application like a model or controller.
Your client will communicate through AJAX with one or more Controllers.
These Controllers use or invoke Models to handle different kind of tasks.
Then either the controller or the model responds to the request either with a message in a transport-friendly format (JSON, YAML, XML) or with a View (piece of HTML).
The controller handles requests, that means it receives the initial client-input. Depending on the situation this input has to be formatted, normalized, mutated or transformed somehow before being used in your application.
Then a controller uses or invokes a model; this means that it either deals with business logic itself (old style) and makes use of the model to access datasources or it hands the main workflow of your application completely over to the model (new style).
A model in first instance abstracts a persistent storage entity (like a database). In contemporary application design it also does the main business logic of your application.
There's one way to see this.
Ajax is the medium for sending data between MVC components like HTTP POST. In this respect it does not show up in the MVC pattern.
The actual display in JSON format can also be seen as a view if it's actually used to show data.
From this you should be able to come to your own conclusions.
You can use PHP's best MVC architecture called "YII".Get more info from here
http://www.yiiframework.com/

Zend_Framework- Where to Place $_GET and $_POST (HTTP Request) handling?

I recently read this post which led to a series of other posts that all seem to suggest the same idea: Models do everything, the View should be able to communicate directly with the model and vice versa all while the Controller stays out of the way. However, all of the examples shown are fairly simplistic and none really show an example of how anyone has tried to implement full handling of of a request / response cycle, which got me to wondering "should the model be responsible for handling the request (ie $_GET, $_POST, etc) itself?" and "should the controller only operate as a pass-through to instantiate the necessary model(s) and pass the model(s) to the view?". (In fact I found one example taken the extreme of embedding a Zend_Form object in the model)
From my reading of what Fowler says about MVC and just controller's in general it seems at first glance that the thinner the controller layer the better. But then I took the time to back through and study what he says about both MVC and Front Controller (which just muddies the waters because both patterns define controllers) and now my instincts suggest that Zend_Framework in implementing both of these patterns, has actually created a composite object that performs the functions of a Controller in MVC and those of a Command object in Front Controller (or some such).
So I'm wondering what the general opinions would be of others who have implemented similar patterns in their apps - do you handle the request entirely within the controller layer or do you make the model aware of the request and handle parameters directly within the model?
My first thought is to avoid handling any sort of request in the model. That is the job of the controller. Here is why: suppose you have a model that does handle your requests (GET or POST). That structure will likely work well initially. Now, suppose you want to add some sort of AJAX functionality or put up a service interface to your system. Now that you accept more than simple GET/POST, i.e. JSON or XML, your model will have to distinguish between each request type and know how to parse them. I believe that destroys a lot of simplicity and clarity of the model code. I agree that the controller layer should be thin, but it should also have a role and an expertise. For me a controllers expertise is to:
Handle incoming requests
Delivery data to the model
Request/accept data from the model
Pass the data's model to the view
I vacillate on how much the view should know about the model. Some people recommend the model go straight into the view, but I think that is fragile coupling. It frequently leads to logic in the view. Also, if you are working on a project where the team members working on the view are not as programming savvy as the main developers it puts a large burden on them to keep up with changes. I tend to package the data I hand to my views in a neutral structure instead of handing over the full models.
My interpretation of MVC is mostly pragmatic. The model's job is to model the domain you are working on and should not care where the data comes from. I frequently structure model code with the assumption that it could be used outside of the web application in perhaps a command line application or a desktop application. That sort of union rarely happens, but it leads to clear purpose of each layer. The controllers job is to move data between involved parties, be they client requests, the models, or the view. The controller should have very little domain logic, but that doesn't mean it doesn't have any code. Finally, the view should just look pretty. Hope that helps.
handling the user instructions/input (like HTTP requests) is the job of the controller. model is for working/manipulating/fetching the data and view is for showing the results to user. this means that connection between the view and the model is duty of a controller most of times.

Categories