Directory Structure & Small Code Question

Jeremy

in memoriam 1991-2020
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
 
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. :)
 

Attachments

  • Register_Errors.webp
    Register_Errors.webp
    12.5 KB · Views: 25
  • GeekPoint.zip
    GeekPoint.zip
    1.1 KB · Views: 6
You're welcome. Let me know how it goes. :)

Btw, is that something you'll release as a mod here?
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.
 
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?
 
That's odd.

Could you please zip the files and upload it for me to check?
(or send it privately if you want)
 
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).
 

Attachments

Please change:
PHP:
parent::actionRegister();
to:
PHP:
return parent::actionRegister();

*Updated my original post.
 
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
 
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!
 
The method needs to return the same response the parent controller would normally (modified or the same)
Yeah. I didn't notice that, since the control never reached there.
Bad choice of sample code on my part. Sorry. :)
 
Yeah. I didn't notice that, since the control never reached there.
Bad choice of sample code on my part. Sorry. :)

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
 
XF is new to us all and I've been tripping up all over the place with it tonight - slowly learning though :D
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
 
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

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.
 
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');
 
Top Bottom