We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Getting values from other controllers?

Hi. I've just started learning Phalcon and I really like the framework and the documentation. One thing I have trouble doing (same with all the frameworks I try) is handling use cases like the following:

Create a new order: The first step is to select the customer from a table, but if the customer doesn't exist, it must be created (and saved to db) without breaking the work flow.

I can't tell the users "just exit the create order page, go to the customer page, create the customer, then come back and start creating the order again".

At the moment I use my own framework and do something like this (simplified):


class OrdersController {
    public static function createOrder()
    {
        $customer = CustomersContrller::getCustomer();

        // display new order form with customer details filled in...
    }
}

class CustomersContrller {
    public static function getCustomer()
    {
        if (isset($_GET['customer_id'])) {
            return CustomersModel::findFirst($_GET['customer_id']);
        } elseif (isset($_GET['new_customer'])) {
            return self::createCustomer();
        } else {
            // display list of customers to click on
        }
    }
    public static function createCustomer()
    {
        if (isset($_POST['new_customer'])) {
            // save to db and return newly created record
        } else {
            // display the new customer form
            // NOTE: the program exits after sending the form,
            // so we won't return to the calling function from 
            // inside this 'else' block.
        }
    }
}

Can anyone recommend a way to do this in Phalcon? (I'm thinking some special routing might do it) Thanks

(I also asked this question at StackOverflow)

I just noticed my typo on CustomersController. Also, bump.



43.9k

Hi,

I don't know how to call (or even if it's possible) a controller action from another controller. But an easy workaround is to implement your getCustomer() in your CustomersModel.



98.9k

You can implement this as you have implemented it in your example. The autoloader will autoload the specified class when it's used.



43.9k

using the same syntax: $customer = CustomersContrller::getCustomer(); ??



98.9k

Yes, it's like calling a static function on a class but this class is a controller. Not sure if this is good practice, though.



43.9k

OK, good to know (I'm always fascinated by phalcon's flexibility) !

On this discussion

https://stackoverflow.com/questions/20866988/php-mvc-routing-and-getting-values-from-other-controllers-phalconphp-and-other

someone points that it's not a good practice and that's my opinion too. So that's why I've suggested to put all this logic in models classes ...

Thanks for your input guys. I'm going to try to do it like in my example. I agree that it might not be good practice but if I can get it working I'll be happy.

The reason I haven't put getCustomer() in a model class is because it needs to send output to the browser (a list of customers to choose from, or a form to create a new customer). But I'll look at putting more of the logic in the models.

Keep up the great work on Phalcon, it's the best framework I've tried so far.



43.9k

you can use some phalcon's great features: 1/ pass a model resultset to the view from your createOrder action

$this->view->setVar('customers',CustomersModel::getCustomers());

2/ use Phalcon\Tag::select() in your view:

echo $this->tag->select(
    array(
        "customer_id",
        $customers,
        "using" => array("customer_id", "customer_name")
    )
);


43.9k

for creating a new customer entry within the create order form, you can use in that form a "create new customer" button that will open a modal window with the new customer form. After submission and success, ajax is your friend, close the modal, update the select list and mark the new entry as selected ... jquery + some good css+js famework (jquery-ui, bootstrap, zurb foundation ...) may help you a lot

Move it out of your controllers into a (business logic, not ORM) model, for example:

  • OrderModel is responsible for managing orders
  • CustomerModel is responsible for managing customers

Your first controller calls OrderModel to create order and it in its turn calls CustomerModel to create and/or return a customer. Your second controller works with CustomerModel only. Both models use ORM models to operate with a database.

It's additional abstraction layer that makes your design more elegant.

Thanks again guys. I'm going to use le51's suggestion of javascript and ajax to get the job done for now (probably a good idea to brush up on my client-side coding anyway). When I have a bit more experience with Phalcon I'll abstract out the business logic to separate classes.

Awesome feedback team :) much more helpful than some other sites...