In Rails, you can organize controllers into folders and keep your structure nice with namespacing. I'm looking for a similar organizational structure in Symfony 1.4.
I was thinking of organizing multiple actions.class.php files in an actions folder, but all I came across was using independent action files, one for each action... like this:
# fooAction.class.php
class fooAction extends sfActions {
public function executeFoo() {
echo 'foo!';
}
}
But I'd have to develop a whole new routing system in order to fit multiple actions into that file, which is... silly.
Really I'm just looking to make Symfony into Rails, (again, silly, but I'm stuck with Symfony for this project) so I'm wondering if there's a better way....?
Thanks.
An alternative action syntax is
available to dispatch the actions in
separate files, one file per action.
In this case, each action class
extends sfAction (instead of
sfActions) and is named
actionNameAction. The actual action
method is simply named execute.
class indexAction extends sfAction
{
public function execute($request)
{
// ...
}
}
A Gentle Introduction to symfony - chapter 06: Inside the controller layer, subsection Alternative Action Class Syntax
Related
I’m looking at different mail services for using with my Codeigniter projects. Amongs them: Mandrill, Mailgun, Postmarkapp etc.
In most cases, there is already one or more Codeigniter libraries available but If I want to build on them, making simpler methods that are more suited to my projects and CMS workflow for instance, what’s the best way to approach without having to write the whole thing from scratch?
Is it best to create a new class that extends the existing CI library? and then include those two files? /libraries/mailgun & /libraries/my_mailgun.php
I'm using this method.
I put the put the external libary in /application/third_party, after I create a class in /application/libraries with name my_{project name}.
Inside the my_{project name} I put a require_once as the follow code
require_once APPPATH."/third_party/projectname/main.php";
class Algumnome extends Project {
public function __construct($arg1 = 'defaultValueToProject', $arg2 = 'defaultValueToProject'){
parent::__construct($arg1, $arg2);
}
}
I my controller I call the lib like:
$this->load->library('algumnome');
$this->algumnome->method();
You definatly answered your own question here.
Is it best to create a new class that extends the existing CI library? and then include those two files? /libraries/mailgun & /libraries/my_mailgun.php?
Yes, is the correct answer, this way you can Add new functionality to an existing library without having to reinvent 90% of the wheel.
class My_lib extends stock_lib
{
function newMethod1()
{
}
function newMethod2()
{
}
function etc()
{
}
}
As you already mentioned this will allow you to use your new functions as well as the existing functions to the parent class.
so, i should up-vote you for answering your own quesiton, and this answer is just a re-iteration of you answer.
We're currently developing an E-commerce site. We have a public and admin module.
Sometimes we offer the same functionality in both modules like viewing of products or creating of orders. But there are also some functionalities that is present in either public or admin like adding of products (which is in admin).
Our problem is that common functionalities lead to duplication of logic. We need to implement it in both modules.
One way of solving the problem is to make use of layers. So what we did was move the common logic into the Model. However, the controller is still duplicating codes like the one shown below:
public function invoice() {
$this->Invoice->create();
$this->Invoice->setCustomer($this->getCurrentUser);
$invoice_items = // get list of items from post
$this->Invoice->setItems($invoice_items);
$this->Invoice->save();
}
My question is, is it wise to create a webservice that will encapsulate this logic and you just have to call it from the admin and public modules..
How does Magento implement the public and admin panels. And how does it manage its logic..
I would recommend you not to do that. From your question, it is not exactly clear what sort of 'logic' are you referring to, but it does not seem too complex from your example. In general, business logic should be coded within the Model, controller, or Helper portions of the code. It can even reside in a separate extension as long as you set dependencies properly in the main xml file of the extension.
It seems that you may benefit from placing your logic in a helper class. The default helper file resides under /app/code/community/company/extension-name/Helper/Data.php. Then you can call the helper method anywhere in the backend (Block, Module, or controllers) by using this piece of code:
Mage::helper('extension-name')->getLogic()
Or you can call the same helper method from the view (phtml files) like this:
$this->helper('extension-name')->getLogic()
I am trying to implement this Command Pattern on my .NET MVC 3 application, specifically for saving edits to a Thing. I am undecided on how to proceed. Before I get to the actual question, here is the simplified code:
public class ThingController
{
private readonly ICommandHandler<EditThingCommand> handler;
public ThingController(ICommandHandler<EditThingCommand> handler)
{
this.handler = handler;
}
public ActionMethod EditThing(int id)
{
...build EditThingViewModel and return with View...
}
[HttpPost]
public ActionMethod EditThing(int id, EditThingViewModel vm)
{
var command = new EditThingCommand
{
...not sure yet...
};
this.handler.Handle(command);
...redirect somewhere...
}
}
My EditThingViewModel is wholly disconnected from my domain, which consists of POCO classes. It seems like my EditThingCommand should look like this:
public class EditThingCommand
{
Thing ModifiedThing;
}
However, building ModifiedThing would then still be happening in my controller. That's the majority of the work in this case. By the time ModifiedThing is built (and the "old" timestamp applied to it for optimistic concurrency checking), all that's left is for command to call Update on my data context.
Clearly there is value in being able to easily decorate it with other commands, but I'd also like to be able to move the construction of ModifiedThing outside of my controller. (Perhaps this question is really just about that.) EditThingCommand is in my domain and doesn't have a reference to EditThingViewModel, so it can't go there. Does it make sense to have another command in my presentation layer for mapping my viewmodel to my poco entity?
I created an EditThingPostCommand outside of my domain, which takes the EditThingViewModel as a parameter. The EditThingPostCommandHandler is responsible for creating the EditThingCommand and calling its handler.
It works, but I'm not going to assume that's the best answer to my question. Arguably most of what the EditThingPostCommandHandler is doing could be done in a custom AutoMapper configuration, which would still serve the purpose of cleaning up the controller action method.
After several months of using this pattern on other projects, it is apparent to me that the commands on this particular project were simply too general and therefore too complex, requiring too much setup. It would have been better to create, for example, an EditThingTitleCommand and a MoveThingPiecesCommand and so on, and call them from their own ActionMethods.
In other words, when using the command pattern, don't just use the commands as replacements for typical CRUD operations. With more specificity comes more benefit.
Am having problems understanding where classes should be kept in CI. I am building an application that describes / markets mobile phones.
I would like for all of my functions (i.e. getphone, getdetails etc.) to reside in one class called Mobile - I understand that this file should be called Mobile.php and reside in the controllers folder.
Can I then have multiple functions inside Mobile.php? E.g.
public function getphone() {
xxx
xx
xx
}
public function getdetails() {
xxx
xx
xx
}
Or do I need to put each function in its own class?
I'd really appreciate looking at some sample code that works. I've been going through the documentation and google for a few hours, and tried all sorts of variations in the URL to find a test class, but without much luck! I've even messed around with the routes and .htaccess...
All I am trying to achieve is the following:
http:///model/HTC-Desire/ to be re-routed to a function that accepts HTC-Desire as a parameter (as I need it for a DB lookup). The default controller works fine, but can't get anything to work thereafter.
Any ideas?
Thanks
Actually it works like this:
Controllers and Models go to their perspective folders as you know it
If you want to create functions that are not methods of an object, you must create a helper file. More info here :
http://codeigniter.com/user_guide/general/helpers.html
Now if you want to create your own datatypes (classes that don't extend Models and Controllers), you add them to the library folder. So if let's say you want to create a class "Car" you create this file:
class Car{
function __construct(){}
}
and save it in the libraries folder as car.php
To create an instance of the Car class you must do the following:
$this->load->library('car');
$my_car = new Car();
More information on libraries here:
http://codeigniter.com/user_guide/general/creating_libraries.html
Yes, you can have as many functions in a controller class as you'd like. They are accessible via the url /class/function.
You can catch parameters in the class functions, though it's not advisable.
class Mobile extends CI_Controller{
public function getPhone($phoneModel=''){
echo $phoneModel;
//echo $this->input->post('phoneModel');
}
}
http://site.com/mobile/getPhone/HTC-Rad theoretically would echo out "HTC-Rad". HOWEVER, special characters are not welcome in URL's in CI by default, so in this example you may be met with a 'Disallowed URI characters" error instead. You'd be better off passing the phone model (or any other parameters) via $_POST to the controller.
Classes can exist both as Controllers and Models, as CodeIgniter implements the MVC pattern. I recommend reading more about that to understand how your classes/functions/etc. can best be organized.
Off the top of my head, Pyro CMS is an application built with CodeIgniter and the source code is freely available. I'm sure there are others.
I think it's best you handle it from one perspective, that is; create a utility class with all your functions in it.
The answer to the question of where to put/place the class file is the "libraries" folder.
This is clearly stated in the documentation. Place your class in the libraries folder.
When we use the term “Libraries” we are normally referring to the
classes that are located in the libraries directory and described in
the Class Reference of this user guide.
You can read more on creating and using libraries Creating Libraries — CodeIgniter 3.1.10 documentation
After placing the newly created class in the libraries folder, to use just simply load the library within your controller as shown below:
$this->load->library('yourphpclassname');
If you wish to receive several arguments within you constructor you have to modify it to receive an argument which would be an array and you loading/initialization would then be slightly different as shown below:
$params = array('type' => 'large', 'color' => 'red');
$this->load->library('yourphpclassname', $params);
Then, to access any of the functions within the class simply do that as shown below:
$this->yourphpclassname->some_method();
I hope this answers your question if you have further question do leave a comment and I would do well to respond to them.
I'm being confused, I have a function that needs to update some table, I have placed it inside controller, however now I have found that I will need to use it inside other 2 controllers.
What is the best practice to place the function that making updates and where to place it and how to call it?
maybe helper?
Did you create your models by extending JTable? In this case, just add the method there. It's perfectly ok to have business logic in the model such as "increment all rows of this user id by one" (static method) or "split up this name and save it into columns first name & second name" (normal method).
The helper would need to be relevant to the controller, as it will be applied to all controllers. I will assume that not all controllers would see meaning in calling the Update.
You could create a static class with a static method that would update your table.
etc Add a file to the Models folder and then create the following class.
public static CalledFromMultipleLocations
{
public static void UpdateMyTable(string somedata)
{
//Do you update code.
}
}
Without knowing your business object model its hard to really provide a solution.