CakePHP 3 Plugin Routes don't seem to be loading - cakephp

I'm trying to load routes in a plugin in CakePHP 3.2. They work fine if I put the routes in the core routes.php file, but not in my plugin routes.php file.
The plugin name is: MFC/HDParser.
The path is: /vendor/mfc/hdparser. (The plugin was originally baked into the plugins directory, but transferred it to the vendors directory (and all the files updated) just in case that was the issue.)
In the core bootstrap file I have:
Plugin::load('MFC/HDParser', ['bootstrap' => true, 'routes' => true, 'autoload' => true]);
/vendor/cakephp-plugins contains the line:
'MFC/HDParser' => $baseDir . '/vendor/mfc/hdparser/'
/composer.json contains:
"autoload": {
"psr-4": {
"App\\": "src",
"mfc\\hdparser\\": "./vendor/mfc/hdparser/src",
}
},
My /vendor/mfc/hdparser/config/routes.php contains:
use Cake\Routing\Router;
Router::plugin(
'MFC/HDParser', ['path' => '/hdparser'], function ($routes) {
$routes->connect('/charactersheet', ['plugin' => 'MFC/HDParser', 'controller' => 'Charactersheet', 'action' => 'index']);
// $routes->connect('/:controller');
//
//$routes->resources('Charactersheet');
// $routes->fallbacks('DashedRoute');
//}
);
//Router::connect('/charactersheet', ['plugin' => 'MFC/HDParser', 'controller' => 'Charactersheet', 'action' => 'index']);
I've also tried using 'path' => '/mfc/hdparser'
When I try to access site.dev/charactersheet I get "Error: CharactersheetController could not be found."
If I try to use a route like /mfc/hdparser/charactersheet, /MFC/HDParser/charactersheet or /m-f-c..., /m_f_c..., /Mfc..., etc I get a missing controller ('Mfc') error.
If I put the line:
Router::connect('/charactersheet', ['plugin' => 'MFC/HDParser', 'controller' => 'Charactersheet', 'action' => 'index']);
in the core routes.php file (outside the scope, before Plugins:load(); or inside the scope using $routes->connect() ) it works fine.
I've tried inflecting just about everything using underscores, dashes and camelcase.
I've dug through the documentation (http://book.cakephp.org/3.0/en/plugins.html, http://book.cakephp.org/3.0/en/development/routing.html, http://api.cakephp.org/3.2/class-Cake.Routing.Router.html) and tried everything I could find there (and here), as well as using the CakeDC/Users plugin as a template, but I'm still missing something...
--MFC

I had the same issue with CakePHP 3.3, the routes.php file in my plugin was not loaded.
I fixed it by putting Plugin::routes(); after loading my plugins. This method loads all routes for plugins, where the configuration has 'routes' => true.
E.g.
Plugin::load('MyPlugin', ['routes' => true]);
Plugin::routes();

Related

How to have different dashboards based on roles with cakedc plugins / users & acl

I am using CakeDC Users & ACL plugins in my CakePhp app. I have different roles for my users in my app and I would like to have different dashboards based on roles after login.
I extend the plugin with my own table and controller based on the documentation here, so I have MyUsersController and MyUsersTable which override the initial files of the plugin, UsersController and UsersTable. Everything works fine. I create an event in my events.php file which contains:
use CakeDC\Users\Controller\Component\UsersAuthComponent;
use Cake\Event\Event;
use Cake\Event\EventManager;
EventManager::instance()->on(
UsersAuthComponent::EVENT_AFTER_LOGIN,
['priority' => 99],
function (Event $event) {
if ($event->data['user']['role_id'] === 'bbcb3031-ebed-445e-8507-f9effb2de026') //the id of my client role{
return ['plugin' => 'CakeDC/Users', 'controller' => 'MyUsers', 'action' => 'index', '_full' => true, 'prefix' => false];
}
}
);
But it seems like the override is not working because I have an error:
Error: CakeDC/Users.MyUsersController could not be found.
In my URL I have /users/my-users instead of /my-users and I don't know why. I have test with a template file which is include in the plugin and the Users controller like this:
function (Event $event) {
if ($event->data['user']['role_id'] === 'bbcb3031-ebed-445e-8507-
f9effb2de026') //the id of role{
return ['plugin' => 'CakeDC/Users', 'controller' => 'Users', 'action' => 'profile';
}
And it works. My URL redirect after login as a client is /profile.
Could someone help me to understand? Please tell me if it's not clear enough and if it's missing parts of codes that might be important to understand my problem.
I specify that I am beginner with Cake.
Your custom controller doesn't live in the CakeDC/Users plugin, hence you must disable the plugin key accordingly, so that the correct URL is being generated (assuming your routes are set up correctly) that connects to your controller, like this:
[
'plugin' => null,
'controller' => 'MyUsers',
'action' => 'index',
'_full' => true,
'prefix' => false
]
That would for example match the default fallback routes, generating a URL like /my-users.
See also:
Cookbook > Routing > Creating Links to Plugin Routes

cakePHP 3.0 Action PagesController::myaction.json() could not be found, or is not accessible."

I am migrating an existing 2.5 app over to 3.0. I am getting an 404 error when using ajax. This works fine in cakePHP 2.5
url: "/cakephp3/pages/myaction.json"
I don't see any step that I might have missed.
I am sure it is a routing issue with the .json extension
routes.php
Router::scope('/', function ($routes) {
Router::extensions(['json', 'xml']);
$routes->connect('/', ['controller' => 'Pages', 'action' => 'home']);
$routes->connect('/hotel-training-courses', ['controller' => 'pages', 'action' => 'trainingCourses']);
$routes->connect('/feature-tour', ['controller' => 'pages', 'action' => 'features']);
$routes->connect('/contact-us', ['controller' => 'pages', 'action' => 'contact']);
$routes->fallbacks('InflectedRoute');
});
PagesController.php
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
}
public function myaction(){
$this->request->onlyAllow('ajax');
$userName = $this->request->data['name'];
$userCompany = $this->request->data['company'];
$userEmail = $this->request->data['email'];
$userPhone = $this->request->data['phone'];
//send an email
}
The previous app was able to detect the request type and return with the same type. There was no need to set the render.
Global extensions must be defined outside of scopes
Router::extensions() must be placed outside of, and in case it should apply to all routes, invoked before defining any scopes and routes.
In case you want to restrict extension parsing to a specific scope, use RouteBuilder::extensions(), ie either
Router::extensions(['json', 'xml']);
Router::scope('/', function (RouteBuilder $routes) {
$routes->connect('/', ['controller' => 'Pages', 'action' => 'home']);
//...
});
or
Router::scope('/', function (RouteBuilder $routes) {
$routes->extensions(['json', 'xml']);
$routes->connect('/', ['controller' => 'Pages', 'action' => 'home']);
//...
});
See Cookbook > Routing > Routing File Extensions
Request::onlyAllow() doesn't exist anymore
Request::onlyAllow() has been renamed to Request::allowMethod(), so that's the next problem that you'll encouter.
See
Cookbook > 3.0 Migration Guide > Network > Request
\Cake\Network\Request::allowMethod()
Enable debug mode
Also you should enable debug mode so that you receive meaningful error messages with the appropriate details, necessary to debug such problems.

How to access plugin in cakephp

I am new in cakephp, I want to call the plugin via the URL. Here is URL of
http://testproject.local/PluginName/ControllerName/ActionName
When I Run this URL at that time I found "Missing Controller" error.
Missing Controller
Error: <ControllerName>Controller could not be found.
Error: Create the class <ControllerName>Controller below in file: `app/Controller/<ControllerName>Controller.php`
It's showing me
`Exception Attributes: array ( 'class' => 'PracticeFusionController', 'plugin' => NULL, )`
Here is my routes.php
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
/**
* ...and connect the rest of 'Pages' controller's urls.
*/
Router::connect('/Pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/gods/:action/*', array('plugin' => 'nova', 'controller' => 'gods'));
Router::connect('/gods', array('plugin' => 'nova', 'controller' => 'gods'));
Router::parseExtensions('json', 'xml');
Router::mapResources('events');
Router::connect('/<pluginName>', array('plugin' => '<pluginName>', 'controller' => '<ControllerName>'));
You can only load/open Plugin routes if you actually loaded the plugin in your project's bootstrap. You don't need to include a plugin route in your core app's routes.php. If you want to add plugin specific routes, you can load the plugin specific routes file, using the routes option. Note that by default all /plugin/controller/action routes are already routed properly, you don't need a separate routes file for that.
So, in your core app's app/Config/bootstrap.php, add:
CakePlugin::load('YourPlugin', array('routes' = true));
The routes from your plugin's Config/routes.php will then be loaded and can be used.
More details on this can also be found in the documentation.
If above solutions does not works, please load plugin like CakePlugin::load('YourPlugin', array('routes' => true)); Please note array passed is : array('routes' => true)

How can I create cached files within CakePHP Plugin?

I have created a plugin for CakePHP that I would like to generate cached files within its own plugin folder at /app/Plugin/MyPlugin/tmp/cache.
I have already cerated the MyPlugin/tmp/cache directory manually.
I have created a bootstrap file at /app/Plugin/MyPlugin/Config/bootstrap.php with the following content:
<?php
Cache::config('short', array(
'engine' => 'File',
'duration' => '+60 minutes',
'path' => 'Plugin/MyPlugin/tmp/cache',
'prefix' => 'cake_short_',
'mask' => 0666,
));
I have created a Shell script at /app/Plugin/MyPlugin/Console/Command/MyPluginShell.php with the following function:
<?php
...
public function get_listings() {
$listings = $this->Listing->find('all');
Cache::write('listings', $listings, 'short');
$this->out('Task Completed');
}
I can run get_listings from within the Cake console just fine and the Task completes, however there is no Cache file being created at /app/Plugin/MyPlugin/tmp/cache like I would expect.
On a side note, I have tried replacing 'path' => 'Plugin/MyPlugin/tmp/cache' with 'path' => CACHE just to see if it will appear in app/tmp/cache but haven't had any luck.
I have also created the /app/Plugin/MyPlugin/tmp/cache within the plugin.
Any help would be appreciated.
I figured it out.
I wasn't loading the plugin correctly within app/Config/bootstrap.php.
I was doing this (incorrect):
CakePlugin::load('MyPlugin', array('routes' => true));
Instead of this (correct):
CakePlugin::load('MyPlugin', array('routes' => true, 'bootstrap' => true));

CakePHP i18n/i10n Routing

Update:
I'm using a shared CakePHP lib across several apps (with all of them living in subdomains). They're not all nested the same; so, for example, on the filesystem I might have:
/foo
.htaccess
/1.0 (app)
/1.1 (app)
/1.2 (app)
...
/bar
.htaccess
/1.0 (app)
/1.1 (app)
/1.2 (app)
...
Where the .htaccess in each just defines which app is the default that requests are routed to within that subfolder, while all of them are still available by a direct url (eg /foo/1.0/...).
It seems that if I'm using the direct URL (eg not the .htaccess-rewritten one) it recognizes the routes appropriately, but if the URL is rewritten by .htaccess, it doesn't; it will invoke AppError::error404() with the ouput at the end of the question. This doesn't seem right to me... if anyone has any insight, that would be awesome.
Hey guys,
I'm using CakePHP 1.3 and having a routing issue. The gist of the concept is this:
I want to use 'en_us' style i18n/i10n, not simply 'en'
I'm not using built-in i18n because of requirements to have some languages display pages with localized views (views/:i18n/...) and others to common views with calls to __()
So, I have routes set up like so:
$sI18nFormat = '/[a-z]{2}_[a-z]{2}/';
Router::connect('/:i18n/:controller/:action',
array('controller' => ':controller', 'action' => ':action', 'i18n' => ':i18n'),
array('i18n' => $sI18nFormat));
Router::connect('/:i18n/:controller',
array('controller' => ':controller', 'action' => 'index', 'i18n' => ':i18n'),
array('i18n' => $sI18nFormat));
Router::connect('/:controller/:action',
array('controller' => ':controller', 'action' => ':action', 'i18n' => 'en_us'),
array('i18n' => $sI18nFormat));
Router::connect('/:controller',
array('controller' => ':controller', 'action' => 'index', 'i18n' => 'en_us'),
array('i18n' => $sI18nFormat));
where obviously the routes are mirrored except that one has a dynamic i18n parameter passed, and the other has a static one.
The problem comes with using certain values for :i18n - for example, en_us is okay, but fr_fr seems to have Cake looking for FrController (not FrFrController) - seemingly because it's trying to work some magic with a built-in i18n fr prefix.
As an example, here's what AppError::error404 is given:
Array
(
[className] => FrController
[webroot] => /path/to/webroot
[url] => _fr
[base] => /path/to/webroot
)
Is it possible to a) make Cake stop this so my routes work as expected, or b) tell Cake what format I want my i18n/i10n in so it doesn't try to do it its own way?
Any thoughts would be appreciated.
You should not (need to) delimit the Regex, and there should also be no need to populate the default parameter. Try this:
$sI18nFormat = '[a-z]{2}_[a-z]{2}';
Router::connect('/:i18n/:controller/:action', array(), array('i18n' => $sI18nFormat));
It's probably also failing because the URL does not match the full defined route. I.e., /fr_fr/foo will not match the above route, since it contains no :action. Try adding shorter variants as well:
Router::connect('/:i18n/:controller', array('action' => 'index'), array('i18n' => $sI18nFormat));
Router::connect('/:i18n', array('controller' => 'foo', 'action' => 'index'), array('i18n' => $sI18nFormat));
Have you looked at p28n? http://bakery.cakephp.org/articles/p0windah/2007/09/12/p28n-the-top-to-bottom-persistent-internationalization-tutorial
I found that it made the whole thing much less of a handful.

Resources