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

Extending ControllerPublic

silence

Well-known member
#1
I'm trying to extend XenForo_ControllerPublic_Account but when I do, it won't let me access my control panel (usercp) and gives me this error:
Code:
 The controller XenForo_ControllerPublic_Account does not define an action called PersonalDetails.
Here is my listener that I am loading the class controller with:
PHP:
    public static function loadClassController($class, array &$extend)
    {
        switch($class)
        {
            case 'XenForo_ControllerPublic_Account':
                $extend[] = 'Test_ControllerPublic_Account';
                break;
        }
    }
Here is the controller public:
Code:
class Test_ControllerPublic_Account extends XenForo_ControllerPublic_Abstract
{
    public function actionIndex()
    {
        return;
    }
}
What can I do to fix this?

Thanks!
 

tyteen4a03

Well-known member
#2
I'm trying to extend XenForo_ControllerPublic_Account but when I do, it won't let me access my control panel (usercp) and gives me this error:
Code:
 The controller XenForo_ControllerPublic_Account does not define an action called PersonalDetails.
Here is my listener that I am loading the class controller with:
PHP:
    public static function loadClassController($class, array &$extend)
    {
        switch($class)
        {
            case 'XenForo_ControllerPublic_Account':
                $extend[] = 'Test_ControllerPublic_Account';
                break;
        }
    }
Here is the controller public:
Code:
class Test_ControllerPublic_Account extends XenForo_ControllerPublic_Abstract
{
    public function actionIndex()
    {
        return;
    }
}
What can I do to fix this?

Thanks!
You are directly extending XenForo_ControllerPublic_Abstract. Don't do that.

Instead, use a proxy class: class Test_ControllerPublic_Account extends XFCP_Test_ControllerPublic_Account.
 

silence

Well-known member
#3
You are directly extending XenForo_ControllerPublic_Abstract. Don't do that.

Instead, use a proxy class: class Test_ControllerPublic_Account extends XFCP_Test_ControllerPublic_Account.
Alright it's just a crap load of other plugins do it so I assumed that the abtract way was the norm.
 

silence

Well-known member
#6
If you are extending an existing class, you must use the XFCP_ prefix so you don't override other addon's functionality.
One more question. I'm adding a custom page to the user control panel. I got the tab to display and the page itself, but how can I get the sidebar to display?
 

tyteen4a03

Well-known member
#7
One more question. I'm adding a custom page to the user control panel. I got the tab to display and the page itself, but how can I get the sidebar to display?
I suppose the change will be similar to that of the help page, so I'll just show you how I did it for the help sidebar:
Template: help_links_wrapper
Code:
<li><a href="{xen:link 'help/coppa-policy'}" class="{xen:if "{$selected} == 'coppaPolicy'", 'secondaryContent', 'primaryContent'}">COPPA Policy</a></li>
 

silence

Well-known member
#8
I found a better way:

PHP:
        return $this->_getWrapper(
            'testuserid',
            'test',
            $this->responseView('XenForo_ViewPublic_Account_Test', 'account_test', $viewParams)
        );
 

silence

Well-known member
#9
I suppose the change will be similar to that of the help page, so I'll just show you how I did it for the help sidebar:
Template: help_links_wrapper
Code:
<li><a href="{xen:link 'help/coppa-policy'}" class="{xen:if "{$selected} == 'coppaPolicy'", 'secondaryContent', 'primaryContent'}">COPPA Policy</a></li>
Alright another question for ya:

