Multiple action.class.php - php

I do have an module e.g. account. Of course you will find a file called in acount/actions/action.class.php.
The PHP-file action.class.php is getting big. Is it possible to extend it?
for an example:
/account/action/action.class.php
/account/action/action2.class.php
If it is possible, how does the code look like in action.class.php and in action2.class.php? And/or where should I enter something in a config-ymal-file?
Thanks in advance!
Craphunter

Symfony actions can be declare in two flavors:
A big actios.class.php file that inherit from sfActions
Multiple xxxAction.class.php file that inherit from sfAction
The are both basically the same but these cant be mixed (you must decide if you want 123123 files, 1 per action, or one big fat file).
Here its the symfony reference on this matters: Symfony Front Controller - Actions check the Action section.

It sounds like the action class is getting too big because you have too much stuff in it. I would suggest breaking it into multiple modules or moving relevant parts of the logic code into your models.
Adding an include for an action2 file is not how Symfony 1.4 is intended to be used and will likely just lead to all kinds of other headache.

PHP doesn't support 'partial classes' like C#. So you have two options:
Create an inheritance chain, by creating a baseActions class which inherits from sfAction. Then create your MainActions class which inherits from baseActions. You can add different layers of inheritance.
Group functions in seperate classes. Override the execute() function in your actions file, and manually call the function on the class you need.

Also consider if some of the behavior you're implementing in the action (controller) belongs to the model (or the view) instead. If the really belongs to the action just follow guiman's advice and create an action per class inheriting sfAction.
If I have a CRUD module based on a model (as generated by the CLI), and I have to define additional behaviors for that model, I tend to create another module to contain that behaviours. E.g., considering a model Article. I could create an article module for the CRUD behaviors (generated), article_support for additional behaviors like moderation, activation, etc. and perhaps article_ajax for async requests.

Related

Symfony2 when should I create a new controller?

I'm currently using Symfony2 and and I'm trying to divide my code into different controller (like an Ajax Controller, a User Controller etc...) but I don't really know when I should use a create a new One.
For example my DefaultController is starting to be quite big (~800 lines) and I was wondering if having a too long controller could impact the website's performance? (Longer loading time...)
And, if it does, when should I split the controller into smaller ones ?
I would say that you should group your actions by which operate on the same data (entities) or operate within a well defined responsibility. E.g. UserController for users, PostController for blog posts, etc. This means that if you want to create an action which role is different than the rest of the actions, put it in a separate controller.
Symfony is caching almost everything so I don't think that huge controllers would cause an impact to the perfomance but if you have a thousands lines long controller, I'm not sure that it does only one thing.
The controller's size can be a warning sign too for the misplaced queries and business logic. You should separate QueryBuilder calls into Repository classes and other logic to services and event handlers. You can save more lines by using annotations instead of PHP code.
I think it's a good idea to start with a controller for each relevant model, with a CRUD structure.
Of course it depends on your needs, but if you have a model "Post", you probably will need a PostController with CRUD routes and methods, like : index (/posts), new, update, create, delete...
Depending what you need you can delete or add some method relative to a
Post from this base structure.
Try to detect what is realy relative to a specific model in your defaultController and create a controller for it.
Good luck.
What #riska and #Yoann said all holds true.
In addition, I prefer not to create separate controller if I'm sure that it hold only that one method. In that case, I just put it into DefaultController.
From my experience, controllers are the part of UI layer. If you care a lot about keeping your controllers small, let me give you the best scenario you can make what a controller must do:
1.Call the appropriate service
2.Return the response
That is 2 lines of code for each controller action, or you can even make it in one line.
Like person above said, controllers are usually separated by what type of entities / services they operate on. If you for example have an entity - lets say User, the following actions are most likely to be in there: createAction, editAction, removeAction, registerAction, activateAction, loginAction, logoutAction and so on...
It does not have any impact on performance if your controllers are thin or fat. The code will be executed in the similar flow, and all classes are being cached in the production environment.

In Symfony2, what folder do I save a multi entity class in?

