Passed
Push — master ( 81ba93...c6c854 )
by Michael
03:30
created

AnswerHandler::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
dl 0
loc 10
rs 10
cc 2
nc 2
nop 2
1
<?php
2
3
namespace XoopsModules\Smartfaq;
4
5
/**
6
 * Module: SmartFAQ
7
 * Author: The SmartFactory <www.smartfactory.ca>
8
 * Licence: GNU
9
 */
10
11
use XoopsModules\Smartfaq;
12
13
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
14
15
/**
16
 * Answers handler class.
17
 * This class is responsible for providing data access mechanisms to the data source
18
 * of Answer class objects.
19
 *
20
 * @author  marcan <[email protected]>
21
 * @package SmartFAQ
22
 */
23
class AnswerHandler extends \XoopsPersistableObjectHandler
24
{
25
26
    /**
27
     * @param \XoopsDatabase $db
28
     * @param null|\XoopsModules\Smartfaq\Helper           $helper
29
     */
30
    public function __construct(\XoopsDatabase $db = null, \XoopsModules\Smartfaq\Helper $helper = null)
31
    {
32
        /** @var \XoopsModules\Smartfaq\Helper $this->helper */
33
        if (null === $helper) {
34
            $this->helper = \XoopsModules\Smartfaq\Helper::getInstance();
0 ignored issues
show
Bug Best Practice introduced by
The property helper does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
35
        } else {
36
            $this->helper = $helper;
37
        }
38
        $smartfaqIsAdmin = $this->helper->isUserAdmin();
0 ignored issues
show
Unused Code introduced by
The assignment to $smartfaqIsAdmin is dead and can be removed.
Loading history...
39
        parent::__construct($db, 'smartfaq_answers', Answer::class, 'answerid', 'answer');
40
    }
41
42
43
    /**
44
     * create a new answer
45
     *
46
     * @param  bool $isNew flag the new objects as "new"?
47
     * @return object Answer
48
     */
49
    public function create($isNew = true)
50
    {
51
        $answer = new Smartfaq\Answer();
52
        if ($isNew) {
53
            $answer->setNew();
54
        }
55
56
        return $answer;
57
    }
58
59
    /**
60
     * retrieve an answer
61
     *
62
     * @param  int  $id answerid of the answer
63
     * @param  null $fields
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $fields is correct as it would always require null to be passed?
Loading history...
64
     * @return mixed reference to the <a href='psi_element://sfAnswer'>sfAnswer</a> object, FALSE if failed
65
     */
66
    public function get($id = null, $fields = null)
67
    {
68
        if ((int)$id > 0) {
69
            $sql = 'SELECT * FROM ' . $this->db->prefix('smartfaq_answers') . ' WHERE answerid=' . $id;
70
            if (!$result = $this->db->query($sql)) {
71
                return false;
72
            }
73
74
            $numrows = $this->db->getRowsNum($result);
75
            if (1 == $numrows) {
76
                $answer = new Smartfaq\Answer();
77
                $answer->assignVars($this->db->fetchArray($result));
78
79
                return $answer;
80
            }
81
        }
82
83
        return false;
84
    }
85
86
    /**
87
     * insert a new answer in the database
88
     *
89
     * @param \XoopsObject $answerObj reference to the <a href='psi_element://sfAnswer'>sfAnswer</a> object
90
     * @param  bool        $force
91
     * @return bool        FALSE if failed, TRUE if already present and unchanged or successful
92
     */
93
    public function insert(\XoopsObject $answerObj, $force = false)
94
    {
95
        if ('xoopsmodules\smartfaq\answer' !== mb_strtolower(get_class($answerObj))) {
96
            return false;
97
        }
98
        if (!$answerObj->isDirty()) {
99
            return true;
100
        }
101
        if (!$answerObj->cleanVars()) {
102
            return false;
103
        }
104
105
        foreach ($answerObj->cleanVars as $k => $v) {
106
            ${$k} = $v;
107
        }
108
109
        if ($answerObj->isNew()) {
110
            $sql = sprintf('INSERT INTO `%s` (answerid, `status`, faqid, answer, uid, datesub, notifypub) VALUES (NULL, %u, %u, %s, %u, %u, %u)', $this->db->prefix('smartfaq_answers'), $status, $faqid, $this->db->quoteString($answer), $uid, time(), $notifypub);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $uid seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $faqid seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $answer does not exist. Did you maybe mean $answerObj?
Loading history...
Comprehensibility Best Practice introduced by
The variable $status seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $notifypub seems to be never defined.
Loading history...
111
        } else {
112
            $sql = sprintf('UPDATE `%s` SET STATUS = %u, faqid = %s, answer = %s, uid = %u, datesub = %u, notifypub = %u WHERE answerid = %u', $this->db->prefix('smartfaq_answers'), $status, $faqid, $this->db->quoteString($answer), $uid, $datesub, $notifypub, $answerid);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $datesub seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $answerid does not exist. Did you maybe mean $answerObj?
Loading history...
113
        }
114
115
        if (false !== $force) {
116
            $result = $this->db->queryF($sql);
117
        } else {
118
            $result = $this->db->query($sql);
119
        }
120
121
        if (!$result) {
122
            return false;
123
        }
124
125
        if ($answerObj->isNew()) {
126
            $answerObj->assignVar('answerid', $this->db->getInsertId());
127
        } else {
128
            $answerObj->assignVar('answerid', $answerid);
129
        }
130
131
        return true;
132
    }
133
134
    /**
135
     * delete an answer from the database
136
     *
137
     * @param \XoopsObject $answer reference to the answer to delete
138
     * @param  bool        $force
139
     * @return bool        FALSE if failed.
140
     */
141
    public function delete(\XoopsObject $answer, $force = false)
142
    {
143
        if ('xoopsmodules\smartfaq\answer' !== mb_strtolower(get_class($answer))) {
144
            return false;
145
        }
146
        $sql = sprintf('DELETE FROM `%s` WHERE answerid = %u', $this->db->prefix('smartfaq_answers'), $answer->getVar('answerid'));
0 ignored issues
show
Bug introduced by
It seems like $answer->getVar('answerid') can also be of type array and array; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

146
        $sql = sprintf('DELETE FROM `%s` WHERE answerid = %u', $this->db->prefix('smartfaq_answers'), /** @scrutinizer ignore-type */ $answer->getVar('answerid'));
Loading history...
147
148
        //echo "<br>" . $sql . "<br>";
149
150
        if (false !== $force) {
151
            $result = $this->db->queryF($sql);
152
        } else {
153
            $result = $this->db->query($sql);
154
        }
155
        if (!$result) {
156
            return false;
157
        }
158
159
        return true;
160
    }
161
162
    /**
163
     * delete an answer from the database
164
     *
165
     * @param  object $faqObj reference to the answer to delete
166
     * @return bool   FALSE if failed.
167
     * @internal param bool $force
168
     */
169
    public function deleteFaqAnswers($faqObj)
170
    {
171
        if ('xoopsmodules\smartfaq\faq' !== mb_strtolower(get_class($faqObj))) {
172
            return false;
173
        }
174
        $answers = $this->getAllAnswers($faqObj->faqid());
175
        $result  = true;
176
        foreach ($answers as $answer) {
177
            if (!$this->delete($answer)) {
178
                $result = false;
179
            }
180
        }
181
182
        return $result;
183
    }
184
185
    /**
186
     * retrieve answers from the database
187
     *
188
     * @param  \CriteriaElement $criteria  {@link CriteriaElement} conditions to be met
189
     * @param  bool             $id_as_key use the answerid as key for the array?
190
     * @param  bool             $as_object
191
     * @return array           array of <a href='psi_element://sfAnswer'>sfAnswer</a> objects
192
     */
193
    public function &getObjects(\CriteriaElement $criteria = null, $id_as_key = false, $as_object = true)
194
    {
195
        $ret   = [];
196
        $limit = $start = 0;
197
        $sql   = 'SELECT * FROM ' . $this->db->prefix('smartfaq_answers');
198
        if (isset($criteria) && $criteria instanceof \CriteriaElement) {
199
            $sql .= ' ' . $criteria->renderWhere();
0 ignored issues
show
Bug introduced by
The method renderWhere() does not exist on CriteriaElement. Did you maybe mean render()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

199
            $sql .= ' ' . $criteria->/** @scrutinizer ignore-call */ renderWhere();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
200
            if ('' != $criteria->getSort()) {
201
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
202
            }
203
            $limit = $criteria->getLimit();
204
            $start = $criteria->getStart();
205
        }
206
        //echo "<br>" . $sql . "<br>";
207
        $result = $this->db->query($sql, $limit, $start);
208
        if (!$result) {
209
            return $ret;
210
        }
211
        while (false !== ($myrow = $this->db->fetchArray($result))) {
212
            $answer = new Smartfaq\Answer();
213
            $answer->assignVars($myrow);
214
            if (!$id_as_key) {
215
                $ret[] = &$answer;
216
            } else {
217
                $ret[$myrow['answerid']] = $answer;
218
            }
219
            unset($answer);
220
        }
221
222
        return $ret;
223
    }
224
225
    /**
226
     * retrieve 1 official answer (for now SmartFAQ only allow 1 official answer...)
227
     *
228
     * @param  int $faqid
229
     * @return mixed reference to the <a href='psi_element://sfAnswer'>sfAnswer</a> object, FALSE if failed
230
     */
231
    public function getOfficialAnswer($faqid = 0)
232
    {
233
        $theaAnswers = $this->getAllAnswers($faqid, Constants::SF_AN_STATUS_APPROVED, 1, 0);
234
        $ret         = false;
235
        if (1 == count($theaAnswers)) {
236
            $ret = $theaAnswers[0];
237
        }
238
239
        return $ret;
240
    }
241
242
    /**
243
     * retrieve all answers
244
     *
245
     * @param  int    $faqid
246
     * @param  int    $status
247
     * @param  int    $limit
248
     * @param  int    $start
249
     * @param  string $sort
250
     * @param  string $order
251
     * @return array  array of <a href='psi_element://sfAnswer'>sfAnswer</a> objects
252
     */
253
    public function getAllAnswers(
254
        $faqid = 0,
255
        $status = -1,
256
        $limit = 0,
257
        $start = 0,
258
        $sort = 'datesub',
259
        $order = 'DESC')
260
    {
261
        $hasStatusCriteria = false;
262
        $criteriaStatus    = new \CriteriaCompo();
263
        if (is_array($status)) {
264
            $hasStatusCriteria = true;
265
            foreach ($status as $v) {
266
                $criteriaStatus->add(new \Criteria('status', $v), 'OR');
267
            }
268
        } elseif (-1 != $status) {
269
            $hasStatusCriteria = true;
270
            $criteriaStatus->add(new \Criteria('status', $status), 'OR');
271
        }
272
        $criteriaFaqid = new \Criteria('faqid', $faqid);
273
274
        $criteria = new \CriteriaCompo();
275
        $criteria->add($criteriaFaqid);
276
277
        if ($hasStatusCriteria) {
278
            $criteria->add($criteriaStatus);
279
        }
280
281
        $criteria->setSort($sort);
282
        $criteria->setOrder($order);
283
        $criteria->setLimit($limit);
284
        $criteria->setStart($start);
285
        $ret = $this->getObjects($criteria);
286
287
        return $ret;
288
    }
289
290
    /**
291
     * count answers matching a condition
292
     *
293
     * @param  \CriteriaElement $criteria {@link CriteriaElement} to match
294
     * @return int             count of answers
295
     */
296
    public function getCount(\CriteriaElement $criteria = null)
297
    {
298
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('smartfaq_answers');
299
        if (isset($criteria) && $criteria instanceof \CriteriaElement) {
300
            $sql .= ' ' . $criteria->renderWhere();
301
        }
302
        $result = $this->db->query($sql);
303
        if (!$result) {
304
            return 0;
305
        }
306
        list($count) = $this->db->fetchRow($result);
307
308
        return $count;
309
    }
310
311
    /**
312
     * count answers matching a condition and group by faq ID
313
     *
314
     * @param  object $criteria {@link CriteriaElement} to match
315
     * @return array
316
     */
317
    public function getCountByFAQ($criteria = null)
318
    {
319
        $sql = 'SELECT faqid, COUNT(*) FROM ' . $this->db->prefix('smartfaq_answers');
320
        if (isset($criteria) && $criteria instanceof \CriteriaElement) {
321
            $sql .= ' ' . $criteria->renderWhere();
322
            $sql .= ' ' . $criteria->getGroupby();
323
        }
324
325
        //echo "<br>$sql<br>";
326
327
        $result = $this->db->query($sql);
328
        if (!$result) {
329
            return [];
330
        }
331
        $ret = [];
332
        while (list($id, $count) = $this->db->fetchRow($result)) {
333
            $ret[$id] = $count;
334
        }
335
336
        return $ret;
337
    }
338
339
    /**
340
     * delete answers matching a set of conditions
341
     *
342
     * @param  \CriteriaElement $criteria {@link CriteriaElement}
343
     * @param  bool             $force
344
     * @param  bool             $asObject
345
     * @return bool            FALSE if deletion failed
346
     */
347
    public function deleteAll(\CriteriaElement $criteria = null, $force = true, $asObject = false)
348
    {
349
        $sql = 'DELETE FROM ' . $this->db->prefix('smartfaq_answers');
350
        if (isset($criteria) && $criteria instanceof \CriteriaElement) {
351
            $sql .= ' ' . $criteria->renderWhere();
352
        }
353
        if (!$this->db->query($sql)) {
354
            return false;
355
        }
356
357
        return true;
358
    }
359
360
    /**
361
     * Change a value for answers with a certain criteria
362
     *
363
     * @param  string           $fieldname  Name of the field
364
     * @param  string           $fieldvalue Value to write
365
     * @param  \CriteriaElement $criteria   {@link CriteriaElement}
366
     * @param  bool             $force
367
     * @return bool
368
     */
369
    public function updateAll($fieldname, $fieldvalue, \CriteriaElement $criteria = null, $force = false)
370
    {
371
        $set_clause = is_numeric($fieldvalue) ? $fieldname . ' = ' . $fieldvalue : $fieldname . ' = ' . $this->db->quoteString($fieldvalue);
372
        $sql        = 'UPDATE ' . $this->db->prefix('smartfaq_answers') . ' SET ' . $set_clause;
373
        if (isset($criteria) && $criteria instanceof \CriteriaElement) {
374
            $sql .= ' ' . $criteria->renderWhere();
375
        }
376
        //echo "<br>" . $sql . "<br>";
377
        if (!$this->db->queryF($sql)) {
378
            return false;
379
        }
380
381
        return true;
382
    }
383
384
    /**
385
     * @param $faqids
386
     * @return array
387
     */
388
    public function getLastPublishedByFaq($faqids)
389
    {
390
        $ret    = [];
391
        $sql    = 'SELECT faqid, answer, uid, datesub FROM ' . $this->db->prefix('smartfaq_answers') . '
392
               WHERE faqid IN (' . implode(',', $faqids) . ') AND status = ' . Constants::SF_AN_STATUS_APPROVED . ' GROUP BY faqid';
393
        $result = $this->db->query($sql);
394
        if (!$result) {
395
            return $ret;
396
        }
397
        while (false !== ($row = $this->db->fetchArray($result))) {
398
            $answer = new Smartfaq\Answer();
399
            $answer->assignVars($row);
400
            $ret[$row['faqid']] = &$answer;
401
            unset($answer);
402
        }
403
404
        return $ret;
405
    }
406
}
407