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

Extending ControllerPublic

Discussion in 'XenForo Development Discussions' started by silence, Jun 18, 2013.

  1. silence

    silence Well-Known Member

    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!
     
  2. tyteen4a03

    tyteen4a03 Well-Known Member

    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.
     
    Chris D and silence like this.
  3. silence

    silence Well-Known Member

    Alright it's just a crap load of other plugins do it so I assumed that the abtract way was the norm.
     
  4. tyteen4a03

    tyteen4a03 Well-Known Member

    If you are extending an existing class, you must use the XFCP_ prefix so you don't override other addon's functionality.
     
  5. silence

    silence Well-Known Member

    Ah kk. Alright thanks matey!
     
    tyteen4a03 likes this.
  6. silence

    silence Well-Known Member

    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?
     
  7. tyteen4a03

    tyteen4a03 Well-Known Member

    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>
     
  8. silence

    silence Well-Known Member

    I found a better way:

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

    silence Well-Known Member

    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
     
  10. tyteen4a03

    tyteen4a03 Well-Known Member

    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.)
     
  11. silence

    silence Well-Known Member

    Ok but if I move the error checking to controllerpublic I still get the same error D:
     
  12. tyteen4a03

    tyteen4a03 Well-Known Member

    What is your ControllerPublic code?
     
  13. silence

    silence Well-Known Member

    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:
     
  14. tyteen4a03

    tyteen4a03 Well-Known Member

    What is your Test_Model_Account?
     
  15. silence

    silence Well-Known Member

    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);
        }
    }
     
  16. tyteen4a03

    tyteen4a03 Well-Known Member

    I just noticed you did not define a primary key in your fields. To define one, add 'autoIncrement' => true to that entry.
     
  17. silence

    silence Well-Known Member

    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;
     
  18. tyteen4a03

    tyteen4a03 Well-Known Member

    They are separate tables.
     
  19. silence

    silence Well-Known Member

    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?
     
  20. tyteen4a03

    tyteen4a03 Well-Known Member

    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?
     

Share This Page