5

I am trying to implement a task using the cakephp shell for my application. The task involves running a long running process (hence the need to use the shell).

The function requires me to use a function inside a Component called CommonComponent

Unfortunately whenever i try to include the component i get the following error PHP Fatal error: Class 'Component' not found in /var/www/nginx-test/app/Controller/Component/CommonComponent.php

Here is the CronShell Class which is being called

class CronShell extends AppShell {
   public function main() {
        $this->out('Hello world.');      
//  $this->out(phpinfo());
    }
     public function test()
    {
         $this->out('Before Import'); 
        App::import('Component', 'Common');
        $this->out('Import complete');
        // $this->Common=ClassRegistry::init('CommonComponent');
        $this->Common =new CommonComponent();
        $this->out('Initialization complete');
        $this->Common->testCron();
         $this->out('FunctionCall complete');
        //$this->Common->saveCacheEntry("name","value");
    }
    }

The CommonComponent class is stored as app/Controller/Component/CommonComponent.php and is as follows

 class CommonComponent extends Component
{
 function testCron()
    {    
     $this->out('Hello world from Component.');
    }
 }

Any ideas?

Sanket Gupta
  • 573
  • 3
  • 6
  • 21

4 Answers4

14

I had to do this recently with MTurk component I wrote. My final solution was using a lib instead of a component. Then I had the component access the lib so I could use the methods from both a component and from shell.

However, here is code that WILL allow you to load a component from a shell.

<?php
App::uses('AppShell', 'Console/Command');
App::uses('ComponentCollection', 'Controller');
App::uses('Controller', 'Controller');
App::uses('MTurkComponent', 'Controller/Component');

class ProcessCompletedTask extends Shell {
    public function execute() {
        $this->out("Processing...\n");
        $collection = new ComponentCollection();
        $this->MTurk = new MTurkComponent($collection);
        $controller = new Controller();
        $this->MTurk->initialize($controller);

        $this->MTurk->processHITs();
        $this->out("Complete\n");
    }
}
nhaarman
  • 98,571
  • 55
  • 246
  • 278
Steve Tauber
  • 9,551
  • 5
  • 42
  • 46
1

What you import into the Shell should be code from within your Apps Lib

the component can also make use of the Lib code - but you'll not need to do a load of tedious stuff if you set it up right you'll make you app cleaner

if you import the component you'll need to pass it a component collection and so you'd have to make that from witin shell not that your use it (or if you do you must be doing it wrong)

sam
  • 166
  • 3
  • Moving the common code from component to a clas inside lib folder worked.I am still confused on what code should bcome part of the libs and what code should be part of a component – Sanket Gupta Feb 09 '12 at 19:03
  • @Zulubaba do you have some code to see either pasted into bin.cakephp.org or paste bin some where else. I can appreciate what your confusion but can't elabourate with out seeing code other than to say that Mark Story's asset compress does this. Asset Compress uses shell and helper both which source classes from with Lib (extra config directions specific to the plugin are used by both) I would need to know more about you common comp and could suggest from there – sam Feb 12 '12 at 18:15
0

I believe that it is semantically wrong to share functionality between controllers and shells.

If you require common functionality, it is clearer and neater to put it in a separate class, place this class in your vendors folder and then import the code into both the controller and the shell.

In addition, this approach does not prevent you from creating components and tasks that use the core functionality and then share these components and tasks between your controllers and shells.

thanassis
  • 691
  • 5
  • 11
0

Have you tried App::uses('Component', 'Controller'); at the top of your file, ev. before import of CommonComponent? Then I guess you need to do what sam says, or you could use the $this->Controller->Components->load('CommonComponent') but for that you need to construct the Controller class.

lp1051
  • 491
  • 7
  • 19