Messaging.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. <?php
  2. /**
  3. *
  4. * PHP Pro Bid $Id$ +UjQ0FR18P5+7L/CT5xJw6MQq0IH5RQawawSM7oSu5g=
  5. *
  6. * @link http://www.phpprobid.com
  7. * @copyright Copyright (c) 2017 Online Ventures Software & CodeCube SRL
  8. * @license http://www.phpprobid.com/license Commercial License
  9. *
  10. * @version 7.9 [rev.7.9.01]
  11. */
  12. /**
  13. * messaging table service class
  14. */
  15. namespace Ppb\Service;
  16. use Ppb\Db\Table\Messaging as MessagingTable,
  17. Cube\Db\Expr;
  18. class Messaging extends AbstractService
  19. {
  20. /**
  21. * messaging topics types
  22. */
  23. const PUBLIC_QUESTION = 'public_question';
  24. const PRIVATE_QUESTION = 'private_question';
  25. const SALE_TRANSACTION = 'sale_transaction';
  26. const ADMIN_MESSAGE = 'admin_message';
  27. const ABUSE_REPORT_USER = 'abuse_report_user';
  28. const ABUSE_REPORT_LISTING = 'abuse_report_listing';
  29. const REFUND_REQUEST = 'refund_request';
  30. const TITLE_RE = 'Re:';
  31. const TITLE_FWD = 'Fwd:';
  32. /**
  33. *
  34. * allowed topics types and their automatic titles
  35. *
  36. * @var array
  37. */
  38. protected $_topicTypes = array(
  39. self::PUBLIC_QUESTION => array(
  40. 'msg' => 'Public Question - Listing ID: #%s',
  41. 'args' => array('listing_id'),
  42. ),
  43. self::PRIVATE_QUESTION => array(
  44. 'msg' => 'Private Message - Listing ID: #%s',
  45. 'args' => array('listing_id'),
  46. ),
  47. self::SALE_TRANSACTION => array(
  48. 'msg' => 'Sale Transaction - Invoice ID: #%s',
  49. 'args' => array('sale_id'),
  50. ),
  51. self::ADMIN_MESSAGE => array(
  52. 'msg' => 'Message from Site Admin',
  53. 'args' => array(),
  54. ),
  55. self::ABUSE_REPORT_USER => array(
  56. 'msg' => 'Abuse Report - User: %s',
  57. 'args' => array('username'),
  58. ),
  59. self::ABUSE_REPORT_LISTING => array(
  60. 'msg' => 'Abuse Report - Listing ID: %s',
  61. 'args' => array('listing_id'),
  62. ),
  63. self::REFUND_REQUEST => array(
  64. 'msg' => 'Refund Request - Invoice ID: #%s',
  65. 'args' => array('sale_id'),
  66. ),
  67. );
  68. protected $_replyPrefixes = array(
  69. self::TITLE_RE,
  70. self::TITLE_FWD,
  71. );
  72. /**
  73. *
  74. * topic type
  75. *
  76. * @var string
  77. */
  78. protected $_topicType = null;
  79. /**
  80. *
  81. * class constructor
  82. */
  83. public function __construct()
  84. {
  85. parent::__construct();
  86. $this->setTable(
  87. new MessagingTable());
  88. }
  89. /**
  90. *
  91. * set topic types
  92. *
  93. * @param array $topicTypes
  94. *
  95. * @return $this
  96. */
  97. public function setTopicTypes($topicTypes)
  98. {
  99. $this->_topicTypes = $topicTypes;
  100. return $this;
  101. }
  102. /**
  103. *
  104. * get topic types
  105. *
  106. * @return array
  107. */
  108. public function getTopicTypes()
  109. {
  110. return $this->_topicTypes;
  111. }
  112. /**
  113. *
  114. * set topic type
  115. *
  116. * @param string $topicType
  117. *
  118. * @return $this
  119. * @throws \InvalidArgumentException
  120. */
  121. public function setTopicType($topicType)
  122. {
  123. if (!array_key_exists($topicType, $this->_topicTypes)) {
  124. throw new \InvalidArgumentException(
  125. sprintf("The messaging topic type '%s' is not allowed.", $topicType));
  126. }
  127. $this->_topicType = $topicType;
  128. return $this;
  129. }
  130. /**
  131. *
  132. * get topic type
  133. *
  134. * @return string
  135. */
  136. public function getTopicType()
  137. {
  138. return $this->_topicType;
  139. }
  140. /**
  141. *
  142. * create or update a row in the messaging table
  143. * if topic_id is null, update data and topic_id = id
  144. *
  145. * @param array $post
  146. *
  147. * @return int the id of the created/edited message
  148. */
  149. public function save($post)
  150. {
  151. $row = null;
  152. $data = $this->_prepareSaveData($post);
  153. if (array_key_exists('id', $data)) {
  154. unset($data['id']);
  155. }
  156. $data['created_at'] = new Expr('now()');
  157. $id = $this->_table->insert($data);
  158. if (!isset($data['topic_id'])) {
  159. $row = $this->findBy('id', $id);
  160. $row->save(array(
  161. 'topic_id' => $id,
  162. ));
  163. }
  164. if (!empty($post['sale_id'])) {
  165. $salesService = new Sales();
  166. $sale = $salesService->findBy('id', (int)$post['sale_id']);
  167. if (!$sale['messaging_topic_id']) {
  168. $sale->save(array(
  169. 'messaging_topic_id' => $id,
  170. ));
  171. }
  172. }
  173. return $id;
  174. }
  175. public function archive($id, $userId, $filter)
  176. {
  177. $updateColumn = ($filter == 'sent') ? 'sender_deleted' : 'receiver_deleted';
  178. $userColumn = ($filter == 'sent') ? 'sender_id' : 'receiver_id';
  179. $adapter = $this->_table->getAdapter();
  180. $where = array(
  181. $adapter->quoteInto('id IN (?)', $id),
  182. $adapter->quoteInto("{$userColumn} = ?", $userId)
  183. );
  184. $this->_table->update(array($updateColumn => 1), $where);
  185. }
  186. /**
  187. *
  188. * messages can only be deleted by the administrator, and only from the admin area
  189. *
  190. * @param int|array $id sale id
  191. *
  192. * @return int the number of affected rows
  193. */
  194. public function delete($id)
  195. {
  196. return $this->_table->delete(
  197. $this->_table->getAdapter()->quoteInto('id IN (?)', $id));
  198. }
  199. /**
  200. *
  201. * prepare save data
  202. *
  203. * @param array $data
  204. *
  205. * @return array
  206. */
  207. protected function _prepareSaveData($data = array())
  208. {
  209. if (empty($data['topic_id'])) {
  210. if (!empty($data['sale_id'])) {
  211. $salesService = new Sales();
  212. $sale = $salesService->findBy('id', (int)$data['sale_id']);
  213. $data['receiver_id'] = ($data['sender_id'] == $sale['buyer_id']) ? $sale['seller_id'] : $sale['buyer_id'];
  214. }
  215. $data['topic_title'] = $this->generateTopicTitle($data);
  216. }
  217. $data['listing_id'] = (isset($data['public_question'])) ?
  218. (($data['public_question']) ? $data['listing_id'] : null) : null;
  219. $data = parent::_prepareSaveData($data);
  220. return array_filter($data, function ($value) {
  221. return trim($value) != null;
  222. });
  223. }
  224. /**
  225. *
  226. * generate the topic title of a messaging topic
  227. * TODO: review this code for private questions when public questions are disabled
  228. *
  229. * @param array $data
  230. *
  231. * @return string|null
  232. */
  233. public function generateTopicTitle(array $data)
  234. {
  235. if (!empty($data['topic_type'])) {
  236. $this->setTopicType($data['topic_type']);
  237. }
  238. else {
  239. $topicType = $this->getTopicType();
  240. if (!isset($topicType)) {
  241. $publicQuestion = (isset($data['public_question'])) ? $data['public_question'] : null;
  242. $this->setTopicType(
  243. $publicQuestion ? self::PUBLIC_QUESTION : self::PRIVATE_QUESTION);
  244. }
  245. }
  246. if ($topicType = $this->getTopicType() != null) {
  247. $topicType = $this->_topicTypes[$this->getTopicType()];
  248. $args = array();
  249. foreach ($topicType['args'] as $arg) {
  250. $args[] = isset($data[$arg]) ? $data[$arg] : null;
  251. }
  252. $translate = $this->getTranslate();
  253. return vsprintf($translate->_($topicType['msg']), $args);
  254. }
  255. return null;
  256. }
  257. /**
  258. *
  259. * generate topic reply title
  260. *
  261. * @param $topicId
  262. *
  263. * @return null|string
  264. */
  265. public function generateMessageReplyTitle($topicId)
  266. {
  267. $topic = $this->findBy('id', $topicId);
  268. if ($topic) {
  269. $translate = $this->getTranslate();
  270. $messageTitle = $topic['title'];
  271. foreach ($this->_replyPrefixes as $prefix) {
  272. $messageTitle = str_ireplace($translate->_($prefix), '', $messageTitle);
  273. }
  274. return $translate->_(self::TITLE_RE) . ' ' . trim($messageTitle);
  275. }
  276. return null;
  277. }
  278. }