diff --git a/lib/model/doctrine/PluginDeletedMessageTable.class.php b/lib/model/doctrine/PluginDeletedMessageTable.class.php index f0dc372..4c4d8b6 100644 --- a/lib/model/doctrine/PluginDeletedMessageTable.class.php +++ b/lib/model/doctrine/PluginDeletedMessageTable.class.php @@ -121,8 +121,26 @@ public function deleteMessage($member_id, $message_id, $object_name) $deleted_message->save(); } $message->setIsDeleted(1); - /* @todo 完全削除の場合ファイルも削除すべきかも */ $message->save(); + + if ($message instanceof DeletedMessage) + { + if ($message->message_send_list_id !== 0) + { + $messageSendList = Doctrine_Core::getTable('MessageSendList')->find($message->message_send_list_id); + $sendMessageData = $messageSendList->SendMessageData; + } + else + { + $sendMessageData = Doctrine_Core::getTable('SendMessageData')->find($message->message_id); + } + + if ($sendMessageData) + { + $sendMessageData->purgeIfOrphaned(); + } + } + return true; } diff --git a/lib/model/doctrine/PluginSendMessageData.class.php b/lib/model/doctrine/PluginSendMessageData.class.php index c42ed62..db148ed 100644 --- a/lib/model/doctrine/PluginSendMessageData.class.php +++ b/lib/model/doctrine/PluginSendMessageData.class.php @@ -183,6 +183,42 @@ public function getDecoratedMessageBody() return $instance->$methodName($this); } + public function purgeIfOrphaned(Doctrine_Connection $conn = null) + { + if (!$this->is_deleted) + { + return false; + } + + $messageSendLists = Doctrine_Core::getTable('MessageSendList')->findByMessageId($this->id); + foreach ($messageSendLists as $messageSendList) + { + if (!$messageSendList->is_deleted) + { + return false; + } + } + + $deletedMessages = Doctrine_Core::getTable('DeletedMessage')->createQuery('dm') + ->andWhereIn('dm.message_send_list_id', $messageSendLists->getPrimaryKeys()) + ->orWhere('dm.message_id = ?', $this->id) + ->execute(); + foreach ($deletedMessages as $deletedMessage) + { + if (!$deletedMessage->is_deleted) + { + return false; + } + } + + // 孤立したメッセージ + $messageSendLists->delete($conn); + $deletedMessages->delete($conn); + $this->delete($conn); + + return true; + } + public function preUpdate($event) { if (in_array('is_send', $this->_modified) && 1 == $this->_data['is_send']) @@ -195,6 +231,14 @@ public function preUpdate($event) } } + public function preDelete($event) + { + foreach ($this->MessageFile as $messageFile) + { + $messageFile->delete(); + } + } + public function postHydrate($event) { $object = $event->data; diff --git a/test/fixtures/010_message.yml b/test/fixtures/010_message.yml index 24fc59c..9b143bc 100644 --- a/test/fixtures/010_message.yml +++ b/test/fixtures/010_message.yml @@ -72,6 +72,21 @@ SendMessageData: return_message_id: 0 MessageType: message_type_default foreign_id: 0 + message_with_file: + id: 7 + Member: first_member + subject: message7 subject + body: message7 body + MessageType: message_type_default + +MessageFile: + message7_file1: + id: 1 + SendMessageData: message_with_file + File: + name: message7_file1 + type: text/plain + FileBin: { bin: ~ } MessageSendList: send_message_send_list: diff --git a/test/unit/model/MessageFileTest.php b/test/unit/model/MessageFileTest.php new file mode 100644 index 0000000..d9adca1 --- /dev/null +++ b/test/unit/model/MessageFileTest.php @@ -0,0 +1,24 @@ + +diag('MessageFile: Cascading Delete'); +$conn->beginTransaction(); + +$messageFile = Doctrine_Core::getTable('MessageFile')->find(1); +$fileId = $messageFile->file_id; + +$messageFile->delete($conn); + +$t->ok(!Doctrine_Core::getTable('MessageFile')->find($messageFile->id), 'message_file is deleted.'); +$t->ok(!Doctrine_Core::getTable('File')->find($fileId), 'file is deleted.'); +$t->ok(!Doctrine_Core::getTable('FileBin')->find($fileId), 'file_bin is deleted.'); + +$conn->rollback(); diff --git a/test/unit/model/SendMessageDataTest.php b/test/unit/model/SendMessageDataTest.php new file mode 100644 index 0000000..6833f91 --- /dev/null +++ b/test/unit/model/SendMessageDataTest.php @@ -0,0 +1,181 @@ +findOneByTypeName('message'); + +//------------------------------------------------------------ +$t->diag('SendMessageData: Cascading Delete'); +$conn->beginTransaction(); + +$sendMessageData = Doctrine_Core::getTable('SendMessageData')->find(7); +$messageFile = $sendMessageData->MessageFile[0]; +$fileId = $messageFile->file_id; + +$sendMessageData->delete($conn); + +$t->ok(!Doctrine_Core::getTable('SendMessageData')->find($sendMessageData->id), 'message is deleted.'); +$t->ok(!Doctrine_Core::getTable('MessageFile')->find($messageFile->id), 'message_file is deleted.'); +$t->ok(!Doctrine_Core::getTable('File')->find($fileId), 'file is deleted.'); +$t->ok(!Doctrine_Core::getTable('FileBin')->find($fileId), 'file_bin is deleted.'); + +$conn->rollback(); + +//------------------------------------------------------------ +$t->diag('SendMessageData::purgeIfOrphaned() [message.is_deleted != 1]'); +$conn->beginTransaction(); + +$sendMessageData = Doctrine_Core::getTable('SendMessageData')->create(array( + 'member_id' => 1, + 'message_type_id' => $messageTypeDefault->id, + 'subject' => 'messageA', + 'body' => 'messageA body', + 'is_deleted' => false, +)); +$sendMessageData->save($conn); + +// message.is_deleted が 1 ではないので削除されない +$sendMessageData->purgeIfOrphaned($conn); + +$t->ok(Doctrine_Core::getTable('SendMessageData')->find($sendMessageData->id)); + +$conn->rollback(); + +//------------------------------------------------------------ +$t->diag('SendMessageData::purgeIfOrphaned() [message_send_list.is_deleted != 1]'); +$conn->beginTransaction(); + +$sendMessageData = Doctrine_Core::getTable('SendMessageData')->create(array( + 'member_id' => 1, + 'message_type_id' => $messageTypeDefault->id, + 'subject' => 'messageA', + 'body' => 'messageA body', + 'is_deleted' => true, // 送信者側からは削除済み +)); +$sendMessageData->save($conn); +$messageSendList = Doctrine_Core::getTable('MessageSendList')->create(array( + 'message_id' => $sendMessageData->id, + 'member_id' => 2, + 'is_deleted' => false, +)); +$messageSendList->save($conn); + +// message_send_list.is_deleted が 1 ではないので削除されない +$sendMessageData->purgeIfOrphaned($conn); + +$t->ok(Doctrine_Core::getTable('SendMessageData')->find($sendMessageData->id)); + +$conn->rollback(); + +//------------------------------------------------------------ +$t->diag('SendMessageData::purgeIfOrphaned() [deleted_message.is_deleted != 1 (sender)]'); +$conn->beginTransaction(); + +$sendMessageData = Doctrine_Core::getTable('SendMessageData')->create(array( + 'member_id' => 1, + 'message_type_id' => $messageTypeDefault->id, + 'subject' => 'messageA', + 'body' => 'messageA body', + 'is_deleted' => true, // 送信者側からは削除済み +)); +$sendMessageData->save($conn); +$messageSendList = Doctrine_Core::getTable('MessageSendList')->create(array( + 'message_id' => $sendMessageData->id, + 'member_id' => 2, + 'is_deleted' => true, // 受信者側からも削除済み +)); +$messageSendList->save($conn); +$deletedMessage = Doctrine_Core::getTable('DeletedMessage')->create(array( + 'member_id' => 1, + 'message_id' => $sendMessageData->id, + 'message_send_list_id' => 0, + 'is_deleted' => false, // 送信者側のゴミ箱から未削除 +)); +$deletedMessage->save($conn); + +// 送信者側の deleted_message.is_deleted が 1 ではないので削除されない +$sendMessageData->purgeIfOrphaned($conn); + +$t->ok(Doctrine_Core::getTable('SendMessageData')->find($sendMessageData->id)); + +$conn->rollback(); + +//------------------------------------------------------------ +$t->diag('SendMessageData::purgeIfOrphaned() [deleted_message.is_deleted != 1 (receiver)]'); +$conn->beginTransaction(); + +$sendMessageData = Doctrine_Core::getTable('SendMessageData')->create(array( + 'member_id' => 1, + 'message_type_id' => $messageTypeDefault->id, + 'subject' => 'messageA', + 'body' => 'messageA body', + 'is_deleted' => true, // 送信者側からは削除済み +)); +$sendMessageData->save($conn); +$messageSendList = Doctrine_Core::getTable('MessageSendList')->create(array( + 'message_id' => $sendMessageData->id, + 'member_id' => 2, + 'is_deleted' => true, // 受信者側からも削除済み +)); +$messageSendList->save($conn); +$deletedMessage = Doctrine_Core::getTable('DeletedMessage')->create(array( + 'member_id' => 2, + 'message_id' => 0, + 'message_send_list_id' => $messageSendList->id, + 'is_deleted' => false, // 受信者側のゴミ箱から未削除 +)); +$deletedMessage->save($conn); + +// 受信者側の deleted_message.is_deleted が 1 ではないので削除されない +$sendMessageData->purgeIfOrphaned($conn); + +$t->ok(Doctrine_Core::getTable('SendMessageData')->find($sendMessageData->id)); + +$conn->rollback(); + +//------------------------------------------------------------ +$t->diag('SendMessageData::purgeIfOrphaned() [orphaned message]'); +$conn->beginTransaction(); + +$sendMessageData = Doctrine_Core::getTable('SendMessageData')->create(array( + 'member_id' => 1, + 'message_type_id' => $messageTypeDefault->id, + 'subject' => 'messageA', + 'body' => 'messageA body', + 'is_deleted' => true, // 送信者側からは削除済み +)); +$sendMessageData->save($conn); +$messageSendList = Doctrine_Core::getTable('MessageSendList')->create(array( + 'message_id' => $sendMessageData->id, + 'member_id' => 2, + 'is_deleted' => true, // 受信者側からも削除済み +)); +$messageSendList->save($conn); +$deletedMessage1 = Doctrine_Core::getTable('DeletedMessage')->create(array( + 'member_id' => 1, + 'message_id' => $sendMessageData->id, + 'message_send_list_id' => 0, + 'is_deleted' => true, // 送信者側のゴミ箱からも削除済み +)); +$deletedMessage1->save($conn); +$deletedMessage2 = Doctrine_Core::getTable('DeletedMessage')->create(array( + 'member_id' => 2, + 'message_id' => 0, + 'message_send_list_id' => $messageSendList->id, + 'is_deleted' => true, // 受信者側のゴミ箱からも削除済み +)); +$deletedMessage2->save($conn); + +// 削除対象 +$sendMessageData->purgeIfOrphaned($conn); + +$t->ok(!Doctrine_Core::getTable('SendMessageData')->find($sendMessageData->id)); + +$conn->rollback();