How do I create an add-on that allows a user to click a link and call php code?

Do you understand how to extend one of those classes? Did you read the resource I linked to earlier?
 
I read all the links several times. Unfortunately it doesn't make much sense.

If I understand correctly, to extend the controller class I need to create a file like this:

/library/Andy/ChangeDate/ControllerPublic/some_file_name_that_i_have_no_idea_what_to_call_it.php

Is this correct?
 
To extend a class you need a code event listener:

You're going to go to admin cp -> development ->code event listener. Select load_class_controller. For event hint, you want to put the name of the class you're extending (in this case I'm pretty sure it's XenForo_ControllerPublic_Post). For 'Execute Callback' you need to put the class name of your listener. I generally put my listeners in a path like this: /library/Andy/ChangeDate/Listeners/ControllerPublic.php
"Andy_ChangeDate_Listeners_ControllerPublic" for the method you pick the name of the function within that class for example:

PHP:
<?php
    class Andy_ChangeDate_Listeners_ControllerPublic
    {
        public static function Post($class, &$extend)
        {
            if ($class == 'XenForo_ControllerPublic_Post') #make this match the event hint, this will allow it to work on 1.1 also.
                $extend[] = 'Andy_ChangeDate_ControllerPublic_Post'; #this is the name of your class that you're extending with.
        }
    }
?>

Because you named it Andy_ChangeDate_ControllerPublic_Post within the listener, you need to make that class in the same file structure XenForo uses, so change the _s to /s, prefix with library/ and suffix with .php so you get library/Andy/ChangeDate/ControllerPublic/Post.php

Then read the XenForo Proxy System thread that @Jeremy linked to
 
Thank you, Daniel. Your help is greatly appreciated.

Question wouldn't the correct path for Post.php be this?

library/Andy/ChangeDate/Listeners/ControllerPublic/Post.php
 
Thank you, Daniel. Your help is greatly appreciated.

Question wouldn't the correct path for Post.php be this?

library/Andy/ChangeDate/Listeners/ControllerPublic/Post.php

No. I understand what you're confused about now. The path to the autoloader isn't relative. No matter where you call XenForo_ControllerPublic_Post from, it's going to load /library/XenForo/ControllerPublic/Post.php. Which means no matter where you call your controller from (you're doing it from your listener), it's going to load that specific file. You could save your listener in /library/a/b/c/d/e/f/g/test.php (assuming you named the class correctly) and if you make $extend[] = "Andy/Test.php" it's going to load /library/Andy/Test.php; In theory you could put all your files in very random places as long as you named the classes the same way, it's just horribly unorganized and that's why we try to be specific. If it's a listener, it's recommended to go in /addon/listener/type.php (not literal), if it's a controller file for the public it goes in /addon/ControllerPublic/file.php (not literal). Make sense?
 
PHP:
<?php
    class Andy_ChangeDate_Listeners_ControllerPublic
    {
        public static function Post($class, &$extend)
        {
            if ($class == 'XenForo_ControllerPublic_Post') #make this match the event hint, this will allow it to work on 1.1 also.
                $extend[] = 'Andy_ChangeDate_ControllerPublic_Post'; #this is the name of your class that you're extending with.
        }
    }
?>

I created the Post.php file in the following path:

library/Andy/ChangeDate/ControllerPublic/Post.php

I assume my next step is to create the Code Event Listener. Here is the error I get:

pic001.webp
 
If it's a listener, it's recommended to go in /addon/listener/type.php (not literal), if it's a controller file for the public it goes in /addon/ControllerPublic/file.php (not literal). Make sense?

My problem is I have no idea if I'm creating a listener or controller file.

What I have done so far is to create a file here:

library/Andy/ChangeDate/ControllerPublic/Post.php

The contents are:

PHP:
<?php
  class Andy_ChangeDate_Listeners_ControllerPublic
  {
  public static function Post($class, &$extend)
  {
  if ($class == 'XenForo_ControllerPublic_Post') #make this match the event hint, this will allow it to work on 1.1 also.
  $extend[] = 'Andy_ChangeDate_ControllerPublic_Post'; #this is the name of your class that you're extending with.
  }
  }
