CakePhp and subdomain routing - cakephp

I'm trying to make subdomains working on my website, however, I still not able to generate links to subdomains...
I used the code I found in the net:
<?php
class SubdomainRoute extends CakeRoute {
public function match ($params) {
$subdomain = isset($params['subdomain']) ? $params['subdomain'] : null;
unset($params['subdomain']);
$path = parent::match($params);
if ($subdomain) {
$path = 'http://' . $subdomain . '.localhost' . $path;
}
return $path;
}
}
but it doesn't work for me. Anyone tried to find a solution and got one please? Thank you!

Better late than never I guess, but in order to use the above code you have to go to app/Config/routes.php and use the class:
App::uses('SubdomainRoute', 'Routing/Route');
As well as add it to your route:
Router::connect( '/:controller/:action/*',
[ 'controller' => 'test' ],
[ 'routeClass' => 'SubdomainRoute' ]
);
Hope this helps... someone :)

Related

how to configure routes for child controllers in CakePHP 3.x?

Reports has many ReportInstances
ReportInstances belongs to Reports
I would like to have the url /reports/:report-id/instances to point to the action index_by_report_id inside ReportInstancesController.php
How do I configure the routes.php accordingly?
UPDATE:
I tried nested resources as described here:
http://book.cakephp.org/3.0/en/development/routing.html#creating-nested-resource-routes
Here are my routes
$routes->resources('Reports', [
'map' => [
'standard' => [
'action' => 'standard',
'method' => 'GET',
]
]
]);
$routes->resources('Reports', function ($routes) {
$routes->resources('ReportInstances');
});
When I do a /reports/1/instances, it goes to ReportsController looking for action 1.
Please advise.
Do this in your routes.php
$routes->resources('Parents', function ($routes) {
$routes->resources('Children');
});
$routes->resources('Children');
In ChildrenController.php,
protected function _prepareConditions() {
$parentId = isset($this->request->params['parent_id']) ? $this->request->params['parent_id'] : null;
if ($parentId == null) {
return [];
}
return [
'Children.parent_id' => $parentId
];
}
public function index()
{
$conditions = $this->_prepareConditions();
$this->paginate = [
'contain' => ['Parents'],
'conditions' => $conditions
];
// ... and so on
You will be able to do the following:
/parents/1/children
/parents/1/children.json
/children
/children.json
Why this works?
http://book.cakephp.org/3.0/en/development/routing.html#creating-nested-resource-routes
tells us that basically to basically retrieve the parent id from the request params.
What it does not say explicitly is that, the routes will then reuse the basic 5 functions: index, add, view, delete, edit even when you nest them under a parent url.
Why do you still have a separate resources route for the Children?
This allows the /children and /children.json to work if you need them as well.
What about add?
I haven't tried that but I do not foresee any issues with using that as
/parents/1/children/add
/parents/1/children/add.json
/children/add
/children/add.json

CakePHP AMFPHP 2.1 vendor integration

I have problem with cakephp and amfphp 2.1 integration.
I made following controller:
class AmfController extends AppController
{
public function index(){
App::import('Vendor','Amfphp/index');
$this->autoRender = false;
}
public function backOffice(){
App::import('Vendor', 'backOffice', array('file' => 'BackOffice' . DS . 'ServiceBrowser.php'));
$this->autoRender = false;
}
}
Method index is working perfectly, cakephp is outputting amf entry point, but method backOffice is outputting following error:
Service call failed
object(CakeRequest) {
params => array(
[maximum depth reached]
)
data => array([maximum depth reached])
query => array([maximum depth reached])
url => 'amf/backOffice'
base => ''
webroot => '/'
here => '/amf/backOffice'
}
object(CakeResponse) {
}
Please help me, folder Amfphp and BackOffice are located in app/Vendor folder.
Here's a thought that might help: the service browser calls the entry point to get information about the various services, so that might create some bizarre side effects in CakePHP resulting in an infinite loop.
Other than that I don't know... If you still have trouble post back and I will give it a try.

CakePHP - Cannot redeclare class

I have a simple class that I've added to the components folder called mixpanel.php. Within the file is:
<?php
class MetricsTracker {
public $token;
public $host = 'http://api.mixpanel.com/';
public function __construct($token_string) {
$this->token = $token_string;
}
function track($event, $properties=array()) {
$params = array(
'event' => $event,
'properties' => $properties
);
if (!isset($params['properties']['token'])){
$params['properties']['token'] = $this->token;
}
$url = $this->host . 'track/?data=' . base64_encode(json_encode($params));
//you still need to run as a background process
exec("curl '" . $url . "' >/dev/null 2>&1 &");
}
}
?>
In users_controller.php I do:
require 'components/mixpanel.php';
however I'm getting an error:
Fatal error: Cannot redeclare class MetricsTracker in /Users/Hooman/Sites/askedout/app/controllers/components/mixpanel.php on line 11
Why is this happening? I do the same thing with a different php class and it works fine. This is very odd to me as I am not repeating the require definition anywhere. Please help, thanks.
In your component code, please change the code from
class MetricsTracker to
class MetricsTracker extends Object
In your controller code , please add the following code :
var $components=array('MetricsTracker');
instead of using require() function

Cakephp - how to make error pages have its own layouts?

I wanna have a different layout for the page not found 404 page. How can i set a different layout for that page?
Savant from the IRC helped me out and he suggest in using beforeRender(){} in the app_controller
// Before Render
function beforeRender() {
if($this->name == 'CakeError') {
//$this->layout = 'error';
}
}
CakeError is a catchAll for errors :D
In CakePHP 2.2.2 I changed the ExceptionRenderer in core.php with my own, like this:
app/Config/core.php:
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'MyExceptionRenderer', // this is ExceptionRenderer by default
'log' => true
));
app/Lib/Error/MyExceptionRenderer.php:
App::uses('ExceptionRenderer', 'Error');
class MyExceptionRenderer extends ExceptionRenderer {
protected function _outputMessage($template) {
$this->controller->layout = 'error';
parent::_outputMessage($template);
}
}
Just you need to make layout changes in your error400.ctp file under /app/View/Errors/error400.ctp
Open that file and set layout by
<?php $this->layout=''; //set your layout here ?>
better to create an error.php file in your app folder
class AppError extends ErrorHandler {
function error404($params) {
$this->controller->layout = 'error';
parent::error404($params);
}
}
so you can avoid the if-testing at EVERY page render that savants' solution introduces
My solution for CakePHP 2.3
Change the ExceptionRenderer in core.php to use your own renderer.
app/Config/core.php:
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'MyExceptionRenderer',
'log' => true
));
app/Lib/Error/MyExceptionRenderer.php:
App::uses('ExceptionRenderer', 'Error');
class MyExceptionRenderer extends ExceptionRenderer
{
/**
* Overrided, to always use a bare controller.
*
* #param Exception $exception The exception to get a controller for.
* #return Controller
*/
protected function _getController($exception) {
if (!$request = Router::getRequest(true)) {
$request = new CakeRequest();
}
$response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
$controller = new Controller($request, $response);
$controller->viewPath = 'Errors';
$controller->layout = 'error';
return $controller;
}
}
The advantage to this approach is that it ensures any exceptions thrown from AppController don't cause an endless loop when rendering the exception. Forces a basic rendering of the exception message every time.
This simplest way I know of is to create this function in your AppController:
function appError($method, $messages)
{
}
You can then do whatever you want with the error, display it however you like, or not display it at all, send an email etc.. (I'm not sure if this method if still valid.)
There is also an option of creating app_error.php in your app root, with class AppError extends ErrorHandler in it, which enables you to override all kinds of errors. But I haven't done this yet, so I can't tell you more about it.
See cake/libs/error.php and cake/libs/object.php and of course The Book for more info.
Edit: Forgot to mention, once you caught the error, there's nothing preventing you to - for example - store the error in session, redirect to your "error handling controller", and then display it in your controller however you want.

Use of requestAction in the ctp file and it turned out a blank page instead

I am using cakePHP 1.26.
The web page turned out blank when I tried to use requestAction to access a function in a COntroller from a .ctp.
Here is the code:
<?php
class TestingController extends AppController {
function hello($id=null){
$IfLoggedIn=$this->Session->check('user');
if($IfLoggedIn){
//search the database
//$result=doing something from the search results
$this->set('userInfo',$result);
return "2";
}
else if(!$IfLoggedIn && $id!=null){
return "1";
}
else if($id==null){
return "0";
}
}
}
and then in default.ctp file, I made use of the function defined above:
<?php
$u = $this->requestAction('/hello');
if($u=="2"){
echo "welcome back, my friend";
}
else{
echo "Hello World";
}
?>
But when I load a web page, it was blank page.
I have no idea what's wrong in the code.
Try to add
$u = $this->requestAction('/hello', array('return'=>true));
Check this
You might try including the controller in the url param of requestAction.
If you spend more time debugging and reading the manual, you'll learn more, more quickly.
I'm new to Cakephp myself, I'm using 2.0 which may be different in your version of Cake.
I found that the following code from the manual was wrong for me:
<?php
class PostsController extends AppController {
// ...
function index() {
$posts = $this->paginate();
if ($this->request->is('requested')) {
return $posts;
} else {
$this->set('posts', $posts);
}
}
}
You need a slight modification (seems the manual was wrong in this case). The following code worked for me:
<?php
class PostsController extends AppController {
// ...
function index() {
$posts = $this->paginate();
if ( !empty($this->request->params['requested']) ) { // line here is different
return $posts;
} else {
$this->set('posts', $posts);
}
}
}
We shouldn't be checking for the request HTTP verb, we should be checking if the request parameter is true.
Here's another relevant link to the manual about request parameters: http://book.cakephp.org/2.0/en/controllers/request-response.html#accessing-request-parameters
Hope that helps.

Resources