• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Overriding a Function?

James

Well-known member
#1
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?
 

Kier

XenForo Developer
Staff member
#2
It looks like it's failing because gender is not changed, and you have no controller response in that case.
 

James

Well-known member
#3
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.
 

James

Well-known member
#4
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.
 

James

Well-known member
#6
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.
 

Rigel Kentaurus

Well-known member
#7
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();

}
}
 
R

ragtek

Guest
#12
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
 

James

Well-known member
#13
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();
	
	}
 
#14
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 );
    }
 

James

Well-known member
#16
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 />
 

Tilkißey

Well-known member
#17
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;
}
 

SheepCow

Well-known member
#18
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.
 

James

Well-known member
#19
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.