XF 2.2 Join a table with each Post

zethon

Member
I've been working my way through the Addon Tutorial and experimenting with my own code as well. One thing I am having problems with is how I would JOIN a table with a XF:Post.

For example, say I want to write a simple plugin that allows you to "comment" on a post (I know various plugins and functionality already exists for this kind of thing, this is just an exercise). So, I create a table that has a three columns: comment_id, post_id, comment, where post_id is the FK for the post. I've created a simple Entity for this, something like so:

Code:
<?php
namespace Demo\Portal\Entity;
use XF\Mvc\Entity\Structure;
class Comments extends \XF\Mvc\Entity\Entity
{
    public static function getStructure(Structure $structure)
    {
        $structure->table = 'lulzapps_comments';
        $structure->shortName = 'lulzapps\MyAddon:Comments';
        $structure->primaryKey = 'comment_id';
        $structure->columns = 
            [
                'comment_id' => ['type' => self::UINT, 'required' => true, 'autoIncrement' => true],
                'post_id' => ['type' => self::UINT, 'required' => true],
                'comment' => ['type' => self::STR, 'required' => true, 'maxLength' => 255],
            ];
        $structure->getters = [];
        $structure->relations = 
            [
                'Post' => 
                    [
                        'entity' => 'XF:Post',
                        'type' => self::TO_MANY,
                        'conditions' => 
                            [
                                ['post_id', '=', '$post_id']
                            ],
                        'primary' => true
                    ],
            ];
    
        return $structure;
    }
}

For now, I'm not worried about how comments get into the table (I've just manually added data for the time being. My first question is: is the self:TO_MANY relationship correct here? Is this saying that a comment can belong to multiple posts (which I don't want)? Or is this saying that a post can have multiple comments (which I do want?)

Also, how would I load this information into my $post object for use within my post_macros template? I know I want to do something like:

Code:
<xf:foreach loop="$post.comments" key="$comment_id" value="?????">
    <h1>{{$post.comments}.comment}</h1>
</xf:foreach>

Or something... I really have no idea. But before I can begin to figure out the template, I need to figure out how to access the data.

Any help would be appreciated.
 
My first question is: is the self:TO_MANY relationship correct here? Is this saying that a comment can belong to multiple posts (which I don't want)?
This is defining the relationship from a comment to a post. Since a comment can only be part of one post, it would be a TO_ONE relationship. This signals the system to know what is being returned by that relationshp (an entity or null instead of a collection object of 0 or more entries).

Also, how would I load this information into my $post object for use within my post_macros template?
You'd need to extend the Post entity using either class extensions or a code event listener so that you can define your Post->Comments relationship in the structure. This would be the TO_MANY relationship. (By convention, relationships are defined with a capital letter.)

If this is defined, then you can iterate over {$post.Comments}. In your example code, the value is just whatever you want the variable to be called. It's equivalent to foreach ($post->Comments AS $comment_id => $value).

Note that we don't support eager fetching of TO_MANY relationships. To access this data efficiently, you may need to add separate functions to do pre-fetching. This is an approach we take with preloading attachments and unfurls, for example. (The relationship will still be loaded on demand anyway, so don't worry about this until you have the rest of the stuff working.)
 
Top Bottom