XF 2.0 Adding user account preference options - where to store data

Sim

Well-known member
I want to add some options to account preferences as part of an addon I'm developing.

Trying to work out the potential ramifications / benefits of different approaches I'm considering in relation to storing the data.

I see two ways of approaching this:
  1. add a new column to the xf_user_option table and extend the UserOption entity
  2. add a new table with corresponding new entity and add that as a new relation to the User entity
I guess the two approaches are likely very similar in outcome - with some pros and cons on each side.

Option 1 - adding a new column to user_option table means the data is loaded along with all other options. But I generally prefer to avoid modifying core tables, which is why I am considering option 2.

Option 2 - potentially adds another query, so care would be needed if this will be loaded frequently - but in my case, it's only going to be loaded as part of a background job, so I'm not concerned about database hits.

I'm not sure which approach is going to require more coding work - if I add a new column to the existing table, I need to extend all of the User Option save functionality to ensure the data gets stored when preferences are updated. If I add a new table, I only need to implement enough to store and retrieve that data when required - but there's potentially more work involved in saving preferences since I can't just piggyback on existing code.

My main driver for wanting to use a separate table is 1) less chance of making a mess when installing/upgrading/removing the addon if my Setup routine isn't perfect ... and 2) potentially less work if there are future changes to the xf_user_option table which might impact on my addon.

I'm guessing it's largely going to come down to personal preference?

How does everyone else approach this? Are there any recommendations from the devs?

I note that both XFMG and XFRM both add columns to the xf_user table directly - but those are mostly count fields rather than preference fields, so it makes sense for them to be there.
 
FYI, in XF1 I generally just used a custom user field - but because you can't associate them with an addon, the installation instructions for the addon would be to create the custom user field with certain specifications and then in the addon options you choose that custom user field as the source of the data. It was clunky, but it worked - and was generally less work than jumping through hoops with XF1.

Now that XF2 makes it far easier to extend the functionality, I think it's worth actually creating a new column somewhere.
 
I talked about that here: https://xenforo.com/community/threa...tory-sessionactivity-php.148510/#post-1258829
The tl;dr is the same as you stated above, "it depends" :P I personally would extend the core tables in your case if it's an option everyone should set or unset. If it's an additional option like "do you wanna see that forum, really?", I'd go with an extra table or a custom field, as you said. Automatically creating custom fields is not a pain in the ass anymore with XF2 iirc.
My main driver for wanting to use a separate table is 1) less chance of making a mess when installing/upgrading/removing the addon if my Setup routine isn't perfect ... and 2) potentially less work if there are future changes to the xf_user_option table which might impact on my addon.
I don't think there are higher chances of messing up with the core tables when extending them, it's just the outcome could be far more impactful (in a negative way). That said, the chance of this is already so low to happen, I wouldn't bother about it. You really would need some ill intention to actually mess up a core table during maintenance routines with XF2.
Your last point is valid, but that does not happen frequently enough to be considered. I mean, the options table has the exact same structure as in XF1.5, so you really don't need to worry about that either. There was just one extra field which got dropped afaik.
 
You really would need some ill intention to actually mess up a core table during maintenance routines with XF2.

It's not ill intention I'm concerned about - it's buggy Setup code :p

I think in this case I'm going to add a new column to the options - now that I've thought more about how I'm actually going to use the column in the code, it makes a lot more sense to be accessing the UserOption entity to manipulate it.

The more tricky bit will be getting the migration process right since I am replacing an XF1.5 addon which uses custom user fields :eek:
 
If you use the XF framework at least how it's intended to use, it's impossible to mess up such a small thing like adding or dropping a column, no matter if core or not. Literally, you can't screw this up unless you really want to. :X3: There are a lot of fallbacks integrated, starting by isolating almost everything into its own realm, following MVC to a very high standard and so on.
 
If you use the XF framework at least how it's intended to use, it's impossible to mess up such a small thing like adding or dropping a column, no matter if core or not. Literally, you can't screw this up unless you really want to. :X3: There are a lot of fallbacks integrated, starting by isolating almost everything into its own realm, following MVC to a very high standard and so on.

It's not adding or dropping a column that's the problem - that's the trivial part.

It's data consistency which usually catches you out. I've also had unexpected bugs in Setup routines cause things to break part way through an upgrade thus requiring additional upgrade steps to patch the inconsistent data.

The problem with upgrade routines involving data migration is that they run on real data which makes it tricky to test how they will operate on your production data without actually running them on your production data, which means setting up a restore-able version of your site to test on and a lot more work than simply running addColumn!

It's even worse when you have 8 sites to test on :eek:
 
Last edited:
Ok, well, you're right, that's another scope. In that case I actually would tend to go with a custom field aswell, that should be the least amount of code to write if you have to do an import anyways.
 
Top Bottom