cakephp routing - pages_controller/home.ctp error only on debug=0 - cakephp

When core.php debug is set at 1 or 2 and I browse to the root of my cakephp site I get expected result, the page served is correct, ie, PagesController default() action -> home.ctp
However if I change debug to 0 I get the the following error:
Error: The requested address '/' was
not found on this server.
My router.php file contains:
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'));
I have tried deleting all cache files and removing CAKE cookies, and other actions work as expected when visited directly, eg, /user, /groups, etc. Problem only occurs when hitting the root '/'.
I am using cakephp 1.3.4 and ACL + Auth.
Edit ** I'm including the code for the default() function from pages_controller.php
/**
* Displays a view
*
* #param mixed What page to display
* #access public
*/
function display() {
$path = func_get_args();
$count = count($path);
if (!$count) {
$this->redirect('/');
}
$page = $subpage = $title_for_layout = null;
if (!empty($path[0])) {
$page = $path[0];
}
if (!empty($path[1])) {
$subpage = $path[1];
}
if (!empty($path[$count - 1])) {
$title_for_layout = Inflector::humanize($path[$count - 1]);
}
$this->set(compact('page', 'subpage', 'title_for_layout'));
$this->render(implode('/', $path));
}

OK the answer is so simple it is embarassing: in home.ctp there is the following code:
if (Configure::read() == 0):
$this->cakeError('error404');
endif;
Configure::read() by default read var debug - therefore it throws this error if debug is set to 0.
Thanks to Benjamin for putting me on the right track. Cake is wonderful and at the same time infuriating until you know the basics!

