Download file via response in Cell View and navigating between Cell Views

Hey there!

I am currently experimenting a lot with cell views. I have a program where there are to be 5 to 7 user types. Each one of them will have an individual setup process where different controller logic applies for different or same setup steps.
To not blow up the main controller and to nicely separate concerns I created own cell views for every user type. So in some main controller there is one single view which dynamically decides which cell to take on every setup step:

store_wizard.ctp

<?php
$cell = $this->cell('EbayFashion.EbayTemplateNavigator' . $type . '::' . $nextStep);

echo $cell->render();

It works fine and definitely has some benefits, although it has some obvious deficits as well, because of the missing controller methods.

Now I stumbled over another problem: when I download an HTML file via the response method I always get the whole HTML of the source page inside my file body with that code:

$this->response->body($text);
            $this->response->type('text/html');
            $this->response->download('dl' . $userName . '.html');
            return $this->response;

where $text is just a string.

The code works fine inside the standard controllers.

Also I didn’t find another possibility to navigate between my cell views besides having a custom redirection method like this:

public function customRedirect($redirecterValue)
{
$this->loadModel(‘EbayFashion.EbayFashionStores’);
$ebayFashionStore = $this->EbayFashionStores->find()->contain([‘EbayAccounts’, ‘CoreSellers.CoreSellerTypes’])->first();

    //value of form's hidden field determines the next step
    $nextStep = $redirecterValue;

    $ebayFashionStore->wizard_next_step = $nextStep;

    if ($this->Store->save($Store)) {
        if(method_exists($this, $nextStep)) {
            $this->{$nextStep}(true);
        }
    }
}

which are called on POST requests. (the redirecter values are strings of hidden input fields of the template view forms which contain the name of the next method to jump in.)
Is this the only workaround on it?

My last question is:
is there any way to jump out of the cell view e.g. to another controller when the setup is finished? So far it doesn’t seem to be possible to me without the redirection method.

I’m not entirely sure I understand what your application is supposed to be and to do, but if you find yourself in need of redirects and the like, chances are that cells are not the right tool for the job.

The idea with cells is essentially identical with that of elements, except that you get the ability to populate them with data from a model directly, that is, without the need to add it to controllers every time you use it.

So the only benefit of cells really is that if you use them multiple times, you won’t have to write code to fetch model data more than once.

This means that if you don’t use a cell action more than once, then there is no point in using a cell whatsoever, since cells are (intentionally) very limited in comparison to controller actions.

Given this fact, it’s important to ask yourself whether cells are the right tool for you, or whether components, elements and helpers may be more suitable.

It strongly depends on how exactly your setup processes need to behave, but my hunch is that cells aren’t the right tool for you (especially since usually, you would create only one cell and load it with different parameters every time, instead of creating multiple cells, which as I described offers no real benefits).

Hey thanks for your answer!

From this point of view I might have chosen the wrong approach indeed.

This approach was thought for a big application where you have for example 5 user types where each one of them has 3 to 5 setup/configuration steps which differ from each other. To avoid having 20 different controller methods and template views, I experimented a bit with cells. In this way all the steps and users are nicely separated in the cell folders (View and Template) and don’t overload the site’s main controller. I find it pretty nice, even though it’s not the original use case for cells.

But of course the missing functionality is killing this approach at some point unfortunately.

Okay, I guess the question then is whether you really need this many controller methods? Usually you can use one action with perhaps 2-3 parameters and use these to load the appropriate model data. Then create only one view and an element folder with as many elements as necessary; This is a very clean approach, too. Depending on your needs, you could also use helpers instead oft elements. Most of the time, these basic tools are more than enough to create very DRY code.

1 Like