Overriding a Function?

James

Well-known member
I'm trying to override the actionPersonalDetailsSave() function to prevent saving if the gender had changed (basically preventing users from changing their gender).

I've tried something simple like:
PHP:
Class James_ControllerPublic_Account extends XFCP_James_ControllerPublic_Account
{
public function actionPersonalDetailsSave()
  {
$userId = XenForo_Visitor::getUserId();
$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
$writer->setExistingData($userId);
$writer->save();
      if ($writer->isChanged('gender')){
return $this->responseError("You cannot change your gender once it has been set!");
}
  }
}
But this doesn't work and throws this error:
The following error occurred:

No controller response from XenForo_ControllerPublic_Account::actionPersonalDetailsSave
  1. XenForo_FrontController->_handleControllerResponse() in XenForo/FrontController.php at line 318
  2. XenForo_FrontController->dispatch() in XenForo/FrontController.php at line 132
  3. XenForo_FrontController->run() in public_html/xen/index.php at line 13

Has anyone got any ideas?
 
It looks like it's failing because gender is not changed, and you have no controller response in that case.
 
Is it possible to use the same function name but only change part of the function?

I'll look into it some more and see if I can come up with anything.
 
I've been looking in XenForo_ControllerResponse_Error because I'm making use of responseError(), would I need to extend the ControllerResponse_Error for my own add-on or could I use XenForo's? I'm a little baffled at this bit.
 
What do you actually want to do?
I'm trying to override the actionPersonalDetailsSave() function to prevent saving if the gender had changed (basically preventing users from changing their gender).

I'm basically trying to allow gender selection at registration but prevent it from being edited on the personal details page.
 
Use this instead

Class James_ControllerPublic_Account extends XFCP_James_ControllerPublic_Account
{
public function actionPersonalDetailsSave()
{
$userId = XenForo_Visitor::getUserId();
$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
$writer->setExistingData($userId);
$writer->save();
if ($writer->isChanged('gender')){
return $this->responseError("You cannot change your gender once it has been set!");
}

return parent::actionPersonalDetailsSave();

}
}
 
Didn't throw an error on gender change, it just allowed it. It's probably my method rather than yours.
 
Your code isn't logical

$userId = XenForo_Visitor::getUserId();
$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
$writer->setExistingData($userId);
$writer->save();
if ($writer->isChanged('gender')){
return $this->responseError("You cannot change your gender once it has been set!");
}

You should check before the save if the gender is changed and not after the save, because here it will be too late
 
Hmm... maybe I'm not looking at this the right way. None of the below methods work:
Code:
public function actionPersonalDetailsSave()
	{
		$userId = XenForo_Visitor::getUserId();
		$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
		$writer->setExistingData($userId);
		$writer->preSave();
		if ($writer->isChanged('gender'))
		{
			return $this->responseError("You cannot change your gender once it has been set!");
		}	else	{
			$writer->save();
		}
		return parent::actionPersonalDetailsSave();
	
	}

Code:
public function actionPersonalDetailsSave()
	{
		$userId = XenForo_Visitor::getUserId();
		$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
		$writer->setExistingData($userId);
		if ($writer->isChanged('gender'))
		{
			return $this->responseError("You cannot change your gender once it has been set!");
		}	else	{
			$writer->save();
		}
		return parent::actionPersonalDetailsSave();
	
	}
 
What about this?
Code:
    protected function _saveVisitorSettings($settings, &$errors, $extras = array())
    {
        $writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
        $writer->setExistingData(XenForo_Visitor::getUserId());
        $writer->bulkSet($settings);
        
        if ($writer->isChanged('gender'))
        {
            return $this->responseError("You cannot change your gender once it has been set!");
        }
        
        return parent::_saveVisitorSettings( $settings, $errors, $extras );
    }
 
That throws an error:
Code:
PHP <br /> <b>Fatal error</b>: Call to undefined method XenForo_ControllerResponse_Error::getMergedData() in <b>/home/whyhq/data/www/whyhq.net/secret/library/XenForo/ControllerPublic/Account.php</b> on line <b>304</b><br />
 
you ve to overwrite _saveVisitorSettings function like that

PHP:
protected function _saveVisitorSettings($settings, &$errors, $extras = array())
{
$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
$writer->setExistingData(XenForo_Visitor::getUserId());
$writer->bulkSet($settings);

   if($writer->isChanged('gender'))
{
   throw new XenForo_Exception('You cannot change your gender once it has been set!', true);
}

if ($writer->isChanged('email')
&& XenForo_Application::get('options')->get('registrationSetup', 'emailConfirmation')
&& !$writer->get('is_moderator')
&& !$writer->get('is_admin')
)
{
switch ($writer->get('user_state'))
{
case 'moderated':
case 'email_confirm':
$writer->set('user_state', 'email_confirm');
break;

default:
$writer->set('user_state', 'email_confirm_edit');
}
}

foreach ($extras AS $methodName => $data)
{
if (method_exists($writer, $methodName))
{
call_user_func(array($writer, $methodName), $data);
}
}

$writer->preSave();

if ($dwErrors = $writer->getErrors())
{
$errors = (is_array($errors) ? $dwErrors + $errors : $dwErrors);
return false;
}

$writer->save();
return $writer;
}
 
It would probably make more sense to override the DataWriter preSave (or equivalent if it's private), then you can check if it's an update or an insert -- allow gender changes on insert but throw an error on update.

If you do it in the DataWriter you should then cover everywhere that attempts to change the user automagically.
 
The function above seems to work fine, if the gender is changed at all then it throws an error.

All I'm doing now is working on differentiating between a male/female gender and a male/female -> unspecified change.
 
Top Bottom