imho this behavior makes sense, as you turn debug to 0 if your app goes into production (something tells me, that you don't want to show the home page as your entry page). The home.ctp which is displayed by the pages controller lives in
./cake/libs/view/pages/home.ctp
of your installation. But if you are in production you want to display the static pages from the
./app/views/pages
directory, which is the task of the pages controller. This directory is empty in a fresh cake installation.

I would like to update code for cakephp version 2.4.3.
as on cakephp version above code is replaced with
if (!Configure::read('debug')):
throw new NotFoundException();
endif;
as when debug is set to '0' it throws exception. you can use below code to make it run properly:
if ((Configure::read('debug')==='')):
throw new NotFoundException();
endif;

Related

Cakephp Error: An internal error has occurred

I have some code in cakephp which produces an error.
Here is the PHP Controller:
$this->loadModel( 'Vote' ); //Newly added by amit start
$vote=$this->Vote->getVote($id,$uid);
$this->set('vote',$vote);
$voteCount = count($vote);
$this->set('voteCount',$voteCount);
$voteShow = $this->Vote->find('all', array(
'fields' => array('SUM(Vote.score) AS score','count(id) as countId'),
'conditions'=>array('Vote.type_id'=>$id),
));
$this->set('voteShow',$voteShow);
model:
public function getVote($id,$uid) {
if (empty($conditions))
$conditions = array('Vote.type' => 'blog',
'Vote.type_id' => $id,
'Vote.user_id' => $uid);
$users = $this->find('all', array('conditions' => $conditions,
'order' => 'Vote.id desc'
));
return $users;
}
That code produces this error:
Error : An internal error has occurred
What does this error mean?
I enabled debug mode: Configure::write('debug', 2); in core.php and it solved my problem.
In my case debug mode was
Configure::write('debug', 0); on live server in core.php.
I set it to Configure::write('debug', 1); and no error was shown this time.
So I again changed my debug mode to Configure::write('debug', 0); because I don't want to show debug error on my live site.
This time no error message shows up.
So just changing the debug mode once in core.php get rid of this error in my case.
If you change your debug mode to 1 and then run those functions which you have changed on local, CakePHP will refresh the cache for all those models which include in those functions. Now you can change back to Configure::write('debug', 0).
Do NOT set Configure::write('debug',2) in production, or you could end up writing sensitive data (such as Query) to user when there will be an error, the reason why debug 2 works is because items in the CACHE are not taken in consideration anymore, so it works. Just delete the cache and leave DEBUG to 0 in production VERY IMPORTANT
Cache can be found here: tmp/cache/
Then again, do NOT delete the 3 folder you'll find there, just delete their content.

Facebook Logout / CakePHP Plugin

In in the CakePHP SDK for Facebook, the following code is provided for logging out:
<?php echo $this->Facebook->logout(array('redirect'=>array('controller'=>'users','action'=>'logout'))); ?>
This codes doesn't seem to work, as the API seems to have changed to now use "next" as opposed to redirect. So the above code doesn't produce a logout button; just a link;
The following code produces a logout button, but doesn't actually redirect:
<?php echo $this->Facebook->logout(array('next'=>array('controller'=>'users','action'=>'logout'))); ?>
Any idea what needs to be done to address this problem?
Try this
$params = array( 'next' => 'https://www.myapp.com/after_logout' );
$facebook->getLogoutUrl($params); // $params is optional.
Source: http://developers.facebook.com/docs/reference/php/facebook-getLogoutUrl/

CakeDC User Plugin - Is there Documentation Anywhere?

Browsing through GitHub and I found a pretty powerful CakePHP plugin called CakeDC Users that has a lot of features (Account verification, password reset, etc) for a creating a login/authentication system. I like it because it seems to be written by some of the actual CakePHP developers and it gets updated a lot but there seems to be absolutely zero documentation anywhere on it. I've just come across this plugin recently, since I was trying to see if there's a better way than "rolling" with my own solution. So I was wondering if anybody here has had experience with it and if so could point to some decent documentation online.
Edit There is some stuff at the bottom of the readme, but it hasn't been too intuitive for me.
Alternate question, if you don't use this plugin, is there a login/authentication plugin you use in CakePHP that you use for login/authentication?
I have ran into the same problem with using the CakeDC plugins, a lot of them have little/no documentation.
However, there is not "Zero" documentation for it, you can see how to set it up for the most part at the bottom of the github page in the read me. Also you need to put this inside your AppController::beforeFilter() method.
$this->Auth->authorize = 'controller';
$this->Auth->fields = array('username' => 'email', 'password' => 'passwd');
$this->Auth->loginAction = array('plugin' => 'users', 'controller' => 'users', 'action' => 'login', 'admin' => false);
$this->Auth->loginRedirect = '/';
$this->Auth->logoutRedirect = '/';
$this->Auth->authError = __('Sorry, but you need to login to access this location.', true);
$this->Auth->loginError = __('Invalid e-mail / password
combination. Please try again', true);
$this->Auth->autoRedirect = true;
$this->Auth->userModel = 'User';
$this->Auth->userScope = array('User.active' => 1);
if ($this->Auth->user()) {
$this->set('userData', $this->Auth->user());
$this->set('isAuthorized', ($this->Auth->user('id') != ''));
}
Also, you need an isAuthorized() function, something as simple as this will do:
public function isAuthorized() {
return true;
}
Additionally, you will need to allow the 'login' action (this will involve editing the plugin files). Just add 'login' to the $this->Auth->allow() in users_controller.php.
This question is pretty old now, but as it's not marked as resolved and we've been doing a lot on the documentation since then I think it's worth to update:
Documentation can be found here:
For the version 3+ of the framework
https://github.com/CakeDC/users/blob/master/Docs/Home.md
Tutorial > http://www.cakedc.com/jorge_gonzalez/2016/02/21/cakedc_users_plugin_for_cakephp_3_-_update
CakePHP Facebook login tutorial >
http://www.cakedc.com/jorge_gonzalez/2016/02/21/cakephp_facebook_login_using_cakedc_users_plugin_-_update_3_1_5
For the (old) version 2
https://github.com/CakeDC/users/blob/2.x/Docs/Home.md
After exhaustive search I found a tutorial on how to use CakeDC!
Here it is

Outputting a hyperlink from a controller in cakePHP

I'm just getting started with cakePHP, and things aren't going so well so far.
I have a controller that handles confirming user emails. On registration the user is sent an email with a confirmcode in a link. Depending on the confirm code they give, the controller gives different text responses. One of these responses includes a hyperlink in order to log in.
I'm trying to use the Html helper, but although I've loaded it in $helpers at the top of the class, I an only make it work if I then use App::import, and then instantiate it.
It all seems overkill to simply make a hyperlink! How many times do I have to load the same class?
Wherever I look on the web it keeps telling me it's a bad idea to use a helper in a controller, but how else am I supposed to get the link made?
So I have
var $helpers = array('Html');
at the top of the controller, and:
if (isset($this->User->id)) { // Check the user's entered it right
// Do some stuff to remember the user has confirmed
// This is to load the html helper - supposedly bad form, but how else do I make the link?
App::import('Helper', 'Html');
$html = new HtmlHelper();
$this->set('message', __("Your email address has been confirmed.", TRUE)." ".$html->link(__("Please log in", TRUE), array('controller' => "users", 'action' => "login" )));
} else {
$this->set('message', __("Please check your mail for the correct URL to confirm your account", TRUE));
}
in the controller's confirm method and
<div>
<?php echo $message;?>
</div>
in the view to output the resulting message
Surely I'm going wrong somewhere - can anyone explain how?
You're not supposed to use Helpers in the Controller. As #Lincoln pointed out, you should construct the link in the View. You may construct the URL in the Controller, since a URL is basically data, but a link is a very medium-specific (HTML) implementation of a URL.
Either way, you'll need to create a full URL (including host) if you want to send it in an Email. The most universal way is to use Router::url:
$fullUrl = Router::url(array('controller' => ...), true); // 'true' for full URL
Do this in either the Controller or the View. For creating a link, use this in the View:
echo $html->link('Title', $fullUrl);
The idea is that all the data you need to render the page is sent to the view with set, then any conditional logic or formatting is done in the view with helpers, so send whole query results when appropriate (suppose you need to alter a link to include the user's screen name, you'll have it handy).
in controller action
$this->set('user', $this->User);
in view (this is slightly different depending on if your in <= 1.2 or 1.3
if ($user->id) //available because of Controller->set
{
//1.2
$link = $html->link(__("Please log in", TRUE), array('controller' => "users", 'action' => "login" ));
//1.3
$link = $this->Html->link(__("Please log in", TRUE), array('controller' => "users", 'action' => "login" ));
echo __("Your email address has been confirmed.", TRUE)." $link";
}
else
{
$this->set('message', __("Please check your mail for the correct URL to confirm your account", TRUE));
}
What you are trying to do should be done with the SessionComponent. $this->Session->setFlash('your message here');
and in your layout with the session helper put $this->Session->flash();
About your wanting urls in the controller, Router::url is correct as deceze said, but there is no use for it there as you should not be building html in a controller.
what you want to do it use the session::setFlash() method above and then redirect them using
$this->redirect(array('controller' => "users", 'action' => "login" ));

CakePhp - render a view + afterFilter

The problem is i want to call the index function, i need it to render the view and then the
afterFilter to redirect again to the index function and do the same.. Like a loop, the problem is it doesnt render it, ive tried using $this->render('index') but it doesnt work and also other things..
PS: I didnt include all the code that i have in index, because its pointless, doesnt render with or without it, just included the things i needed for the view.
function afterFilter()
{
if ($this->params['action'] == 'index')
{
sleep(3);
$this->redirect(array('action'=>'index',$id), null, true);
}
}
THE FUNCTION
function index($ido = 0)
{
$this->set('Operator', $this->Operator->read(null, $ido));
$this->set('ido', $ido);
}
THE VIEW = INDEX.CTP
<legend>Operator StandBy Window</legend>
<?php
?>
</fieldset>
<?php echo $html->link('LogIn', array('controller' => 'operators', 'action' => 'add')); ?>
<?php echo $html->link('LogOut', array('controller' => 'operators', 'action' => 'logout',$ido)); ?>
a function that constantly checks my database for a change, if a change occurs ill redirect, if not i need to have that constant loop of 'checking the database' and 'rendering the view'.
This is not possible entirely on the server with PHP, and especially not with CakePHP's template system. PHP just "makes pages" on the server and sends them to the browser and a linear fashion. If you loop on the server, the content of your page will just repeat itself:
Normal content
Normal content
Normal content
<redirect>
To redirect the client, you need to output headers. The headers need to be output before anything else. If you've already looped a few times and content has already been sent to the client, you can't redirect anymore.
There are two ways:
You just output one page at a time showing the current status, with a meta tag that'll refresh the page every x seconds. This can be rather expensive and annoying though.
Use AJAX and possibly Comet to update the information on the page dynamically in the browser.

Resources