3.12.1.1 Creating Your Own Shells

Let's create a shell for use in the Console. For this example, we'll create a ‘report' shell that prints out some model data. First, create report.php in /vendors/shells/.

<?php 
class ReportShell extends Shell {
	function main() {}
}
?>
  1. <?php
  2. class ReportShell extends Shell {
  3. function main() {}
  4. }
  5. ?>

From this point, we can run the shell, but it won't do much. Let's add some models to the shell so that we can create a report of some sort. This is done just as it is in the controller: by adding the names of models to the $uses variable.

<?php
class ReportShell extends Shell {
	var $uses = array('Order');

	function main() {
	}
}
?>
  1. <?php
  2. class ReportShell extends Shell {
  3. var $uses = array('Order');
  4. function main() {
  5. }
  6. }
  7. ?>

Once we've added our model to the $uses array, we can use it in the main() method. In this example, our Order model should now be accessible as $this->Order in the main() method of our new shell.

Here's a simple example of the logic we might use in this shell:

class ReportShell extends Shell {
	var $uses = array('Order');
	function main() {
		//Get orders shipped in the last    month
		$month_ago = date('Y-m-d H:i:s',    strtotime('-1 month'));
		$orders =    $this->Order->findAll("Order.shipped >= '$month_ago'");

		//Print out each order's information
		foreach($orders as $order) {
			$this->out('Order date:	' .    $order['created'] . "\n");
			$this->out('Amount: $' .    number_format($order['amount'], 2) . "\n");
			$this->out('----------------------------------------' .    "\n");
	 
			$total += $order['amount'];
		}

		//Print out total for the selected orders
		$this->out("Total: $" .    number_format($total, 2) . "\n"); 
	}
}
  1. class ReportShell extends Shell {
  2. var $uses = array('Order');
  3. function main() {
  4. //Get orders shipped in the last month
  5. $month_ago = date('Y-m-d H:i:s', strtotime('-1 month'));
  6. $orders = $this->Order->findAll("Order.shipped >= '$month_ago'");
  7. //Print out each order's information
  8. foreach($orders as $order) {
  9. $this->out('Order date: ' . $order['created'] . "\n");
  10. $this->out('Amount: $' . number_format($order['amount'], 2) . "\n");
  11. $this->out('----------------------------------------' . "\n");
  12. $total += $order['amount'];
  13. }
  14. //Print out total for the selected orders
  15. $this->out("Total: $" . number_format($total, 2) . "\n");
  16. }
  17. }

You would be able to run this report by executing this command (if the cake command is in your PATH):

$ cake report 

where report is the name of the shell file in /vendor/shells/ without the .php extension. This should yield something like:

Hello user,
   Welcome to    CakePHP v1.2 Console
   ---------------------------------------------------------------
   App : app
   Path:    /path/to/cake/app
   ---------------------------------------------------------------
   Order date:    2007-07-30 10:31:12
   Amount:    $42.78
   ----------------------------------------
   Order date:    2007-07-30 21:16:03
   Amount:    $83.63
   ----------------------------------------
   Order date:    2007-07-29 15:52:42
   Amount:    $423.26
   ----------------------------------------
   Order date:    2007-07-29 01:42:22
   Amount:    $134.52
   ----------------------------------------
   Order date:    2007-07-29 01:40:52
   Amount:    $183.56
   ----------------------------------------
   Total:    $867.75