Reputation: 500
Using CakePHP 1.3 I have an existing InvoicesController with a method single_invoice($customer_id), and all works great through normal use. However, I want to do the same thing through the cake shell and build it as a cronjob.
I have the shell created, and it does run as a cronjob, so that is not the problem. The problem is that I cannot get view rendered from the cronjob. Basically, here is what I have so far:
class InvoiceCreationShell extends Shell {
var $uses = array('Institution');
function main()
{
$institutions = $this->Institution->find('all');
foreach ($institutions as $institution)
{
App::import('Core', 'Controller');
App::import('Controller', 'Invoices');
$Invoices = new InvoicesController;
$Invoices->constructClasses();
$invoice = $Invoices->single_invoice();
$pdf = create_pdf($invoice);
file_put_contents($pdf);
}
}
}
What I would like is for the rendered view content to be returned via the $invoice parameter.
Upvotes: 0
Views: 978
Reputation: 4856
You cannot do this because a Shell is used for CLI applications where the PHP environment is different from the one called through a web server such as Apache or Nginx.
However you could still use existing Web Application functionality and you have two options for this:
Initialize a Controller object
The following code example is for CakePHP >= 2.x
Sorry but initially I did not see that the question is about 1.3. Point 2. has a nice suggestion in that case. Also there is a way to Initialize a Controller object in CakePHP1.3 - this for example.
In this case it really depends on how your invoice generation is implemented. Just remember that the view part is "out of the question". So if you render to a variable and then create the pdf (for example) from that var you will still be able to get it. The trick is how to initialize the Controller Object in the Shell:
Firstly include the Classes required:
App::import('Controller','Controller'); App::import('Controller', 'initializedController');
Have a variable in the Shell/Task:
private $initializedController;
Then:
$this->initializedController = new initializedController(new CakeRequest('/'), new CakeResponse()); $this->initializedController->constructClasses(); $this->initializedController->startupProcess();
Now you could call all methods in the Controller.
2.Make an HTTP request to the existing WebApp
This could be achieved via CakePHP's own HttpSocket Class or some request library such as Guzzle.
Upvotes: 1
Reputation: 500
I came to the conclusion that using a view from a shell was not possible after talking to many people, posting here as well as IRC. So here is how I solved my problem:
Instead of trying to get the view to output from the shell I simply rendered the View from within the Controller instead. Here is a sample of what the controller would look like to solve this:
class InvoicesController extends AppController {
function single_invoice($institution_id)
{
/* Do stuff */
return $this->render('single_invoice', 'invoice_layout');
}
}
This allowed the shell to capture the contents of the rendered view in the $invoice parameter, then to pass it to the pdf generator.
I also added a paremeter, not shown, to the single_invoice action for $is_shell. Then I surrounded the return $this->render... in an "if ($is_shell) {" check to render only if used by the shell.
Upvotes: 0