CakePHP 1.3.8 - Editing user info causes 404

Hello Group,

I am new to this group and CakePHP.

I am dealing with a site that is build using CakePHP version 1.3.8. When adding a new user, everything works fine. When modifying a user (either through admin’s account or through the user’s account) the save function keeps the URL of the page (with client ID in url as it should) but the page doesn’t add the updated data to the database, and gives a 404 page. When the URL is copied and entered again in browser the User’s page appears, but like I mentioned no changes to the User’s information was recorded. See the start and end of the form functions, there are a lot of fields in this form.

I was told that this form was working properly a couple months ago (I just recently have been looking into this issue), and then one day the saving of the form stopped.

For example:
When I am logged in as an administrator and go view all users (/admin/admin/view_all_users) and I click to edit user ID=“305880” (/admin/admin/user_edit/305880), after making changes to the form I click save (Enregistrer) and the URL I come back to is the same (/admin/admin/user_edit/305880) but displays a 404 page. I can then copy the URL into another tab and the page loads (without any changes saved).

So I’ve been digging through the CakePHP files for the past couple days and I must say it’s a bit overwhelming with what seems like duplicate files/functions in similar filenames with a Postfix of “_bu” (maybe because of the way the original developer built it).

Anyways, what I found is the following, please let me know if I am even looking in the right spot…
So as I posted yesterday, the form is in app/views/admin/admin_user_edit.php
`<?php echo $this->Form->create("User", array("url" => array("controller" => "admin", "action" => $this->params["action"]))); ?>
There are many fields > echo $this->Form->input("…");, etc…

<?php echo $this->Form->end("Enregistrer"); ?>`

I did also find a function in app/controllers/admin_controller.php
`function admin_user_edit($id = NULL){
$new_user = false;
if (!$id){
$new_user = true;
}

	if (!empty($this->data)){
		
		//print_r($this->data);
		$this->_uz_remove_data_not_to_be_saved("UserAddress");
		$this->_uz_remove_data_not_to_be_saved("UserPhone");
		$this->_uz_remove_data_not_to_be_saved("UserEmail");
		$this->_uz_remove_data_not_to_be_saved("UserLink");
		$this->_uz_remove_data_not_to_be_saved("UserContact");
					
		//print_r($this->data);
		//special for new user
		if ($new_user){
			$this->User->save($this->data, array("validate" => false));
			$id = $this->User->id;
			$this->data['User']['user_id'] = $id;
		}
		
	
		//pr($this->data);			
		
		//validate password
		if (!empty($this->data['User']['password']) && !empty($this->data['User']['confirm_password'])){
			if ($this->data['User']['confirm_password'] == $this->data['User']['password']){
				
			}
			else {
				unset($this->data['User']['password']);
				unset($this->data['User']['confirm_password']);
			}
		}
		else {
			unset($this->data['User']['password']);
			unset($this->data['User']['confirm_password']);
		}
		
		if (!empty($this->data['ExpertisesUser']['expertise_id'])){
			$all_eus = $this->data['ExpertisesUser']['expertise_id'];
			unset($this->data['ExpertisesUser']);
			foreach ($all_eus as $k => $v){
				unset($temp);
				$temp['user_id'] = $this->data['User']['user_id'];
				$temp['expertise_id'] = $v;
				$this->data['ExpertisesUser'][] = $temp;
			}
		}
		else {
			unset($this->data['ExpertisesUser']);
		}
		
		if (!empty($this->data['UserCircusField']['circus_field_id'])){
			$all_eus = $this->data['UserCircusField']['circus_field_id'];
			unset($this->data['UserCircusField']);
			foreach ($all_eus as $k => $v){
				unset($temp);
				$temp['user_id'] = $this->data['User']['user_id'];
				$temp['circus_field_id'] = $v;
				$this->data['UserCircusField'][] = $temp;
			}
		}
		else {
			unset($this->data['UserCircusField']);
		}
		
		//delete previous circus fields and expertises first
		if (!$new_user){
			$this->loadModel("UserCircusField");
			$this->loadModel("ExpertisesUser");
			$this->UserCircusField->deleteAll(array("UserCircusField.user_id" => $this->data['User']['user_id']), false);
			$this->ExpertisesUser->deleteAll(array("ExpertisesUser.user_id" => $this->data['User']['user_id']), false);
		}
							

		$this->loadModel("UserProfile");
		unset($this->UserProfile->validate);
	
		if ($this->User->saveAll($this->data)){
			if ($new_user){
				$redirect = array("action" => "new_user_order_creation", $this->data['User']['user_id']);
			}
			else {
				$redirect = array("action" => "user_edit", $this->data['User']['user_id']);
			}
			$this->Session->setFlash("Utilisateur enregistré !", "fs");
			$this->redirect($redirect);
		}
		else {
			if ($new_user){
				$this->User->delete($this->data['User']['user_id']);
				unset($this->data['User']['user_id']);
			}
			$this->Session->setFlash("Utilisateur non enregistré. Vérifiez les erreurs ci-dessous.", "fe");
		}
	}
	
	else {
		//new user/////////////
		if ($new_user){
			$this->loadModel("UserProfile");
			$max_member_number_temp = $this->UserProfile->find('first', array("recursive" => -1, "order" => "UserProfile.member_number DESC", "limit" => 1));
			$this->data['UserProfile']['member_number'] = $max_member_number_temp['UserProfile']['member_number'] + 1;
			$this->data['UserProfile']['member_since'] = date("Y-m-d");
			$this->data['UserProfile']['membership_expiry'] = date("Y-m-d", strtotime("+ 1 year"));
			$this->set('crumb', array("Utilisateurs" => array("action" => "view_all_users"), "Nouvel utilisateur" => array()));
		}
		
		//edit user/////////////
		else {
			$this->data = $this->User->find('first', array('conditions' => array("User.user_id" => $id)));
			$this->set('crumb', array("Utilisateurs" => array("action" => "view_all_users"), "# " . $id => array("action" => "user_edit11", $id)));
		}
	}
	
	$this->_get_countries();
	$this->_get_regions();
	$this->_get_companies();
	$this->_get_main_activity_fields();
	$this->_get_expertises();
	$this->_get_circus_fields();
	$this->_get_membertypes();
	
}`

