Cakephp 3.x使用外壳中的控制器方法



我正在尝试在我的应用程序中发送背景电子邮件。

我正在制作一个外壳,最终将安排通过crontask运行。

我试图在电子邮件壳中运行以下代码:

<?php
namespace AppShell;
use CakeConsoleShell;
use CakeCoreApp;
App::import('Controller', 'Messages');
class EmailShell extends Shell{
    public function main(){
        //Check for unsent emails
        $messagesCont = new MessagesController;
        $messages = $messagesCont->findAllUnsent();
        //Send all unsent emails
        foreach ($messages as $message){
        $email = new Email();
        $email->to($messages->receiver)
            ->subject($message->subject)
            ->send($message->body);
        }
      //Update the table to be marked as sent
    }   
}
?>

我从MessagesController中需要的代码就是这样:

 public function findAllUnsent(){
     $messages = $this->paginate($this->Messages);
    foreach ($messages as $message){
      if ($message->sent == false){
        //If message is unsent then add it to the array
        $messagesFound[] = $message;
      }
    }
    //Return the array of unsent messages
    return $messagesFound;
  }
}

但是,当我使用bin/cake email

通过命令行终端运行外壳时

我有以下错误:

例外:致电未定义的方法蛋糕 core app :: import()in [/HOME/CABOX/WORKSPACE/SRC/SHELL/EMAILSHELL.PHP,第7行]

中指出的答案对注释中链接的问题,您根本不应在外壳中使用控制器。该代码应在您的模型中,例如在查找器中或只是常规类方法中。

还应注意,吊载器的使用与方法名称相矛盾,该方法名称"找到全部",默认情况下将只找到最多20个记录。另外,我建议您改为过滤SQL级别的记录,以便您仅收到实际需要的记录,然后将其减少后,因为它使用针对原始结果计算的数字进行操作。

因此,在您的MessagesTable类中添加例如自定义查找器,例如:

public function findUnsent(CakeORMQuery $query, array $options)
{
    return $query->where([
        $this->aliasField('sent') => false
    ]);
}

在您的外壳中使用模型,例如:

class EmailShell extends Shell
{
    use CakeORMLocatorLocatorAwareTrait;
    public function main()
    {
        // tableLocator() before CakePHP 3.5
        $MessagesTable = $this->getTableLocator()->get('Messages');
        $unsentMessages = $MessagesTable->find('unsent');
        foreach ($unsentMessages as $message) {
            // ...
        }
    }   
}

类似地,您也将查找器也在控制器中,然后将查询传递给paginate()方法。

顺便说一句,不再有App::import(),Cakephp 3.x使用 Composer 自动加载,该调用应该触发错误。

另请参见

  • cookbook>数据库访问&amp;ORM>检索数据&amp;结果集>使用发现器加载数据
  • cookbook>数据库访问&amp;ORM>检索数据&amp;结果集>自定义查找器方法
  • API> cake orm locator locatorawaretrait
  • cookbook>控制器>组件>分页>使用控制器:: paginate()

最新更新