I am new to Symfony2 and I am not sure where I should save a class that updated multiple tables(entities).
From reading documentation and tutorials it says I should not put any other tables reference within the entity class; I could put it within the controller class, but again many people have said this class should be as simple as possible and not include business logic; Not in repositories, because these are used for query data and not for update or inserting.
Is there a standard folder structure where another type of class for working with multiple entities(tables) should be saved? Should the business logic really be stored in the controller classes?
Symfony2 is very flexible in this regard.
You're right, entities are for one "table" only.
I would suggest you look into Services, as they are a good way to move your code from a controller to a separate class. You basically call your service and use the functions it provides. This will slim your controller down.

mvc design question

I am using Zend framework and doctrine in this app
In my web application i have various individual modules like events, conferences, case studies.. so i am making controller design at this moment. In the below image regulatory document is the controller and its sub are its actions. So regulatory doc, videos, podcasts all are having almost the same kind of functionality. so is this design appropriate...?
In mvc for each action i will be having a separate view. And on user type i may have to put access levels on this modules. so i have kept separate controller so that i can easily control the module for each user type. But this is resulting in duplicate code.
Now i am thinking to make one parent class and in that i will have all the common methods. eg. I will have common class Resources and in that i will keep list, search, suggest, addFavorite etc. And that will be the parent to the above given controllers.
So than how will i manage my view for all these different modules if i go with this approach..? if i go with this than my code will be bit messy..?
I would suggest to keep all the controllers to have nice URLs and clear structure in the modules, however keep the controllers thin. Put your domain logic into Services or Entities, hence no (or just less) code duplication is required.
More in:
Is MVC + Service Layer common in zend or PHP?
How to implement service layer in Zend Framework?
From DDD:
http://domaindrivendesign.org/node/118
controllers belong to application layer / domain logic belongs to domain layer
If I understand you correctly you have a set of common behaviors among your regulatory documents, videos and podcasts.
In this case you should probably try to abstract the commonalities out into a parent class from which these three areas inherit.
As an example, I have my own MVC framework where I define a superclass tnh_controller from which my other controllers (eg: venue_controller, group_controller) inherit. In the parent controller I define the header() and footer() and delete() methods. I can then use those unchanged in the child classes and save myself some effort.
You can likewise do some of the common work for your models (CRUD) in a model superclass, only overriding it as needed. Most of the logic for different models comes from class variables (table names, column names, etc).
I wouldn't worry too much about being "strict" MVC. Instead try to work out what will save you time and keep your code organized. It sounds like you're on the right track putting similar behaviors at a parent level.
You can still have a separate controller to contain suggest, addFavorite actions without having to make it the parent class for all the controllers. Basically the UI elements related to these you can render as partial views and call on to the actions in the relevant controller. That way you can get rid of the problem with the views.
MVC designing means that for each view, you have a controller and a model. However, the models don't need to be classes at all, nor having a different model for each MVC. Usually you will share a model between some MVCs, or your model might just be an integer value which you define in the own controller. Usually, you might even want to share data between them, then you will have a singleton mode:
http://www.galloway.me.uk/tutorials/singleton-classes/

How to merge few ACLs in Zend Framework?

I have few instances of Zend_Acl objects, like this one (one for each module):
class My_Acl_Module1 extends My_Base_Acl
{
public function __construct()
{
parent::__construct();
$this->addResource('News_Model_Entry');
$this->deny('guest', 'News_Model_Entry', 'index', new News_Model_Acl_Assert_CategoryPrivate());
}
}
class My_Base_Acl extends Zend_Acl
{
public function __construct()
{
$this->addRole('guest');
}
}
How to merge them into one ACL object to use in navigation container?
Edit
Some more info:
I don't use controller resources in favor of model based resources (models, forms implement Zend_Acl_Resource_Interface). All of them have method isAllowed()
I use modular directory and reusable modules (separate models, configs, routes etc.)
My application knows all installed modules, controllers, action (structure already parsed, not in real time)
So I'm looking the way to follow this scheme, and separate the ACL for each module. I don't want to use application resource, because it is a waste - acl is not needed always.
I have an action helper which instantiates module specific ACL only when it is really needed. But sometimes I'd like to have global application ACL available too (eg. when I'd like to pass it to the navigation view helper or controller plugin).
My module ACL classes have all just one method: init().
Dirty solution I see, is to parse the source classes and merge the files into one method for new class.
Any suggestions?
I think this is almost impossible without the application knowing a bit more about itself. I had a similiar problem a while ago too and didn't find any satisfying solution. When merging you'll loose some information (the module) which you need later on in your navigation.
The first solution I had back there, was to iterate over all acl-files in each module and create a custom ACL-merge function to merge them all. This actually did work but I didn't like the idea of a file-scan over my complete application (even if the results were cached).
My last approach was to add more data to my application: For every linkable action I defined the corresponding acl-file. This wasn't as much work as it may sound. Mainly because my controllers/models do match almost exactly. So I have a model 'News' and a controller 'News' which handles the access to it and maps every action of the model to the frontend. So I only had to specify the acl/controller relations. (I used a custom element in each navigation container to save this).

