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

How To Make An Addon Resource?

Discussion in 'XenForo Development Discussions' started by DRE, Sep 10, 2012.

  1. DRE

    DRE Well-Known Member

    Can someone please make a how to make an addon resource since Floris deleted his before I could finish learning?
  2. DRE

    DRE Well-Known Member

  3. Chris D

    Chris D XenForo Developer Staff Member

    Look for the one that Fhurman did (I spelt that wrong) to do with adding a tab with a template hook.

    It's the one I used.

    Also you can contact me anytime if you need specific help.
    Fuhrmann likes this.
  4. DRE

    DRE Well-Known Member

    Thanks! The main thing I need is an addon that creates user profile fields.

    If I had an addon that did that then I could just combine it with TMS edits.
  5. Chris D

    Chris D XenForo Developer Staff Member

    Ah I see.

    Well, unfortunately the creation of profile fields requires custom PHP code to be written, but it's actually quite straight forward. I was going to write a tutorial about it actually.

    In an ideal world, you should be able to create User Profile Fields and export them with your add-on like you can do with everything else. I believe it has been suggested for 1.2 (if not I will do so).

    The first step is to create your Add-On in the Admin CP. Let's say it's called: Your Add-On and it has an ID of YourAddOnID.

    You will notice in the Edit Add-On page (available only with Debug Mode on, of course) that there is a box for Installation Code and Uninstallation Code. These are what we need to fill in, but first, we need to start writing some PHP!

    1) Create a folder in the library folder that matches the name of the add-on ID you've just created. So: library/YourAddOnID.

    2) Create a new file called Install.php

    3) This file needs to begin as follows. With the <?php declaration, a class declaration and the name of a function:

    class YourAddOnID_Install
    public static function installer($existingAddOn)​
    // We will put code here later​
    Note that the class matches the directory structure? That convention should be adhered to.

    The name of the function can be anything, in this case I have called it installer. There is also a parameter in the brackets called $existingAddOn. This is very important for this add-on and you'll see why later. This is passed to the installer function by some other XenForo class, I believe. The parameter basically contains the information that either "This is an upgrade of an existing add-on" or "This is a brand new install of a new add-on".

    4) In your Edit Add-On screen, you can now set the Installation code class to the class defined in Install.php, e.g. YourAddOnID_Install and you can set the Installation code method to the name of your function, in this case installer.

    Click Save.

    If you save this before creating the Install.php or you've not created it properly then you will receive an error: "Please enter a valid callback method".

    5) Now it's time to add some PHP code. So directly below my commented line //We will put code here later we need the following:

    6) First let's call the DataWriter responsible for UserFields. This is going to write data to the xf_user_field table in the database.

    $dw = XenForo_DataWriter::create('XenForo_DataWriter_UserField');
    This line calls the DataWriter class responsible for User Fields. Based on the convention we used to create the class in Install.php, you can hopefully see that the PHP file being called here is located at library/XenForo/DataWriter/UserField.php You don't need to do anything else with this file, but it's worth bearing in mind. You'll learn a lot by looking at these files and what they do.

    7) Now we've called the correct DataWriter we can now use the DataWriter to start setting the data that we want to write to the database. In our case, the following steps are adding a Custom User Field directly to the database. You will hopefully recognise some of the option names from creating fields in the Admin CP.

    For example purposes, this will simply create the simple Preference option I used to create the Custom User Field used in this add-on: http://xenforo.com/community/resources/display-e-mail-address-in-profile.810/ There's a screenshot too.

    $dw->set('field_id', 'displayEmailAddress');
    So, this line references the DataWriter again using the $dw variable we set on the previous line. It then references a function called "set" which takes two parameters. The first is the name of the column we're inserting data into, the second is the value of the row we're setting.

    The field_id is important. You need to remember this, we'll need to use it later.

    $dw->set('display_group', 'preferences');
    $dw->set('display_order', 1);
    $dw->set('field_type', 'select');
    $dw->set('required', 1);
    $dw->set('show_registration', 1);
    $dw->set('user_editable', 'yes');
    $dw->set('viewable_profile', '0');
    Hopefully these are quite self explanatory based on the fields you would use to create a user profile field in the Admin CP... if not ask and I will clarify.

    8) Now we've instructed what needs to be populated in the xf_user_field table, we need to define some options for that table. That's done with this code... This actually may be more complicated than you need it to be. This is to define choices for a drop down select box. You need to define an array which contains the ID of the option, and some hard coded text. Obviously hard coded text isn't good where phrases are involved... but more on that later too... In my case the options were simple, there were only two. Show or Hide:

    $choices = array(
    'hide' => 'Hide',​
    'show' => 'Show'​
    9) That array doesn't actually do anything on its own. It just defines an array called $choices. We now need to write that to the database... Luckily there's a function that does this for us!

    10) That's everything right? Everything has been written to the database. No. It hasn't. We've told the DataWriter what we want to write, but we haven't told the DataWriter to write that to the database yet. That's incredibly complicated:

    The resulting Install.php should now look like this:

    class YourAddOnID_Install
        public static function installer($existingAddOn)
                $dw = XenForo_DataWriter::create('XenForo_DataWriter_UserField');
                $dw->set('field_id', 'displayEmailAddress');
                $dw->set('display_group', 'preferences');
                $dw->set('display_order', 1);
                $dw->set('field_type', 'select');
                $dw->set('required', 1);
                $dw->set('show_registration', 1);
                $dw->set('user_editable', 'yes');
                $dw->set('viewable_profile', '0');
                $choices = array(
                    'hide' => 'Hide',
                    'show' => 'Show'
    Now we have three problems.

    Problem 1: If you release an update, the upgrade of your add-on will fail. The reason for that is the installer will run every time it is either installed or upgraded. It will fail because it will try to write the same database stuff again as before.

    Problem 2: If the add-on is uninstalled there is currently nothing that will remove these fields from the database.

    Problem 3: We need to make use of the phrases system so the field and options have phrases that can be translated using the Phrases system.

    Solution 1:

    Remember the $existingAddOn parameter? This is an easy fix. So the datawriter only writes the data if it's a new add-on all you need to do is add the following above the $dw = XenForo_DataWriter... line:

    if (!$existingAddOn)
    And the following to close the if statement below the $dw->save(); line


    Solution 2:

    We need to add an uninstaller.

    We can define that in the same Install.php file:

        public static function uninstaller()
    $db = XenForo_Application::get('db');​
    } protected static $query = array(
    'dropField' => "DELETE FROM `xf_user_field` WHERE `xf_user_field`.`field_id` = 'displayEmailAddress'",​
    'dropValues' => "DELETE FROM `xf_user_field_value` WHERE `xf_user_field_value`.`field_id` = 'displayEmailAddress'"​
    You will just need to now edit your Add on again and under Uninstall Code type class: YourAddOnID_Install and method: uninstaller.

    I'm running out of time, but essentially the Uninstaller accesses the Database directly as defined in the config file and runs two queries. The two queries are defined below the uninstaller function.

    Solution 3:

    We need to create some phrases! Remember when we created the field I said remember the field ID? This is why. The Field ID is used in the phrases. This is how XenForo knows how to associate the below phrases to your field.

    Phrase 1
    This is the title of the field, as seen in "Preferences" by the user
    Title: user_field_displayEmailAddress
    Text: Display E-Mail Address in Profile

    Phrase 2
    This is the phrase for the choice with an ID of 'hide'. Notice again, it uses the field ID, and the id of the choice as defined in $choices above!
    Title: user_field_displayEmailAddress_choice_hide
    Text: Hide

    Phrase 3
    This is the phrase for the choice with an ID of 'show'
    Title: user_field_displayEmailAddress_choice_show
    Text: Show

    Phrase 4
    This is the description that shows below the field as seen in "Preferences" by the user
    Title: user_field_displayEmailAddress_desc
    Text: Your e-mail address will always be hidden to guests.

    Make sure all of these phrases have your add-on as the selected Add-on so they are exported when you export the XML.

    And that's it! You're finished!

    Nightmare, really, they should really let us just export user fields in the add-on XML file.

    Hopefully this will help. I know I've been vaguer in some places more than others but this took me ages to right and I'm supposed to be working :sneaky:

    Let me know how you get on! I have attached the PHP file so you can use that for reference.

    Attached Files:

    Mirovinger, RoldanLT, Steve F and 7 others like this.
  6. DRE

    DRE Well-Known Member

    Oh thank youuuu i will be doing this very soon!!
  7. justinsan

    justinsan New Member

    thanks for those who posted their commands​
  8. SheepCow

    SheepCow Well-Known Member

    You'd be better off using the data writer to delete the profile field, it will automagically deal with removing everything needed (e.g. values).
    Chris D likes this.
  9. Chris D

    Chris D XenForo Developer Staff Member

    True dat
  10. DRE

    DRE Well-Known Member

    How do you do that?
  11. DRE

    DRE Well-Known Member

    My main reason for asking is the only addons I plan on making are updates to my current addons that are dependent on TMS and addons that are template modification resources that require a custom user field. By no means am I trying to do anything grand. I just want to get off TMS.
  12. Chris D

    Chris D XenForo Developer Staff Member

    My example will work with no issues.

    There's just a slightly better way of doing it. The same result though.
  13. SheepCow

    SheepCow Well-Known Member

    Indeedy, the more "correct" way would be (off the top of my head) in your uninstaller to do:
    $dw XenForo_DataWriter::create('XenForo_DataWriter_UserField');
    Steve F, LPH and Chris D like this.
  14. Morgain

    Morgain Well-Known Member

    I have an almost completed addon - a cool dev created the php part and an xml file.
    I'm trying to be independent and do parts for myself, at least the appearance of it.

    So I did a lot of phrase edits. I'd like to add them to the addon so I don't have to do them individually on several sites.
    Also other people might like this little addon if I can get it tidy, so the phrase edits would be nice for them too. I thought I'd add a key as a text file in the final zip so specific edits can be easily identified, undone or changed later.

    How do I add all these phrase edits into the addon so they automagically install?
    DRE likes this.
  15. Pereira

    Pereira Well-Known Member

    You can assign phrases to a specific add-on when creating them.

    EDIT: Are you in debug mode when creating the phrases?
  16. Morgain

    Morgain Well-Known Member

    Thanks but I'm not creating Phrases, I'm editing them so they display as different words.

    I want to add those LOTS of changes to the addon so I don't have to go through each separate Phrase to change it when I install my version of the RM.Or other people if they want to use it.

    I am guessing there is a way to add Phrase edits to the xml file? I looked at it in an editor but there weren't any lines in it that looked like they were Phrases so I couldn't use anything there as a model to copy.
    Or maybe there is a different way to include automagic Phrase edits in an addon install.
  17. tenants

    tenants Well-Known Member

    If you have updated the phases inthe ACP (under master-language), and those phrases are associated to a particular add-on, when you export the add-on, your new phrases will export with them (into the xml that the export produced)

    To export the addon, you will turn on the dev options in your config:

    Chris Deeming also made this resource to enable debug mode (so you can flick it on, do the export, then flick it off again):
    Morgain likes this.
  18. Morgain

    Morgain Well-Known Member

    Thank you lots. I still have knowledge gaps ...

    I know about debug and the addon that toggles it.
    I have changed phrases so they look how I want them frontend - this is in my default style.
    Almost all are already part of the RM. (The few not are not important)

    I think I did do an export of phrases once ... but this will mean I now have two xml files as the addon has an xml already doing other stuff?
    Hmm - a join? I guess I first copy both xml files for backup safety.
    Then I check their headers and footers to see if anything matches. In the 2nd one ignore any header and footer bits which match, and paste the rest between into the first xml above its footer?
  19. Steve F

    Steve F Well-Known Member

    I think this is worthy of putting in the RM as a tutorial @Chris D . Was very handy guide for me :)
  20. Chris D

    Chris D XenForo Developer Staff Member

    Thanks Steve.

    I wrote that so long ago now... wow. Nearly 2 years!

    As it happens, there's a much better way of defining the titles and descriptions of fields. I wasn't aware of it at the time (noob!). Also I'm pretty sure the choice phrases are added automatically too.

    To set the title and description, before the line $dw->save(); add this:

    $dw->setExtraData(XenForo_DataWriter_UserField::DATA_TITLE'This is the title of the user field');
    $dw->setExtraData(XenForo_DataWriter_UserField::DATA_DESCRIPTION'This is the description of the user field');
    That automatically creates the phrases with the defined text.
    Steve F likes this.

Share This Page