• I’m Designing a post type with 3 membership levels:

    Master, Member and Viewer.

    The Master can manipulate the post content in the database, the Member has restricted access and the Viewer has read-only access.

    I’m adding the information by the way of meta data:

    update_post_meta( $post_id, '_membership', array('master'=$userID) );

    What I want is to be able to tell what level of access the current user has. Obviously the ‘master’ will have only a few entries, the ‘member’ will have a lot more and the ‘viewer’ will have loads more still.

    The problem is that the documentation suggests that updating the meta data will overwrite all the values in the array.

    What would be the best way of handling this?

Viewing 11 replies - 1 through 11 (of 11 total)
  • Moderator bcworkz

    (@bcworkz)

    And you cannot use user roles because the Master of one post may be the Viewer of another, yes? And the usual Author and everyone else model fails because of the intermediate role? Just checking ??

    Yes, updating post meta overwrites the previous values. But you can store arrays in post meta, so retrieve the current array, add a new value to it, then save the entire array. This works OK until the arrays get quite large, as do the number of posts. Then you probably need to devise a custom table system similar to how taxonomies are handled.

    Thread Starter dgcov

    (@dgcov)

    Ok, thanks; that was roughly how I was planning to use it.

    When you say it works until the arrays get quite large, how large is large? A couple of hundred? a few thousand? or a dozen?

    THe Author and everyone else won’t work as you say, because of the intermediate, but also because there may be multiple masters.

    Moderator bcworkz

    (@bcworkz)

    A couple hundred should be OK. A few thousand probably not. Just a wild guess really, I don’t work with large sites so I’ve not encountered such limits. It ultimately would depend on the server speed and load along with one’s tolerance for slowness.

    Thread Starter dgcov

    (@dgcov)

    I’m not getting the data I’m expecting.

    I’m using user_meta (which I understand works in the same way) to store a reference to the post.

    $usermeta=get_user_meta($userID,'membership');
          $usermeta[]=$post_id;
          update_user_meta($userID,'membership',$usermeta);

    I’m using `
    $membership=get_user_meta($userID,’membership’,true);` to get the array.

    I’m expecting something like:

    Array (
      [0] => 107
      [1] => 108
      [2] => 109
      [3] => 110
    )

    What I’m getting is the following:

    Array (
      [0] => Array (
        [0] => Array (
          [0] => Array (
            [0] => Array (
              [0] => 106
            )
            [1] => 107
          )
          [1] => 108
        )
        [1] => 109
      )
      [1] => 110
    )

    Moderator bcworkz

    (@bcworkz)

    LOL! Sorry, I find the output funny. I’m not laughing at your predicament.

    Try using get_user_meta( $userID,'membership', true );
    The Codex description of the third argument is confusing and using true does not make sense because of it. It has to do with how arrays are un-serialized automatically. Anyway, I think you will find that it solves your predicament.

    OK, maybe your predicament is at least a little bit funny ??

    Thread Starter dgcov

    (@dgcov)

    Sorry for taking so long in responding.

    This is how I’m doing it at the moment:

    $membership=get_user_meta($userID,'membership',true);
      $members=explode(',',$membership[0]);

    This gives me an array of member IDs which I can use, manipulate and save back to the database.

    $members[]=202;
    $membership=implode(",", $members);
    update_user_meta( $userID, 'membership', $membership );

    However, I can’t think that this was how it was meant to be implemented.

    Moderator bcworkz

    (@bcworkz)

    What part are you skeptical about? It seems odd to me you need to explode and implode the array, meta data is supposed to be serialized automatically. It could be because you are ending up with an array in an array. It has always taken some trial and error when I deal with these to get the process to behave symmetrically. It partly depends on what or if you provide the 4th parameter $prev_value when updating.

    All you really want is to essentially “push” another value onto the existing array, correct? See what happens if you simply update the meta key with a single integer without the fourth parameter. I think when you get this back with $single set as false you get the expected one level array of all integers that were “pushed”. If that fails try something else, it’s educational if nothing else.

    I just noticed we have moved sometime back from post meta to user meta. The behavior is the same so it doesn’t matter on one level, but to achieve your ultimate goal shouldn’t the user’s privileges be stored with each post since it varies by post?

    It’s maybe worth thinking about a different approach though. Would it make more sense to track which posts a particular user has some access level to by user instead of by post? What ever way results in less data in the long run should be preferable. It may be even worth considering custom tables much like how taxonomies are handled. Or for that matter, could this be handled with a custom taxonomy?

    I dunno, just thinking out loud. Do what you think is best.

    Thread Starter dgcov

    (@dgcov)

    Thanks.

    Yes, I would have expected that the array in the user_meta (or post_meta) can be added to without exploding and imploding the array.

    The scenario is as follows:
    A registered user has documents on the site which he can allow access to by other nominated users. Each document has 3 levels of access: view, editor and super, and 3 post_meta entries, each of which carries a list of user ids with access at that level.

    Similarly, each user has a list of documents he is allowed access to.

    When the registered user gives someone access to a document, that person is registered at a low level and a user_meta is generated or updated to include that document.

    So when someone logs in to the site, they have a list of documents they can access. Similarly, when they access the document, they get granted access at the level specified by the document’s post_meta.

    I suppose I could do this using roles, but there may frequently be occasions where a user may have ‘super’ access to one document but only ‘viewer’ access to another.

    Moderator bcworkz

    (@bcworkz)

    Ah! So you were thinking both user and post meta! I don’t think that’s necessary (though workable), you should want to avoid redundant data. Pick one or the other, it may not matter which, the data volume is probably the same either way. Where ever the data resides, you can get the complementary results by how you query. For example, lets say we chose to use post meta and thus store user IDs with each post.

    To get all posts any particular user has a certain access to, just query for posts where the user ID is in that post’s meta. And of course when they request a post it’ll only be shown if their ID is in that same meta. No need to go to user meta to determine these things.

    I’m reasonably sure that if you experiment a bit you should arrive at an update routine that doesn’t involve explicitly serializing arrays. I can’t say what that is. I do recall I struggled with the same thing some time back and eventually found a way. IIRC, the crux was more about how I added new values to the existing data than WP functions. But I don’t recall what I ended up doing ??

    Thread Starter dgcov

    (@dgcov)

    Cheers.

    Am I wrong in thinking that doing a query for a post by id and then querying the post_meta data for access level would be more efficient than querying each of the meta data entries for each of the posts for the user id?

    Moderator bcworkz

    (@bcworkz)

    Hmm, interesting question! I really don’t know. I’m of the mind to minimize the number of queries overall. That a complex query is better than multiple queries to serve the same purpose.

    I deceive myself often enough in discounting the queries that result from WP functions like get_post_meta(), thinking only in terms of the main query. Maybe I’m not really seeing the whole picture.

    While I don’t have direct evidence to support it, I’m quite clear that one should avoid redundant data, even if it reduces efficiency to some extent. From a general data management stand point it’s just plain wrong IMO. If one really needed redundant data to make queries work efficiently, I would look into some way of auto-generating the redundant data and have it updated regularly, in the same way caches are managed. They after all are redundant data for the sake of efficiency, but in theory no one should have to manage it. It happens behind the scenes.

Viewing 11 replies - 1 through 11 (of 11 total)
  • The topic ‘Post Meta Data: How does it work?’ is closed to new replies.