This is in my model:
PHP:
    public function verifyUserID($input)
    {
        $errors = array();

        $result = $this->_getDb()->fetchRow('SELECT test_userid FROM xf_user_profile WHERE test_userid = ?', $input);
        if (empty($result))
        {
            return true;
        }
        else
        {
            $errors = "That UserID is currently in use! Please try another!";
            return $this->responseError($errors);
        }
However, when it hit's the responseError I get this error in javascript and it won't continue:
Code:
PHP Fatal error: Call to undefined method Test_Model_Query::responseError() in /xxxxxx/xenforo/library/Test/Model/Query.php on line 28
 

tyteen4a03

Well-known member
#10
Alright another question for ya:

This is in my model:
PHP:
    public function verifyUserID($input)
    {
        $errors = array();

        $result = $this->_getDb()->fetchRow('SELECT test_userid FROM xf_user_profile WHERE test_userid = ?', $input);
        if (empty($result))
        {
            return true;
        }
        else
        {
            $errors = "That UserID is currently in use! Please try another!";
            return $this->responseError($errors);
        }
However, when it hit's the responseError I get this error in javascript and it won't continue:
Code:
PHP Fatal error: Call to undefined method Test_Model_Query::responseError() in /xxxxxx/xenforo/library/Test/Model/Query.php on line 28
Why are you handling errors in Models? That is a job for controllers. (and because of this, Models does not have responseExceptions defined. Also use throw, not return, when doing errors.)
 

silence

Well-known member
#11
Why are you handling errors in Models? That is a job for controllers. (and because of this, Models does not have responseExceptions defined. Also use throw, not return, when doing errors.)
Ok but if I move the error checking to controllerpublic I still get the same error D:
 

silence

Well-known member
#13
What is your ControllerPublic code?
Nevermind I got it worked out but one more error :(
I'm getting:
The existing data required by the data writer could not be found.

Here is my controllerpublic:
PHP:
    public function actionTestUpdate()
    {
        $visitor = XenForo_Visitor::getInstance();

        // parse input parameters
        $input = $this->getInput();
        $testuserid_input = $input->filterSingle('auth_id', XenForo_Input::STRING);
        $duplicate = $this->_getAccountModel()->verifyUserID($testuserid_input);
        if (empty($duplicate))
        {
            $dwAccount = XenForo_DataWriter::create('Test_DataWriter_Account');
            $dwAccount->setExistingData($testuserid_input);
            $index = array(
                        'user_id' => $visitor['user_id'],
                        'auth_id' => $testuserid_input
            );
            $dwAccount->bulkSet($index);
            $dwAccount->save();
            return $this->responseRedirect(
                XenForo_ControllerResponse_Redirect::SUCCESS,
                XenForo_Link::buildPublicLink('account/Test')
            );
        }
        else
        {
            return $this->responseError("That UserID is currently in use! Please try another!");
        }
    }
and here is my datawriter:
PHP:
<?php
class Test_DataWriter_Account extends XenForo_DataWriter
{
    /**
    * Gets the fields that are defined for the table. See parent for explanation.
    *
    * @return array
    */
    protected function _getFields()
    {
        return array(
            'xf_test' => array(
                'user_id'    => array(
                    'type' => self::TYPE_UINT
                ),
                'auth_id'    => array(
                    'type' => self::TYPE_STRING, 'required' => true
                ),
            )
        );
    }

    /**
    * Gets the actual existing data out of data that was passed in. See parent for explanation.
    *
    * @param mixed
    *
      * @see XenForo_DataWriter::_getExistingData()
      *
      * @return array|false
    */
    protected function _getExistingData($data)
    {
        if (!$id = $this->_getExistingPrimaryKey($data, 'auth_id'))
        {
            return false;
        }
   
        return array('xf_test' => $this->_getAccountModel()->getTestUserID($id));
    }
    /**
    * Gets SQL condition to update the existing record.
    *
    * @see XenForo_DataWriter::_getUpdateCondition()
    *
    * @return string
    */
    protected function _getUpdateCondition($tableName)
    {
        return 'user_id = ' . $this->_db->quote($this->getExisting('user_id'));
    }
    /**
    * Get the simple text model.
    *
    * @return SimpleText_Model_SimpleText
    */
    protected function _getAccountModel()
    {
        return $this->getModelFromCache('Test_Model_Account');
    }
}
?>
I've looked everywhere but nobody has seemed to have this issue and I dunno what's causing it D:
 

silence

Well-known member
#15
PHP:
<?php

class Test_Model_Account extends XenForo_Model
{
    public function getTestUserID($user_id)
    {
        $user_id = $this->_getDb()->fetchRow('SELECT auth_id FROM xf_test WHERE user_id = ?', $user_id);
        if (!empty($user_id))
        {
            $string = reset($user_id);
            if ($string == '0') { $string = 'None'; }
            return $string;
        }
        return 'None';
    }
    public function verifyUserID($input)
    {
        return $this->_getDb()->fetchRow('SELECT auth_id FROM xf_test WHERE auth_id = ?', $input);
    }
}
What is your Test_Model_Account?
 

silence

Well-known member
#17
I just noticed you did not define a primary key in your fields. To define one, add 'autoIncrement' => true to that entry.
Yeah but I'm grabbing their user_id and adding it to that, I was under the assumption that autoIncrement just fills it in automatically D;
 

silence

Well-known member
#19
They are separate tables.
So like this?:
PHP:
    protected function _getFields()
    {
        return array(
            'xf_test' => array(
                'user_id'    => array(
                    'type' => self::TYPE_UINT, 'autoIncrement' => true
                ),
                'auth_id'    => array(
                    'type' => self::TYPE_STRING, 'required' => true
                ),
            )
        );
    }
Because that doesn't seem to fix it. Do I have to enable AI for user_id in the table as well?
 

tyteen4a03

Well-known member
#20
So like this?:
PHP:
    protected function _getFields()
    {
        return array(
            'xf_test' => array(
                'user_id'    => array(
                    'type' => self::TYPE_UINT, 'autoIncrement' => true
                ),
                'auth_id'    => array(
                    'type' => self::TYPE_STRING, 'required' => true
                ),
            )
        );
    }
Because that doesn't seem to fix it. Do I have to enable AI for user_id in the table as well?
I think yes, you also need to make that field your primary key (but doesn't need AI if you're inserting from another table).

Also, I suppose $testuserid_input's value is correct?