?>

What am I creating? Is it a listener or controller file?
 
Hi Andy,

I just gave you the idea with the file edit, so you have an instant success and see how you can "create an addon" without the listener and extending stuff. Because this stuff is confusing at first (it's not complicated, but as with math, one wrong step and it doesn't work).

#48: Here in Execute Callback you enter the location of your LISTENER file. Andy_ChangeDate_Listener would be library/Andy/ChangeDate/Listener.php
 
#48 Event Hint: XenForo_ControllerPublic_Post

That means, that only if load_class_controller == "XenForo_ControllerPublic_Post", the Listener (the whole addon) will be activated.
 
My problem is I have no idea if I'm creating a listener or controller file.

What I have done so far is to create a file here:

library/Andy/ChangeDate/ControllerPublic/Post.php

The contents are:

PHP:
<?php
  class Andy_ChangeDate_Listeners_ControllerPublic
  {
  public static function Post($class, &$extend)
  {
  if ($class == 'XenForo_ControllerPublic_Post') #make this match the event hint, this will allow it to work on 1.1 also.
  $extend[] = 'Andy_ChangeDate_ControllerPublic_Post'; #this is the name of your class that you're extending with.
  }
  }
?>

What am I creating? Is it a listener or controller file?
The code I gave you is for the Listener.

When you create a file in XenForo, it has to be named in correlation to the class name. The file you created will literally never work.

library/Andy/ChangeDate/ControllerPublic/Post.php cannot have a class named Andy_ChangeDate_Listeners_ControllerPublic. You have to trip /library/ and .php off of the file path and change /s to _s to get your class name

library/Andy/ChangeDate/ControllerPublic/Post.php = class Andy_ChangeDate_ControllerPublic_Post
 
The official demos are a bit outdated as template_hooks are deprecated, and also other stuff as hints are very new. It is much easier to work with hints, as first it makes your code faster (not every load_class_controller XenForo loads will be checked against if it is "XenForo_ControllerPublic_Post"), and second it makes your coding shorter.

library/Andy/ChangeDate/Listener.php
PHP:
<?php

class Andy_ChangeDate_Listener
{
public static function Post($class, &$extend)
{
    $extend[] = 'Andy_ChangeDate_ControllerPublic_Post';
}

?>

As the "hint" tells this listener will only be executed in "XenForo_ControllerPublic_Post", you don't need to check it in the listener.

The class is named after the file path below "library/": Andy/ChangeDate/Listener.php will be named Andy_ChangeDate_Listener
 
Summary:

1. Create library/Andy/ChangeDate/Listener.php as in #56
2. Setup the addon with this data:
Listen to event: load_class_controller
Execute Callback: Andy_ChangeDate_Listener
Event Hint: XenForo_ControllerPublic_Post
 
To check whether the listener works, you can change the listener to

PHP:
<?php
class Andy_ChangeDate_Listener
{
public static function Post($class, &$extend)
{
  ZEND_DEBUG::dump("This listener is executed");break;
  //$extend[] = 'Andy_ChangeDate_ControllerPublic_Post';
}?>
 
Summary:

1. Create library/Andy/ChangeDate/Listener.php as in #56
2. Setup the addon with this data:
Listen to event: load_class_controller
Execute Callback: Andy_ChangeDate_Listener
Event Hint: XenForo_ControllerPublic_Post

Hi Marcus,

EDIT. Okay it works without errors.

I followed your instructions, but got a fatal error when I tried to view my forum. I suspect it has something to do with the Code Event Listener. Does this look correct?

pic001.webp
 
OK the listener file I provided you with was not correct.

PHP:
<?php

class Andy_ChangeDate_Listener
{
   public static function Post($class, array &$extend)
   {
         $extend[] = 'Andy_ChangeDate_ControllerPublic_Post';
   }
}

the "array &$extend" was missing partly.

Congratulations to your first addon!
 
Back
Top Bottom