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

Directory Structure & Small Code Question

Discussion in 'XenForo Development Discussions' started by Jeremy, Oct 6, 2010.

  1. Jeremy

    Jeremy XenForo Moderator Staff Member

    Just two quick questions:

    1. The modification directory structure is everything inside a directory of the add on ID, under the library directory. Correct? If so, how come everything under the sun I do with code Listeners tend to result in a "Please add a valid callback method" error.

    2. I'm writing an add on to take values from a registering user, check them against a database, and reject/accept the registration. But, I'm going into seriously new territory (MVC). And I don't see a code event listener that'd be used to modify this particular area? Just a quick nudge would be helpful.

    Jeremy
     
  2. Shadab

    Shadab Well-Known Member

    1. Make sure you are creating static event listener functions.
    2. Heres a good start:

    The controller for the registration form is located at /library/XenForo/ControllerPublic/Register.php, whose actionRegister() method is called when you submit the registration form. So you need to override this particular method only and perform your own validation before letting the registration continue as usual.

    Create a new file: /library/GeekPoint/ControllerPublic/Register.php where you'll override the actionRegister() method and perform your own validations...
    PHP:
    <?php

    class GeekPoint_ControllerPublic_Register extends XFCP_GeekPoint_ControllerPublic_Register
    {
        public function 
    actionRegister()
        {
            
    $errors = array();
            
    $data   $this->_input->filter(array(
                
    'username'   => XenForo_Input::STRING,
                
    'email'      => XenForo_Input::STRING,
                
    'timezone'   => XenForo_Input::STRING,
                
    'gender'     => XenForo_Input::STRING,
                
    'dob_day'    => XenForo_Input::UINT,
                
    'dob_month'  => XenForo_Input::UINT,
                
    'dob_year'   => XenForo_Input::UINT,
            ));

            if (!
    $this->_validateRegistration($data))
            {
                
    // Add errors to display to the end user (See note #3)
                
    $errors[] = "Epic Fail";
            }

            if (
    $errors)
            {
                
    // Return the invalid data along with the errors
                
    return $this->_getRegisterFormResponse($data$errors);
            }

            
    // Reached here? Continue the registration...
            
    return parent::actionRegister();
        }

        protected function 
    _validateRegistration($data)
        {
            
    // Do your processing & validation here
            
    return false;
        }
    }
    Next, we'll create a code event listener that would listen to the load_class_controller event and hook our class accordingly. Create a file /library/GeekPoint/EventListener/Register.php with the given code:

    PHP:
    <?php

    class GeekPoint_EventListener_Register
    {
        public static function 
    listen($class, array &$extend)
        {
            if (
    $class == 'XenForo_ControllerPublic_Register')
            {
                
    $extend[] = 'GeekPoint_ControllerPublic_Register';
            }
        }
    }
    We're done with the PHP part. All we need to do next is register our event listener via the AdminCP. Go to: AdminCP -> Development -> Code Event Listeners -> Create New Code Event Listener; and enter the following values:

    Listen to event: load_class_controller
    Execute Callback: GeekPoint_EventListener_Register :: listen

    [Save Event Listener]

    Done! Visit: /your_board/register/ and submit the form to see this in effect.

    Notes:

    1. You don't need to follow the directory structure I gave above. You can create your file in any location you want in /library/ as long as the autoloader is able to recognize and load it. But it's easier if you follow the conventions.

    2. For the class you want to extend via any load_class_* event, you need to extend a non-existent proxy class with the name: XFCP_your_own_classname, and XenForo will take care of everything else.

    3. Use the inbuilt language/phrase system instead of directly embedding text in your scripts. So use: $errors[] = new XenForo_Phrase('epic_fail'); in place of $errors[] = "Epic Fail";. This would come handy when you want to change the text later or provide translations of your script in other languages.

    Hope it helps. :)
     

    Attached Files:

  3. Jeremy

    Jeremy XenForo Moderator Staff Member

    THANK YOU SOOOOOOOO MUCH! I can probably finish my mod now that I have this. :)
     
    Shadab likes this.
  4. Shadab

    Shadab Well-Known Member

    You're welcome. Let me know how it goes. :)

    Btw, is that something you'll release as a mod here?
     
  5. Jeremy

    Jeremy XenForo Moderator Staff Member

    Absolutely! It's my Stop Forum Spam modification, and anything I code is either for release or fun, as my XenForo license won't be utilized just yet.
     
  6. Jeremy

    Jeremy XenForo Moderator Staff Member

    Hm. Basically using your exact code (I changed the name of the classes I used, and added all must stuff into them), it seems to work, but I get this error:

    No controller response from XenForo_ControllerPublic_Register::actionRegister
    1. [*]XenForo_FrontController->_handleControllerResponse()inXenForo/FrontController.phpat line311
      [*]XenForo_FrontController->dispatch()inXenForo/FrontController.phpat line132
      [*]XenForo_FrontController->run()in/Users/Jeremy/Sites/xen/index.phpat line15
    Thoughts?
     
  7. Shadab

    Shadab Well-Known Member

    That's odd.

    Could you please zip the files and upload it for me to check?
    (or send it privately if you want)
     
  8. Jeremy

    Jeremy XenForo Moderator Staff Member

    Since I'll be releasing it once you help me out big time again, I will just post them here (BTW: There's only 1 phrase added, and 3 options, not yet Zipped here).
     

    Attached Files:

  9. Shadab

    Shadab Well-Known Member

    Please change:
    PHP:
    parent::actionRegister();
    to:
    PHP:
    return parent::actionRegister();
    *Updated my original post.
     
    Jeremy likes this.
  10. Deceptor

    Deceptor Active Member

    Code:
            // So, you are human after all. I guess I shall let you register.
            parent::actionRegister();
    Change this to
    Code:
            // So, you are human after all. I guess I shall let you register.
            return parent::actionRegister();
    The method needs to return the same response the parent controller would normally (modified or the same) :)

    Edit: NVM :p
     
    Jeremy and Shadab like this.
  11. Jeremy

    Jeremy XenForo Moderator Staff Member

    Duh. I really should go to bed early one of these days... Thank you guys! I'll do one last quick test and release it right quick!
     
  12. Shadab

    Shadab Well-Known Member

    Yeah. I didn't notice that, since the control never reached there.
    Bad choice of sample code on my part. Sorry. :)
     
  13. Deceptor

    Deceptor Active Member

    No need to apologise at all :) XF is new to us all and I've been tripping up all over the place with it tonight - slowly learning though :D
     
    Jeremy likes this.
  14. Jeremy

    Jeremy XenForo Moderator Staff Member

    Honestly, without you, I couldn't have gotten this far. :) I can't thank you enough!
     
    Shadab likes this.
  15. Shadab

    Shadab Well-Known Member

    8 AM here & no sign of sleep yet. Been up all night reading the source code and playing with the template system. Whoever said XF is the crack cocaine caffeine of forums... was damn right! :D
     
  16. Jeremy

    Jeremy XenForo Moderator Staff Member

    Haha, Its going on 11 PM here and I still have homework (a ton of it) and class tomorrow. Boo. :( But I will start to work on a much more complicated add on tomorrow.
     
  17. Kier

    Kier XenForo Developer Staff Member

    Just a note that you should not really be doing this
    PHP:
    $errors[] = "Epic Fail";
    but rather, use this:
    PHP:
    $errors[] = new XenForo_Phrase('epic_fail');
     
    ZeWildGuy and Shadab like this.
  18. Jeremy

    Jeremy XenForo Moderator Staff Member

    Woohoo! I actually did that. :p
     
  19. Shadab

    Shadab Well-Known Member

    Thanks!

    *Added a note (#3) to the post.
     

Share This Page