1

I'm developing a plugin in cakephp. I have created a controller inside called PermissionsController.php inside Plugin/Permissions/Controller

This controller extends another controller: PermissionManagerAppController.php in the same directory.

I would like to know how to call a function inside the plugin from another controller like UsersController.php

this is my plugin controller empty now:

class PermissionsController extends PermissionManagerAppController {
    public $uses = array('PermissionManager.Permission');

    public function index() {
    }

    public function test($string) {
        echo'<p>TEST: '.$string.'</p>';
    }
}

I would like to call action test from another controller.
I have tried this:

App::uses('Permissions', 'PermissionsController.Controller');

class UsersController extends AppController {
    public $name = 'Users';
    public $scaffold;

    public function beforeFilter () {
        parent::beforeFilter(); 
        $permissions = new Permissions();
        $permissions->test('test');
       }
}

I have also tried

App::uses('Permissions', 'Permissions.Controller');

return me always this error:

Fatal error: Class 'Permissions' not found

I have tried:

$this->permissions->test('test');

And I retrieve this error:

Fatal error: Call to a member function test() on a non-object 

how to solve this?

Alessandro Minoccheri
  • 35,521
  • 22
  • 122
  • 171
  • 2
    Thinking about doing such calls is an indicator for not following the MVC pattern proposed by CakePHP. Depending on the functionality your `test()` method provides, it should probably go into a component or a model, or you should extend the plugin controller. – ndm Nov 18 '13 at 22:59
  • Ok but if i only write a vendor file? Because i havn't to write into the database. . Or is better to make only a component? I have used a controller Because i have to make a redirect. . How to do it in component or vendor? @ndm – Alessandro Minoccheri Nov 19 '13 at 07:33
  • I can't recommend you anything without knowing about the exact functionality you are trying to share, you'll have to show some actual code and/or describe this functions purpose. All I can say for now is that redirects can be done from anywhere in your code (though models really shouldn't do that), so you are not limited to a controller, and if the functionality is CakePHP related and doesn't interact with the database, then [**a component**](http://book.cakephp.org/2.0/en/controllers/components.html#creating-a-component) is _probably_ the way to go. – ndm Nov 19 '13 at 10:32
  • Weel, code is a simple function where parameters ar an array. Inside it there are a list of view and user_group and in vase of the actual URL (action passed) I check if that user (in base its group) can access or not at the page, if not redirect to another page. @ndm – Alessandro Minoccheri Nov 19 '13 at 10:34
  • Sounds similar to that what the ACL and auth components do... Judging from the information you provide I'd say a component is the way to go then. – ndm Nov 19 '13 at 10:53
  • Perfect thanks for your help, yes is similar ACL, but is more simple to manage access, ASAP I'll publish it on github. @ndm – Alessandro Minoccheri Nov 19 '13 at 10:55
  • You *really* shouldn’t be calling a controller from within another controller. Permissions sounds more like something that would be better packages as a controller component, rather than a controller unto itself. – Martin Bean Nov 19 '13 at 13:03
  • great, but you meaning a plugin with a component, or a plugin with component and controller to manage well? If possible answer to my question with an example of the better solution for you tahnks @MartinBean – Alessandro Minoccheri Nov 19 '13 at 13:05

3 Answers3

6

Just to build on Thorpe Obazee’s answer and my comment, it’s probably best to build something like permissions management as a controller component as opposed to a controller unto itself. As aforementioned, you really shouldn’t be calling controllers from controllers—this goes against the principles of MVC (and in turn CakePHP).

A component can be packaged within a plugin. If your plugin is called Permissions and your component is called Permissions too, then your directory structure would look like this:

  • app
    • Plugin
      • Permissions
        • Controller
          • Component
            • PermissionsComponent.php

When you load your plugin, you can then use this component in your core app’s controller as any other component, just with the plugin syntax:

<?php
class UsersController extends AppController {

    public $components = array(
        'Permissions.Permissions'
    );
}

And your actual component within your plugin would look like this:

<?php
App::uses('Component', 'Controller');

class PermissionsComponent extends Component {

    public function checkPermission() {
        // code...
    }
}

You would then call any component methods as you would a core component method:

<?php
class UsersController extends AppController {

    public $components = array(
        'Permissions.Permissions'
    );

    public function beforeFilter() {
        $this->Permissions->checkPermission();
    }
}

Hope this helps.

Martin Bean
  • 38,379
  • 25
  • 128
  • 201
  • the only thing missed is how to call checkPermission function, for the rest is a complete answer thanks – Alessandro Minoccheri Nov 19 '13 at 13:14
  • Updated. You would call your plugin component’s methods as you would a core component’s methods. – Martin Bean Nov 19 '13 at 13:16
  • Perfect, I think that this answer is very complete for my scope, I haven't used a component because I thinked that a plugin can't be only a component, and for hat I have create a controller and a plugin after.. – Alessandro Minoccheri Nov 19 '13 at 13:19
  • No. A plugin can be as little or as complete as you wish, there are no limits either way. I have lots of plugins that are just a view helper or a model behavior or a controller component. – Martin Bean Nov 19 '13 at 13:23
  • 1
    No problem. All the best with your CakePHP project! – Martin Bean Nov 19 '13 at 13:25
1

I suggest that you extract the functionality into a component that way functionality can be shared between Controllers.

<?php

App::uses('Component', 'Controller');

class TestingComponent extends Component {

    public function sayTesting($email) {
         return '<p>TEST: '.$string.'</p>';
    }
}

Update: To add this to a Controller,

public $components = array('Testing');

Then from a Controller method:

public function foobar() {
    $word = $this->Testing->sayTesting();
}
Teej
  • 12,764
  • 9
  • 72
  • 93
  • `$this->components = array('Permissions.Permissions')';` assuming your plugin is called `Permissions` and your component is called `Permissions` too. – Martin Bean Nov 19 '13 at 13:05
  • Thanks I have seen and it would be a nice solution, you adivse to use controller or model inside the plugin and this component to manage well or is not necessary? – Alessandro Minoccheri Nov 19 '13 at 13:06
0

Just to add another note. I also notice that the sub-folders in '/app/Plugin' must have the correct permission (chmod 755). If not, Cakephp will not be able to find/load the plugin.

If you are on ubuntu, just send the command below. Remember to do this for your SUB-FOLDERS too!

chmod 755 /app/Plugin/YOUR_PLUGIN_NAME

More info about chmod here : Change all files and folders permissions of a directory to 644/755

Community
  • 1
  • 1
Britc
  • 623
  • 5
  • 8