1. 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?

Discussion in 'XenForo Development Discussions' started by Mr. Goodie2Shoes, Nov 9, 2012.

  1. Mr. Goodie2Shoes

    Mr. Goodie2Shoes Well-Known Member

    Can anyone tell me how do these constants and fetch options work? For example here's XenForo_Model_User:
        const FETCH_USER_PROFILE    0x01;
    FETCH_USER_OPTION      0x02;
    what exactly do these numbers mean and how do they work?

    and the function
    function getUserById($userId, array $fetchOptions = array())
    when exactly does the fetchOptions is added?
  2. Chris D

    Chris D XenForo Developer Staff Member

    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
    Mr. Goodie2Shoes likes this.
  3. Luke F

    Luke F Well-Known Member

    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
    Mr. Goodie2Shoes likes this.
  4. ManOnDaMoon

    ManOnDaMoon Well-Known Member

    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:
    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 likes this.
  5. Mr. Goodie2Shoes

    Mr. Goodie2Shoes Well-Known Member

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

    okay this makes sense, thanks :)
  6. ManOnDaMoon

    ManOnDaMoon Well-Known Member

    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 :
    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).
    Fuhrmann, Marcus and Mr. Goodie2Shoes like this.
  7. Chris D

    Chris D XenForo Developer Staff Member

    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:

        const FETCH_USER 0x01;
    FETCH_THREAD 0x08;
    FETCH_FORUM 0x10;
    FETCH_MY_DATA 0x30;
    Is it that simple?
  8. Chris D

    Chris D XenForo Developer Staff Member

    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 ;)
  9. Luke F

    Luke F Well-Known Member

    Last should be 0x40
    Mr. Goodie2Shoes and ManOnDaMoon like this.
  10. ManOnDaMoon

    ManOnDaMoon Well-Known Member

    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
    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.
  11. Mr. Goodie2Shoes

    Mr. Goodie2Shoes Well-Known Member

    What exactly do single '&' and '|' mean? I know that they are not logical but what exactly is the use?
  12. Bob

    Bob Well-Known Member

    Mr. Goodie2Shoes likes this.
  13. ManOnDaMoon

    ManOnDaMoon Well-Known Member

    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.
  14. Chris D

    Chris D XenForo Developer Staff Member

    Thank you all for your answers. Makes a little more sense.

Share This Page