1
0

Comment.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  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. * @version 1.2.1
  11. */
  12. namespace PrivateBin\Model;
  13. use Exception;
  14. use Identicon\Identicon;
  15. use PrivateBin\Persistence\TrafficLimiter;
  16. use PrivateBin\FormatV2;
  17. use PrivateBin\Vizhash16x16;
  18. /**
  19. * Comment
  20. *
  21. * Model of a PrivateBin comment.
  22. */
  23. class Comment extends AbstractModel
  24. {
  25. /**
  26. * Instance's parent.
  27. *
  28. * @access private
  29. * @var Paste
  30. */
  31. private $_paste;
  32. /**
  33. * Get comment data.
  34. *
  35. * @access public
  36. * @throws Exception
  37. * @return \stdClass
  38. */
  39. public function get()
  40. {
  41. // @todo add support to read specific comment
  42. $comments = $this->_store->readComments($this->getPaste()->getId());
  43. foreach ($comments as $comment) {
  44. if (
  45. $comment->parentid == $this->getParentId() &&
  46. $comment->id == $this->getId()
  47. ) {
  48. $this->_data = $comment;
  49. break;
  50. }
  51. }
  52. return $this->_data;
  53. }
  54. /**
  55. * Store the comment's data.
  56. *
  57. * @access public
  58. * @throws Exception
  59. */
  60. public function store()
  61. {
  62. // Make sure paste exists.
  63. $pasteid = $this->getPaste()->getId();
  64. if (!$this->getPaste()->exists()) {
  65. throw new Exception('Invalid data.', 67);
  66. }
  67. // Make sure the discussion is opened in this paste and in configuration.
  68. if (!$this->getPaste()->isOpendiscussion() || !$this->_conf->getKey('discussion')) {
  69. throw new Exception('Invalid data.', 68);
  70. }
  71. // Check for improbable collision.
  72. if ($this->exists()) {
  73. throw new Exception('You are unlucky. Try again.', 69);
  74. }
  75. $this->_data->meta->postdate = time();
  76. // store comment
  77. if (
  78. $this->_store->createComment(
  79. $pasteid,
  80. $this->getParentId(),
  81. $this->getId(),
  82. json_decode(json_encode($this->_data), true)
  83. ) === false
  84. ) {
  85. throw new Exception('Error saving comment. Sorry.', 70);
  86. }
  87. }
  88. /**
  89. * Delete the comment.
  90. *
  91. * @access public
  92. * @throws Exception
  93. */
  94. public function delete()
  95. {
  96. throw new Exception('To delete a comment, delete its parent paste', 64);
  97. }
  98. /**
  99. * Test if comment exists in store.
  100. *
  101. * @access public
  102. * @return bool
  103. */
  104. public function exists()
  105. {
  106. return $this->_store->existsComment(
  107. $this->getPaste()->getId(),
  108. $this->getParentId(),
  109. $this->getId()
  110. );
  111. }
  112. /**
  113. * Set paste.
  114. *
  115. * @access public
  116. * @param Paste $paste
  117. * @throws Exception
  118. */
  119. public function setPaste(Paste $paste)
  120. {
  121. $this->_paste = $paste;
  122. $this->_data->meta->pasteid = $paste->getId();
  123. }
  124. /**
  125. * Get paste.
  126. *
  127. * @access public
  128. * @return Paste
  129. */
  130. public function getPaste()
  131. {
  132. return $this->_paste;
  133. }
  134. /**
  135. * Set parent ID.
  136. *
  137. * @access public
  138. * @param string $id
  139. * @throws Exception
  140. */
  141. public function setParentId($id)
  142. {
  143. if (!self::isValidId($id)) {
  144. throw new Exception('Invalid paste ID.', 65);
  145. }
  146. $this->_data->meta->parentid = $id;
  147. }
  148. /**
  149. * Get parent ID.
  150. *
  151. * @access public
  152. * @return string
  153. */
  154. public function getParentId()
  155. {
  156. if (!property_exists($this->_data->meta, 'parentid')) {
  157. $this->_data->meta->parentid = '';
  158. }
  159. return $this->_data->meta->parentid;
  160. }
  161. /**
  162. * Set nickname.
  163. *
  164. * @access public
  165. * @param string $nickname
  166. * @throws Exception
  167. */
  168. public function setNickname($nickname)
  169. {
  170. if (!FormatV2::isValid($nickname)) {
  171. throw new Exception('Invalid data.', 66);
  172. }
  173. $this->_data->meta->nickname = $nickname;
  174. // If a nickname is provided, we generate an icon based on a SHA512 HMAC
  175. // of the users IP. (We assume that if the user did not enter a nickname,
  176. // the user wants to be anonymous and we will not generate an icon.)
  177. $icon = $this->_conf->getKey('icon');
  178. if ($icon != 'none') {
  179. $pngdata = '';
  180. $hmac = TrafficLimiter::getHash();
  181. if ($icon == 'identicon') {
  182. $identicon = new Identicon();
  183. $pngdata = $identicon->getImageDataUri($hmac, 16);
  184. } elseif ($icon == 'vizhash') {
  185. $vh = new Vizhash16x16();
  186. $pngdata = 'data:image/png;base64,' . base64_encode(
  187. $vh->generate($hmac)
  188. );
  189. }
  190. if ($pngdata != '') {
  191. $this->_data->meta->vizhash = $pngdata;
  192. }
  193. }
  194. // Once the icon is generated, we do not keep the IP address hash.
  195. }
  196. }