简体   繁体   中英

CakePHP - Shell command can't bypass beforeFilter

I'm trying to build a cronjob that calls a specific action in a controller. The shell script that I write doesn't seem to be able to bypass the controller's beforeFilter call.

I thought of using session but there's no luck so far. Here is the code:

<?php

if (!isset($_SESSION)) session_start();

class MyShell extends AppShell
{
    public function main() {
        $_SESSION['toBypassBeforeFilter'] = "true";

        CakeLog::write('debug', 'Calculating WIP...');
        $this->requestAction('/account/wip_reports');
        CakeLog::write('debug', 'Finishing WIP calculations...');
    }

}

The debug log writes out the first one before the action call.

2015-10-05 02:08:49 Debug: Calculating WIP...

But not the second one when that action call is done. What have I missed?

EDIT

It looks like that requestAction() call to the route is not recognizable even though I can still run it in the browser. Maybe it should have been a different route?

Do not call controllers from cli processes

Generally speaking using requestAction is an indicator of poor application architecture. The right approach to running cron jobs with CakePHP is to write a cli process that calls the methods that actually do things directly, not having a cli process that simulates a http request.

Fat models, skinny controllers

In a cli context, the shell is a controller - controller code should always be kept to a minium. Whereas currently you've got this:

class MyShell extends AppShell
{
    public function main()
    {
        $this->requestAction('/account/wip_reports');
    }
}

And this:

class AccountsController extends AppController
{
    public function wip_reports()
    {
        ... some code ...
    }
}

In principle what you should have is this:

class MyShell extends AppShell
{
    public function main()
    {
        $account = ClassRegistry::init('Account');
        $account->something();
}

And this:

class AccountsController extends AppController
{
    public function wip_reports()
    {
        $this->Account->something();
    }
}

With all the relevant logic in a model:

class Account extends AppModel
{
    public function something()
    {
        ... some code ...
    }
}

In this way the shell does not depend on, or even interact with, the controller at all - it just calls the same methods the controller action method does.

Well, you're abusing a controller for something it is not thought for and you now have to face the results of that abuse. A session won't be available in a shell environment either.

Refactor your code so that the business logic resides in a model or another class that is callable from a shell environment and has no dependencies on a web environment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM