Comment.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php declare(strict_types=1);
  2. /**
  3. * PrivateBin
  4. *
  5. * a zero-knowledge paste bin
  6. *
  7. * @link https://github.com/PrivateBin/PrivateBin
  8. * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  9. * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
  10. */
  11. namespace PrivateBin\Model;
  12. use Exception;
  13. use Identicon\Identicon;
  14. use Jdenticon\Identicon as Jdenticon;
  15. use PrivateBin\Persistence\TrafficLimiter;
  16. use PrivateBin\Vizhash16x16;
  17. /**
  18. * Comment
  19. *
  20. * Model of a PrivateBin comment.
  21. */
  22. class Comment extends AbstractModel
  23. {
  24. /**
  25. * Instance's parent.
  26. *
  27. * @access private
  28. * @var Paste
  29. */
  30. private $_paste;
  31. /**
  32. * Store the comment's data.
  33. *
  34. * @access public
  35. * @throws Exception
  36. */
  37. public function store()
  38. {
  39. // Make sure paste exists.
  40. $pasteid = $this->getPaste()->getId();
  41. if (!$this->getPaste()->exists()) {
  42. throw new Exception('Invalid data.', 67);
  43. }
  44. // Make sure the discussion is opened in this paste and in configuration.
  45. if (!$this->getPaste()->isOpendiscussion() || !$this->_conf->getKey('discussion')) {
  46. throw new Exception('Invalid data.', 68);
  47. }
  48. // Check for improbable collision.
  49. if ($this->exists()) {
  50. throw new Exception('You are unlucky. Try again.', 69);
  51. }
  52. $this->_data['meta']['created'] = time();
  53. // store comment
  54. if (
  55. $this->_store->createComment(
  56. $pasteid,
  57. $this->getParentId(),
  58. $this->getId(),
  59. $this->_data
  60. ) === false
  61. ) {
  62. throw new Exception('Error saving comment. Sorry.', 70);
  63. }
  64. }
  65. /**
  66. * Delete the comment.
  67. *
  68. * @access public
  69. * @throws Exception
  70. */
  71. public function delete()
  72. {
  73. throw new Exception('To delete a comment, delete its parent paste', 64);
  74. }
  75. /**
  76. * Test if comment exists in store.
  77. *
  78. * @access public
  79. * @return bool
  80. */
  81. public function exists()
  82. {
  83. return $this->_store->existsComment(
  84. $this->getPaste()->getId(),
  85. $this->getParentId(),
  86. $this->getId()
  87. );
  88. }
  89. /**
  90. * Set paste.
  91. *
  92. * @access public
  93. * @param Paste $paste
  94. * @throws Exception
  95. */
  96. public function setPaste(Paste $paste)
  97. {
  98. $this->_paste = $paste;
  99. $this->_data['pasteid'] = $paste->getId();
  100. }
  101. /**
  102. * Get paste.
  103. *
  104. * @access public
  105. * @return Paste
  106. */
  107. public function getPaste()
  108. {
  109. return $this->_paste;
  110. }
  111. /**
  112. * Set parent ID.
  113. *
  114. * @access public
  115. * @param string $id
  116. * @throws Exception
  117. */
  118. public function setParentId($id)
  119. {
  120. if (!self::isValidId($id)) {
  121. throw new Exception('Invalid paste ID.', 65);
  122. }
  123. $this->_data['parentid'] = $id;
  124. }
  125. /**
  126. * Get parent ID.
  127. *
  128. * @access public
  129. * @return string
  130. */
  131. public function getParentId()
  132. {
  133. if (!array_key_exists('parentid', $this->_data)) {
  134. $this->_data['parentid'] = $this->getPaste()->getId();
  135. }
  136. return $this->_data['parentid'];
  137. }
  138. /**
  139. * Sanitizes data to conform with current configuration.
  140. *
  141. * @access protected
  142. * @param array $data
  143. * @return array
  144. */
  145. protected function _sanitize(array $data)
  146. {
  147. // we generate an icon based on a SHA512 HMAC of the users IP, if configured
  148. $icon = $this->_conf->getKey('icon');
  149. if ($icon != 'none') {
  150. $pngdata = '';
  151. $hmac = TrafficLimiter::getHash();
  152. if ($icon == 'identicon') {
  153. $identicon = new Identicon();
  154. $pngdata = $identicon->getImageDataUri($hmac, 16);
  155. } elseif ($icon == 'jdenticon') {
  156. $jdenticon = new Jdenticon(array(
  157. 'hash' => $hmac,
  158. 'size' => 16,
  159. 'style' => array(
  160. 'backgroundColor' => '#fff0', // fully transparent, for dark mode
  161. 'padding' => 0,
  162. ),
  163. ));
  164. $pngdata = $jdenticon->getImageDataUri('png');
  165. } elseif ($icon == 'vizhash') {
  166. $vh = new Vizhash16x16();
  167. $pngdata = 'data:image/png;base64,' . base64_encode(
  168. $vh->generate($hmac)
  169. );
  170. }
  171. if ($pngdata != '') {
  172. if (!array_key_exists('meta', $data)) {
  173. $data['meta'] = array();
  174. }
  175. $data['meta']['icon'] = $pngdata;
  176. }
  177. }
  178. return $data;
  179. }
  180. }