phpsortingcakephpcakephp-3.x

How combine data from two models and sort them by created date (time object) in cakephp?


The models Messages and Files belongs to Conversations. Both Messages and Files have a created DATETIME field.

I want to select all messages and files that belongs to a specific conversation and them into the same feed based on created date.

How?

This is what I have tried.

//Get us a conversation with all Files and Messages
$conversations = $this->Users->Conversations->find();
$conversations->contain([
  'Files' => function ($q)
             {
               return $q->order('Files.created ASC');
             },
  'Messages' => function ($q)
                {
                  return $q->order('Messages.created ASC');
                },
  'Messages.Users',
  ]);
  $conversations->where(['Conversations.id' => $conversationID]);

//Now we want to sort the files an messages according to created date
$converted = $conversations->toArray();
$allEntities = array_merge($converted[0]['files'],$converted[0]['messages']);
$allEntities = Hash::sort($allEntities,'{n}.created','asc');

That works like a charm on any field that is not a time object, for instance id.

I have read this question Combining lists of data from Multiple Models and sort them by date created in cakephp

but since cakephp 3 converts datetime into time objects i can't get Hash::sort to work.

One way could be if it's possible to turn the time object off somehow. It mostly makes things more troublesome for me.

Any suggestions?


Solution

  • Any suggestions?

    Link your file(s) directly to the messages table instead of linking them to the conversation. You can use the messages body field (or whatever you call the field that holds the message) to serialize any data into it (in case you want to translate the values later for example) or just have a text string in it "Foo send File Bar."

    If you add a message_type field to your messages table you can use a string in that field to identify the kind of message, for example system.

    Your current architecture just makes it on the DB and app level pretty complicated, much more complicated than necessary.