If I am not in the right place, please let me know where I should be looking for the user_edit function. NOTE, the same issue happens for users (non admin) when they edit their profile or other info. Add works, edit does not… so I’m a little lost :slight_smile:

Any help is greatly appreciated. I can also send snippets of code if need be.

Thank you in advance!
josh

This is a response to Josh Rs request for help, posted to the CakePHP Google Group. Somewhere between his last post, and my response, the forum was made read only. So I’m posting it here, in the hope he’ll see it.

The original post was here [https://groups.google.com/forum/#!topic/cake-php/UJEWOQCvFhE]


Hi Josh

I couldn’t see a similar topic on discourse.cakephp, so I’ll reply here [Edit: now here is gone, and we’re at discourse anyway]

It’s been a while since I’ve worked with CakePHP 1.x, so nothing in particular is jumping out at me as being the cause for the 404. However, here are some pointers:

When the new user gets created, before the save() call, do a create(). i.e. $this->User->create(); This makes sure that any data set on the User model is cleared, and doesn’t interfere with the save. Not having it “shouldn’t” cause the 404.

Not sure if it’s a change from Steven Ybarra, but it looks like validation is being suppressed on save, for the the create. Ideally, you should allow the validation, and check the results of the save before continuing. If the save fails, then let the page be rendered, and if CakePHP Forms and Inputs are being used, then validation errors should show.

i.e.

$continueProcessing = true;
if ($new_user) {
    $this->User->create();
    if ($this->User->save($this->data)) {
        $id = $this->User->id;
    $this->data['User']['user_id'] = $id;
    } else {
        $continueProcessing = false;
    }
}

if ($continueProcessing) {
   // most remaining code
}

// $this->_get_*() calls here so they get called regardless, or your lists won't populate on error

The next thing you might want to do is turn up debugging, to help solve the issue. Sometimes CakePHP will mask an error behind a CakePHP generated 404 (rather than a genuine web server based 404). In the core.php, there will be a debug variable. Set this to 2 (don’t forget to change it back when you’re all done), and try the operation again. You should get increased debugging, and this might reveal the issue. Also check the tmp/logs/debug.log file and perhaps errors.log.

I’m not sure that the highlighted redirect is causing the issue. If you’re not getting any data saved, then the saveAll will return false, and you’ve never get to the redirect.

I don’t think I’ve used the crumb option before, but please double check the last $this->set('crumb', ...) for the posted code. You have a ‘#’ concatenating to an array expression (i.e. '#' . $id => ()). It doesn’t look right, and the value of the action seems a little hinky if it’s supposed to match the PHP action. Though if it’s a special Ajax provision, then this might be okay.

With regards to the highlighted redirect code, it “should” be okay. When $this->redirect() is called, CakePHP should default the control, and recognize that it’s in an admin prefix, to produce the correct URL. Again, use the Network table in Chrome to check if the 404 is a web server based 404 (Apache, nginx or IIS), or a CakePHP generated 404. If that gets you no where, perhaps try an IDE (like PHPStorm or Eclipse PDT) that can hook into xdebug for some interactive debugging, and step through the execution of the action. You could also try uncommenting some of those debugging statements, or use good old error_log('Here' . print_r($this->data, true)); to output to the error log (marginally better than a plain print_r(), but worse than using proper CakePHP debugging and DebugKit.

I’m hoping there’s something in there that will cast a light on the underlying cause.

Regards
Reuben Helms