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

XenForo_Model how does these work?

Mr. Goodie2Shoes

Well-known member
#1
Hello,
Can anyone tell me how do these constants and fetch options work? For example here's XenForo_Model_User:
PHP:
    const FETCH_USER_PROFILE    = 0x01;
    const FETCH_USER_OPTION      = 0x02;
    const FETCH_USER_PRIVACY    = 0x04;
    const FETCH_USER_PERMISSIONS = 0x08;
    const FETCH_LAST_ACTIVITY    = 0x10;
what exactly do these numbers mean and how do they work?

and the function
PHP:
function getUserById($userId, array $fetchOptions = array())
when exactly does the fetchOptions is added?
 

Chris D

XenForo developer
Staff member
#2
I can answer part of that.

fetchOptions is usually referenced in the controller that calls that function in the model.

It usually is an array that contains things such as the tables to be joined, sort order.

Later on in that model function you will see how fetchOptions is processed. It's processed by another function and essentially returns the SQL conditions to be used in the query.

It's a great way of doing things. In the context of fetching all users, sometimes you'd need your user data to be joined with their profile data, other times you wouldn't. So rather than two different blocks of code, XF will use the same function but ad just its output using the fetchOptions.

Still don't know what those constants do though :p
 

Luke F

Well-known member
#3
The constants are bitmask flags for use in fetchOptions['join'] (see function prepareUserFetchOptions in XenForo_Model_User) to control joins for data from tables beyond the basic xf_user
 

ManOnDaMoon

Well-known member
#4
The constants are useful preset options for telling the model to fetch more information. You pass this option in fetchOptions.

E.g.: You wish to fetch a user from its id, but also its last activity date, just tell the model that way:
PHP:
XenForo_Model::create('XenForo_Model_User')->getUserById($userId, array('join' => XenForo_Model_User::FETCH_LAST_ACTIVITY));
The XenForo_Model_User::prepareUserFetchOptions() function will check for these constants and add the preset join conditions.

Each Model has its own constants for its own additional fetch options.
 

Mr. Goodie2Shoes

Well-known member
#5
So the constants don't mean anything?
If so, then why did they use '0x01', '0x02' (and so on...) instead of just using 'true'?

EDIT:
The XenForo_Model_User::PrepareUserFetchOptions() function will check for these constants and add the preset join conditions.
okay this makes sense, thanks :)
 

ManOnDaMoon

Well-known member
#6
As darkimmortal said, they are bitmasks that can be combined.
See, they are set in hexadecimal, thus :
0x01 = 0001 (binary)
0x02 = 0010
0x04 = 0100

When you want both 0x02 (user options) and 0x01 (user profile), you can feed fetchOptions with
0x01 + 0x02 = 0011

Use it this way :
PHP:
XenForo_Model::create('XenForo_Model_User')->getUserById($userId, array('join' => XenForo_Model_User::FETCH_USER_PROFIL | XenForo_Model_User::FETCH_USER_OPTION));
(note the binary OR operator).
 

Chris D

XenForo developer
Staff member
#7
The constants are bitmask flags for use in fetchOptions['join'] (see function prepareUserFetchOptions in XenForo_Model_User) to control joins for data from tables beyond the basic xf_user
As darkimmortal said, they are bitmasks that can be combined.
See, they are set in hexadecimal, thus :
0x01 = 0001 (binary)
0x02 = 0010
0x04 = 0100

When you want both 0x02 (user options) and 0x01 (user profile), you can feed fetchOptions with
0x01 + 0x02 = 0011

Use it this way :
PHP:
XenForo_Model::create('XenForo_Model_User')->getUserById($userId, array('join' => XenForo_Model_User::FETCH_USER_PROFIL | XenForo_Model_User::FETCH_USER_OPTION));
(note the binary OR operator).
I get why these are here, now. I'm still a little bit hazy... but I thought I would ask to help achieve something I'm working on.

If I wanted to make more data available to the array of posts in a thread by joining to another table, how would I go about this using this constants? I can extend the thread controller index to add extra join data to the fetchOptions array, I can extend the post model to add additional prepareJoinOptions, but I want to be sure of how I can trigger this off with an additional constant, using XenForo_Model_Post::FETCH_MY_DATA.

I need to understand whether this is possible, and if it is how to do it so I don't prevent other add-on developers doing the same thing.

My alternative is to grab my data and slice it into the existing posts array, but this sounds like it could be more elegant and would save a db query.

EDIT: These are the existing constants, with mine added at the bottom:

PHP:
	const FETCH_USER = 0x01;
	const FETCH_USER_PROFILE = 0x02;
	const FETCH_USER_OPTIONS = 0x04;
	const FETCH_THREAD = 0x08;
	const FETCH_FORUM = 0x10;
	const FETCH_DELETION_LOG = 0x20;
	const FETCH_MY_DATA = 0x30;
Is it that simple?
 

Chris D

XenForo developer
Staff member
#8
Though I guess I don't even need to worry about them, right?

I can extend the controller with $fetchOptions['myJoin'], then I think I can extend the model::preparePostJoinOptions with

if ($fetchOptions['myJoin'])
{
$selectFields .= 'mytable.*';
$joinTables .= 'INNER JOIN xf_mytable AS mytable ON (mydata.user_id = post.user_id';
}

That could work... I will report back ;)
 

Luke F

Well-known member
#9
I get why these are here, now. I'm still a little bit hazy... but I thought I would ask to help achieve something I'm working on.

If I wanted to make more data available to the array of posts in a thread by joining to another table, how would I go about this using this constants? I can extend the thread controller index to add extra join data to the fetchOptions array, I can extend the post model to add additional prepareJoinOptions, but I want to be sure of how I can trigger this off with an additional constant, using XenForo_Model_Post::FETCH_MY_DATA.

I need to understand whether this is possible, and if it is how to do it so I don't prevent other add-on developers doing the same thing.

My alternative is to grab my data and slice it into the existing posts array, but this sounds like it could be more elegant and would save a db query.

EDIT: These are the existing constants, with mine added at the bottom:

PHP:
 const FETCH_USER = 0x01;
const FETCH_USER_PROFILE = 0x02;
const FETCH_USER_OPTIONS = 0x04;
const FETCH_THREAD = 0x08;
const FETCH_FORUM = 0x10;
const FETCH_DELETION_LOG = 0x20;
const FETCH_MY_DATA = 0x30;
Is it that simple?
Last should be 0x40
 

ManOnDaMoon

Well-known member
#10
Yup, or else the number will be binary 0011 0000, and will give the same result as combining FETCH_FORUM and FETCH_DELETION_LOG.

Also, you should use
PHP:
if ($fetchOptions['myJoin'] | Your_Extended_Class::FETCH_MY_DATA)
in the Model, having declared beforehand the FETCH_MY_DATA constant into your own class, thus not modifying any core file.
 

ManOnDaMoon

Well-known member
#13
What exactly do single '&' and '|' mean? I know that they are not logical but what exactly is the use?
Well you've got an illustration of a typical use in this topic. Binary numbers are also used in very low level operations, especially when one manipulates binary data, sometime related to the OS, or when one seeks performance in complex calculus.