What could I do to improve my MVC?

I'm thinking of re-working my MVC before I get to far along with it. At the moment it uses a sinle controller which takes the user input and determines the model. The model has maby differ methods which I call actions, because one is called automatically. The model loads its view file, which again holds many different methods. The model can set properties which can be used in the view. Then the controller calls th template classwhich parses the output for display.
Is this the bst way to do it?
Or should each different part (news, contact, about) have its own controller, which loads a specific model and view. Essentially, instead of grouping methods into a single file, it uses multipe files.
I'm kind of lost as to how I should do it.
Cheers
Start using a MVC that works and is well-known like in Symfony or Cake. From that you will decide:
what do to in your own, knowing the best practices;
to drop your own if you feel like you can save time by using theses.
If you are thinking of advancing your own MVC model, like #e-satis have said, you will need to experience what is happening in already developed systems. However, as based on my experience in designing MVC model and determining what is there in opensource community, I stick back to my own MVC for two good reasons. One reason is the flexibility of customization and the other is own MVC privacy.
I used the following approach for MVC design pattern.
A Router.php file identifying user-request urls. This router will be able to fetch controllers and include the file and call the controller default method.
The loaded controller is also able to load other controllers if required to function. This is done using a global method, where all controller Class will extend to a MainController Class which is able to call to other controllers.
I do use a global registry to set and get variables from one controller to the other.
The Models are used to get the Data from Table, and most of my Models will represent Database functions which includes CRUD (Create Read Update Delete). So that a controller can easily manipulate database table data using a model.
Naming conventions in all controller, models, and views is also important, if you want to system to be more intelligent to identify the required action knowing the file name.
I use the Views separately for each type of controller. And these views will be sent to a Master Template View file.
Same as models, the controller will be able to set Views to Master View.
There are other customizations which you can do, like applying security methods before calling a class, or after calling a class/controller/model/view etc.
This is done by the MainController, which it will always look into a folder with autoload class which states what files should be loaded before and after of different actions during the process of building the content and delivering the output.
MVC is not a small scale idea, but it is a design idea which can always be developed. There are so many PHP MVC open source frameworks to be found if you know how to search the major search engines like google.com
But I do advice you that, MVC is not a good solution if you are simply developing a small dynamic website, as it will consume more time in developing compared to developing small websites. MVC is ideal, if you have business logic and needs system automation in order to avoid most routine tasks of developing, and like that I would say MVC is most ideal for larger applications.
The model loads its view file
The Controller should act as a Mediator between the Model and the View.
The Model shouldn't be aware of the way the view renders it, and also the View shouldn't be aware of any kind of logic of the Model.
In theory, if your MVC is well structured, you should be able to represent the same Model with different types of Views (HTML, XML, JSON for example).
Build FrontController which parses request uri and decides which controller to load and which method to run. With .htaccess rewrite all request to index.php
//index.php
class FrontController{
function run(){
//parse request uri here /comment/new
//load controller comment
//run controllers method new and pass some request attributes
}
}
// ../controllers/comment.php
class Controller_Comment extends Controller{
function new($request){
//do stuff here
}
}

Categories