XF 2.0 Some questions about this whole "Entity" thing...

Then you could use a regular property to store the result of the calculation, e.g.
PHP:
protected $streamChat;

public function getStreamChat()
{
    if ($this->streamChat === NULL)
    {
        // Calculate streamchat
        $streamChat = 'something';
      
        $this->streamChat = $streamChat;
    }

    return $this->streamChat;
}

From the looks of your example previously, you were doing the calculations for streamChat outside of the entity and setting it into the entity, and that's the difference - with the entities, you're trying to make your code as portable and reusable as possible by putting these kind of calculations inside the entity.

Since you're essentially creating a fake property, pretending stream_chat is a column in your database, you'd do the calculations inside the entity. That means if I wanted to integrate with your mod, I wouldn't need to copy all your OTHER code in order to get the necessary data to calculate stream_chat, then set it into the entity, then get it later in the template.

That leads to code duplication as soon as you need to access your Stream entity in more than one location :)


Fillip
FYI, XenForo 2.x entities have built in caching support.

PHP:
protected $streamChat;

public function getStreamChat()
{
        // Calculate streamchat
        $streamChat = 'something';
      
        return $streamChat;
}

public static function getStructure(Structure $structure)
{
...

        $structure->getters = [
            'StreamChat' => true
        ];
...
}

Getters can have a structure like
Code:
'StreamChat' => ['getter' => 'getStreamChat', 'cache' => true]
.
 
Okay, I got another complication... Can I order a fetch based on a getter?

For instance, I have a getter:
Code:
    public function getStreamFeatured()
    {
        return ($this->Game->game_featured || $this->Channel->channel_featured) ? 1 : 0;
    }


Then in my controller I have:
Code:
$streamRepo->findStreams()
    ->limitByPage($page, $perPage)
    ->order('stream_featured', 'DESC')
    ->order('stream_viewers', 'DESC')
    ->fetch();


This however, returns an error:
InvalidArgumentException: Unknown column stream_featured on EWR\Rio:Stream in src/XF/Mvc/Entity/Finder.php at line 1394


I was able to do this in XF1 with a CONCAT in a select:
Code:
SELECT EWRrio_games.*, EWRrio_channels.*, EWRrio_streams.*,
    IF(EWRrio_games.game_featured, EWRrio_games.game_featured,
        IF(EWRrio_channels.channel_featured, EWRrio_channels.channel_featured, 0)
    ) AS stream_featured
 
Okay, I got another complication... Can I order a fetch based on a getter?

For instance, I have a getter:
Code:
    public function getStreamFeatured()
    {
        return ($this->Game->game_featured || $this->Channel->channel_featured) ? 1 : 0;
    }


Then in my controller I have:
Code:
$streamRepo->findStreams()
    ->limitByPage($page, $perPage)
    ->order('stream_featured', 'DESC')
    ->order('stream_viewers', 'DESC')
    ->fetch();


This however, returns an error:



I was able to do this in XF1 with a CONCAT in a select:
Code:
SELECT EWRrio_games.*, EWRrio_channels.*, EWRrio_streams.*,
    IF(EWRrio_games.game_featured, EWRrio_games.game_featured,
        IF(EWRrio_channels.channel_featured, EWRrio_channels.channel_featured, 0)
    ) AS stream_featured
I would recommend you change your code and add a stream_featured column on the streams table.

Then, whenever you change the contents of the channel_featured or game_featured columns, also update the stream_featured column.

You should do this with _postSave functions in your Channel and Game entities.

I’m on mobile right now so I can’t pseudocode, but hopefully you get where I’m going with this :)

If not, let me know your relations between those 3 tables.


Fillip
 
I would recommend you change your code and add a stream_featured column on the streams table.

Then, whenever you change the contents of the channel_featured or game_featured columns, also update the stream_featured column.

You should do this with _postSave functions in your Channel and Game entities.

I’m on mobile right now so I can’t pseudocode, but hopefully you get where I’m going with this :)

If not, let me know your relations between those 3 tables.


Fillip
Yeah... a simple solution... one I didn't want to do because of the amount of extra queries it would add. This is how I did it:
Code:
\XF::db()->emptyTable('EWRrio_streams');

if (!empty($streams))
{
    \XF::db()->insertBulk('EWRrio_streams', $streams);
   
    $fGames = \XF::finder('EWR\Rio:Game')->where('game_featured', '1')->fetch();
    foreach ($fGames AS $fGame)
    {
        \XF::db()->update('EWRrio_streams', ['stream_featured'=>1], 'game_id='.$fGame['game_id']);
    }
}
 
Is it possible to do a COUNT() and GROUP BY with the Finder system?

I want to do something like this:
Code:
SELECT games.*, COUNT(streams.game_id)
    FROM games
        INNER JOIN streams ON (streams.game_id = games.game_id)
GROUP BY streams.game_id
 
Top Bottom