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