src/models/MessageReceiver.php
<?php
namespace bizley\podium\models;
use bizley\podium\db\Query;
use bizley\podium\log\Log;
use bizley\podium\models\db\MessageReceiverActiveRecord;
use bizley\podium\models\User;
use bizley\podium\Podium;
use Exception;
use Yii;
use yii\data\ActiveDataProvider;
/**
* MessageReceiver model
*
* @author Paweł Bizley Brzozowski <pawel@positive.codes>
* @since 0.1
*/
class MessageReceiver extends MessageReceiverActiveRecord
{
/**
* Removes message.
* @return bool
*/
public function remove()
{
$transaction = static::getDb()->beginTransaction();
try {
$clearCache = false;
if ($this->receiver_status == self::STATUS_NEW) {
$clearCache = true;
}
$deleteParent = null;
$this->scenario = 'remove';
if ($this->message->sender_status != Message::STATUS_DELETED) {
$this->receiver_status = self::STATUS_DELETED;
if (!$this->save()) {
throw new Exception('Message status changing error!');
}
if ($clearCache) {
Podium::getInstance()->podiumCache->deleteElement('user.newmessages', $this->receiver_id);
}
$transaction->commit();
return true;
}
if ($this->message->sender_status == Message::STATUS_DELETED && count($this->message->messageReceivers) == 1) {
$deleteParent = $this->message;
}
if (!$this->delete()) {
throw new Exception('Message removing error!');
}
if ($clearCache) {
Podium::getInstance()->podiumCache->deleteElement('user.newmessages', $this->receiver_id);
}
if ($deleteParent) {
if (!$deleteParent->delete()) {
throw new Exception('Sender message deleting error!');
}
}
$transaction->commit();
return true;
} catch (Exception $e) {
$transaction->rollBack();
Log::error($e->getMessage(), $this->id, __METHOD__);
}
return false;
}
/**
* Searches for messages.
* @return ActiveDataProvider
*/
public function search($params)
{
$subquery = (new Query())
->select(['m2.replyto'])
->from(['m1' => Message::tableName()])
->leftJoin(['m2' => Message::tableName()], 'm1.replyto = m2.id')
->where(['is not', 'm2.replyto', null]);
$query = static::find()->where(['and',
['receiver_id' => User::loggedId()],
['!=', 'receiver_status', self::STATUS_DELETED],
['not in', 'message_id', $subquery]
]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->sort->attributes['senderName'] = [
'asc' => [
User::tableName() . '.username' => SORT_ASC,
User::tableName() . '.id' => SORT_ASC
],
'desc' => [
User::tableName() . '.username' => SORT_DESC,
User::tableName() . '.id' => SORT_DESC
],
'default' => SORT_ASC
];
$dataProvider->sort->defaultOrder = ['id' => SORT_DESC];
$dataProvider->pagination->pageSize = Yii::$app->session->get('per-page', 20);
if (!($this->load($params) && $this->validate())) {
$dataProvider->query->joinWith(['message' => function ($q) {
$q->joinWith(['sender']);
}]);
return $dataProvider;
}
$dataProvider->query->andFilterWhere(['like', 'topic', $this->topic]);
if (preg_match('/^(forum|orum|rum|um|m)?#([0-9]+)$/', strtolower($this->senderName), $matches)) {
$dataProvider->query->joinWith(['message' => function ($q) use ($matches) {
$q->joinWith(['sender' => function ($q) use ($matches) {
$q->andFilterWhere(['and',
[User::tableName() . '.id' => $matches[2]],
['or',
['username' => ''],
['username' => null]
]
]);
}]);
}]);
} elseif (preg_match('/^([0-9]+)$/', $this->senderName, $matches)) {
$dataProvider->query->joinWith(['message' => function ($q) use ($matches) {
$q->joinWith(['sender' => function ($q) use ($matches) {
$q->andFilterWhere(['or',
['like', 'username', $this->senderName],
['and',
['id' => $matches[1]],
['or',
['username' => ''],
['username' => null]
]
],
]);
}]);
}]);
} else {
$dataProvider->query->joinWith(['message' => function ($q) {
$q->joinWith(['sender' => function ($q) {
$q->andFilterWhere(['like', User::tableName() . '.username', $this->senderName]);
}]);
}]);
}
return $dataProvider;
}
/**
* Marks message read.
* @since 0.2
*/
public function markRead()
{
if ($this->receiver_status == Message::STATUS_NEW) {
$this->receiver_status = Message::STATUS_READ;
if ($this->save()) {
Podium::getInstance()->podiumCache->deleteElement('user.newmessages', $this->receiver_id);
}
}
}
}