Completed
Pull Request — master (#563)
by Richard
08:33
created

PublisherItem::getCategoryLink()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
 */
11
12
use Xoops\Core\Database\Connection;
13
use Xoops\Core\Kernel\XoopsObject;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsObject. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
14
use Xoops\Core\Kernel\XoopsPersistableObjectHandler;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsPersistableObjectHandler. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
15
use Xoops\Core\Kernel\Criteria;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Criteria. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
16
use Xoops\Core\Kernel\CriteriaCompo;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, CriteriaCompo. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
17
use Xmf\Request;
18
19
/**
20
 * @copyright       The XUUPS Project http://sourceforge.net/projects/xuups/
21
 * @license         GNU GPL V2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
22
 * @package         Publisher
23
 * @since           1.0
24
 * @author          trabis <[email protected]>
25
 * @author          The SmartFactory <www.smartfactory.ca>
26
 * @version         $Id$
27
 */
28
29
include_once dirname(__DIR__) . '/include/common.php';
30
31
class PublisherItem extends XoopsObject
32
{
33
    /**
34
     * @var Publisher
35
     * @access public
36
     */
37
    public $publisher = null;
38
39
    /**
40
     * @var PublisherCategory
41
     * @access public
42
     */
43
    public $_category = null;
44
45
    /**
46
     * @param int|null $id
47
     */
48
    public function __construct($id = null)
49
    {
50
        $this->publisher = Publisher::getInstance();
51
        $this->initVar("itemid", XOBJ_DTYPE_INT, 0);
52
        $this->initVar("categoryid", XOBJ_DTYPE_INT, 0, false);
53
        $this->initVar("title", XOBJ_DTYPE_TXTBOX, '', true, 255);
54
        $this->initVar("subtitle", XOBJ_DTYPE_TXTBOX, '', false, 255);
55
        $this->initVar("summary", XOBJ_DTYPE_TXTAREA, '', false);
56
        $this->initVar("body", XOBJ_DTYPE_TXTAREA, '', false);
57
        $this->initVar("uid", XOBJ_DTYPE_INT, 0, false);
58
        $this->initVar("author_alias", XOBJ_DTYPE_TXTBOX, '', false, 255);
59
        $this->initVar("datesub", XOBJ_DTYPE_INT, '', false);
60
        $this->initVar("status", XOBJ_DTYPE_INT, -1, false);
61
        $this->initVar("image", XOBJ_DTYPE_INT, 0, false);
62
        $this->initVar("images", XOBJ_DTYPE_TXTBOX, '', false, 255);
63
        $this->initVar("counter", XOBJ_DTYPE_INT, 0, false);
64
        $this->initVar("rating", XOBJ_DTYPE_OTHER, 0, false);
65
        $this->initVar("votes", XOBJ_DTYPE_INT, 0, false);
66
        $this->initVar("weight", XOBJ_DTYPE_INT, 0, false);
67
        $this->initVar("dohtml", XOBJ_DTYPE_INT, 1, true);
68
        $this->initVar("dosmiley", XOBJ_DTYPE_INT, 1, true);
69
        $this->initVar("doimage", XOBJ_DTYPE_INT, 1, true);
70
        $this->initVar("dobr", XOBJ_DTYPE_INT, 1, false);
71
        $this->initVar("doxcode", XOBJ_DTYPE_INT, 1, true);
72
        $this->initVar("cancomment", XOBJ_DTYPE_INT, 1, true);
73
        $this->initVar("comments", XOBJ_DTYPE_INT, 0, false);
74
        $this->initVar("notifypub", XOBJ_DTYPE_INT, 1, false);
75
        $this->initVar("meta_keywords", XOBJ_DTYPE_TXTAREA, '', false);
76
        $this->initVar("meta_description", XOBJ_DTYPE_TXTAREA, '', false);
77
        $this->initVar("short_url", XOBJ_DTYPE_TXTBOX, '', false, 255);
78
        $this->initVar("item_tag", XOBJ_DTYPE_TXTAREA, '', false);
79
        // Non consistent values
80
        $this->initVar("pagescount", XOBJ_DTYPE_INT, 0, false);
81
        if (isset($id)) {
82
            $item = $this->publisher->getItemHandler()->get($id);
83
            foreach ($item->vars as $k => $v) {
84
                $this->assignVar($k, $v['value']);
85
            }
86
        }
87
    }
88
89
    /**
90
     * @return null|PublisherCategory
91
     */
92
    public function category()
93
    {
94
        if (!isset($this->_category)) {
95
            $this->_category = $this->publisher->getCategoryHandler()->get($this->getVar('categoryid'));
96
        }
97
        return $this->_category;
98
    }
99
100
    /**
101
     * @param int    $maxLength
102
     * @param string $format
103
     *
104
     * @return string
105
     */
106
    public function title($maxLength = 0, $format = "S")
107
    {
108
        $ret = $this->getVar("title", $format);
109
        if ($maxLength != 0) {
110
            if (!XoopsLocale::isMultiByte()) {
0 ignored issues
show
Deprecated Code introduced by
The function Xoops\Locale\AbstractLocale::isMultiByte() has been deprecated: since 2.6.0 -- UTF-8 is always used ( Ignorable by Annotation )

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

110
            if (!/** @scrutinizer ignore-deprecated */ XoopsLocale::isMultiByte()) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
111
                if (strlen($ret) >= $maxLength) {
0 ignored issues
show
Bug introduced by
It seems like $ret can also be of type array; however, parameter $string of strlen() 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

111
                if (strlen(/** @scrutinizer ignore-type */ $ret) >= $maxLength) {
Loading history...
112
                    $ret = PublisherUtils::substr($ret, 0, $maxLength);
0 ignored issues
show
Bug introduced by
It seems like $ret can also be of type array; however, parameter $str of PublisherUtils::substr() 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

112
                    $ret = PublisherUtils::substr(/** @scrutinizer ignore-type */ $ret, 0, $maxLength);
Loading history...
113
                }
114
            }
115
        }
116
        return $ret;
117
    }
118
119
    /**
120
     * @param int    $maxLength
121
     * @param string $format
122
     *
123
     * @return mixed|string
124
     */
125
    public function subtitle($maxLength = 0, $format = "S")
126
    {
127
        $ret = $this->getVar("subtitle", $format);
128
        if ($maxLength != 0) {
129
            if (!XoopsLocale::isMultiByte()) {
0 ignored issues
show
Deprecated Code introduced by
The function Xoops\Locale\AbstractLocale::isMultiByte() has been deprecated: since 2.6.0 -- UTF-8 is always used ( Ignorable by Annotation )

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

129
            if (!/** @scrutinizer ignore-deprecated */ XoopsLocale::isMultiByte()) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
130
                if (strlen($ret) >= $maxLength) {
0 ignored issues
show
Bug introduced by
It seems like $ret can also be of type array; however, parameter $string of strlen() 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

130
                if (strlen(/** @scrutinizer ignore-type */ $ret) >= $maxLength) {
Loading history...
131
                    $ret = PublisherUtils::substr($ret, 0, $maxLength);
0 ignored issues
show
Bug introduced by
It seems like $ret can also be of type array; however, parameter $str of PublisherUtils::substr() 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

131
                    $ret = PublisherUtils::substr(/** @scrutinizer ignore-type */ $ret, 0, $maxLength);
Loading history...
132
                }
133
            }
134
        }
135
        return $ret;
136
    }
137
138
    /**
139
     * @param int    $maxLength
140
     * @param string $format
141
     * @param string $stripTags
142
     *
143
     * @return mixed|string
144
     */
145
    public function summary($maxLength = 0, $format = "S", $stripTags = '')
146
    {
147
        $ret = $this->getVar("summary", $format);
148
        if (!empty($stripTags)) {
149
            $ret = strip_tags($ret, $stripTags);
0 ignored issues
show
Bug introduced by
It seems like $ret can also be of type array; however, parameter $str of strip_tags() 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

149
            $ret = strip_tags(/** @scrutinizer ignore-type */ $ret, $stripTags);
Loading history...
150
        }
151
        if ($maxLength != 0) {
152
            if (!XoopsLocale::isMultiByte()) {
0 ignored issues
show
Deprecated Code introduced by
The function Xoops\Locale\AbstractLocale::isMultiByte() has been deprecated: since 2.6.0 -- UTF-8 is always used ( Ignorable by Annotation )

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

152
            if (!/** @scrutinizer ignore-deprecated */ XoopsLocale::isMultiByte()) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
153
                if (strlen($ret) >= $maxLength) {
154
                    //$ret = PublisherUtils::substr($ret , 0, $maxLength);
155
                    $ret = PublisherUtils::truncateTagSafe($ret, $maxLength, $etc = '...', $break_words = false);
156
                }
157
            }
158
        }
159
        return $ret;
160
    }
161
162
    /**
163
     * @param int  $maxLength
164
     * @param bool $fullSummary
165
     *
166
     * @return mixed|string
167
     */
168
    public function getBlockSummary($maxLength = 0, $fullSummary = false)
169
    {
170
        if ($fullSummary) {
171
            $ret = $this->summary(0, 's', '<br></ br>');
172
        } else {
173
            $ret = $this->summary($maxLength, 's', '<br></ br>');
174
        }
175
        //no summary? get body!
176
        if (strlen($ret) == 0) {
177
            $ret = $this->body($maxLength, 's', '<br></ br>');
178
        }
179
        return $ret;
180
    }
181
182
    /**
183
     * @param string $file_name
184
     *
185
     * @return string
186
     */
187
    public function wrappage($file_name)
188
    {
189
        $content = '';
190
        $page = PublisherUtils::getUploadDir(true, 'content') . $file_name;
0 ignored issues
show
Bug introduced by
'content' of type string is incompatible with the type boolean expected by parameter $item of PublisherUtils::getUploadDir(). ( Ignorable by Annotation )

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

190
        $page = PublisherUtils::getUploadDir(true, /** @scrutinizer ignore-type */ 'content') . $file_name;
Loading history...
191
        if (XoopsLoad::fileExists($page)) {
192
            // this page uses smarty template
193
            ob_start();
194
            include($page);
195
            $content = ob_get_contents();
196
            ob_end_clean();
197
            // Cleaning the content
198
            $body_start_pos = strpos($content, '<body>');
199
            if ($body_start_pos) {
200
                $body_end_pos = strpos($content, '</body>', $body_start_pos);
201
                $content = substr($content, $body_start_pos + strlen('<body>'), $body_end_pos - strlen('<body>') - $body_start_pos);
202
            }
203
            // Check if ML Hack is installed, and if yes, parse the $content in formatForML
204
            $myts = \Xoops\Core\Text\Sanitizer::getInstance();
205
            if (method_exists($myts, 'formatForML')) {
206
                $content = $myts->formatForML($content);
207
            }
208
        }
209
        return $content;
210
    }
211
212
    /**
213
     * This method returns the body to be displayed. Not to be used for editing
214
     *
215
     * @param int    $maxLength
216
     * @param string $format
217
     * @param string $stripTags
218
     *
219
     * @return mixed|string
220
     */
221
    public function body($maxLength = 0, $format = 'S', $stripTags = '')
222
    {
223
        $ret = $this->getVar('body', $format);
224
        $wrap_pos = strpos($ret, '[pagewrap=');
0 ignored issues
show
Bug introduced by
It seems like $ret can also be of type array; however, parameter $haystack of strpos() 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

224
        $wrap_pos = strpos(/** @scrutinizer ignore-type */ $ret, '[pagewrap=');
Loading history...
225
        if (!($wrap_pos === false)) {
0 ignored issues
show
introduced by
The condition ! $wrap_pos === false can never be false.
Loading history...
226
            $wrap_pages = array();
227
            $wrap_code_length = strlen('[pagewrap=');
228
            while (!($wrap_pos === false)) {
229
                $end_wrap_pos = strpos($ret, ']', $wrap_pos);
230
                if ($end_wrap_pos) {
231
                    $wrap_page_name = substr($ret, $wrap_pos + $wrap_code_length, $end_wrap_pos - $wrap_code_length - $wrap_pos);
0 ignored issues
show
Bug introduced by
It seems like $ret can also be of type array; however, parameter $string of substr() 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

231
                    $wrap_page_name = substr(/** @scrutinizer ignore-type */ $ret, $wrap_pos + $wrap_code_length, $end_wrap_pos - $wrap_code_length - $wrap_pos);
Loading history...
232
                    $wrap_pages[] = $wrap_page_name;
233
                }
234
                $wrap_pos = strpos($ret, '[pagewrap=', $end_wrap_pos - 1);
235
            }
236
            foreach ($wrap_pages as $page) {
237
                $wrap_page_content = $this->wrappage($page);
238
                $ret = str_replace("[pagewrap={$page}]", $wrap_page_content, $ret);
239
            }
240
        }
241
        if ($this->publisher->getConfig('item_disp_blocks_summary')) {
242
            $summary = $this->summary($maxLength, $format, $stripTags);
243
            if ($summary) {
244
                $ret = $this->summary() . '<br /><br />' . $ret;
245
            }
246
        }
247
        if (!empty($stripTags)) {
248
            $ret = strip_tags($ret, $stripTags);
249
        }
250
        if ($maxLength != 0) {
251
            if (!XoopsLocale::isMultiByte()) {
0 ignored issues
show
Deprecated Code introduced by
The function Xoops\Locale\AbstractLocale::isMultiByte() has been deprecated: since 2.6.0 -- UTF-8 is always used ( Ignorable by Annotation )

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

251
            if (!/** @scrutinizer ignore-deprecated */ XoopsLocale::isMultiByte()) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
252
                if (strlen($ret) >= $maxLength) {
253
                    //$ret = PublisherUtils::substr($ret , 0, $maxLength);
254
                    $ret = PublisherUtils::truncateTagSafe($ret, $maxLength, $etc = '...', $break_words = false);
255
                }
256
            }
257
        }
258
        return $ret;
259
    }
260
261
    /**
262
     * @param string $dateFormat
263
     * @param string $format
264
     *
265
     * @return string
266
     */
267
    public function datesub($dateFormat = '', $format = 'S')
268
    {
269
        if (empty($dateformat)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dateformat does not exist. Did you maybe mean $format?
Loading history...
270
            $dateFormat = $this->publisher->getConfig('format_date');
271
        }
272
        return XoopsLocale::formatTimestamp($this->getVar('datesub', $format), $dateFormat);
273
    }
274
275
    /**
276
     * @param int $realName
277
     *
278
     * @return string
279
     */
280
    public function posterName($realName = -1)
281
    {
282
        if ($realName == -1) {
283
            $realName = $this->publisher->getConfig('format_realname');
284
        }
285
        $ret = $this->getVar('author_alias');
286
        if ($ret == '') {
287
            $ret = XoopsUserUtility::getUnameFromId($this->getVar('uid'), $realName);
288
        }
289
        return $ret;
290
    }
291
292
    /**
293
     * @return string
294
     */
295
    public function posterAvatar()
296
    {
297
        $xoops = Xoops::getInstance();
298
        $ret = 'blank.gif';
299
        $member_handler = $xoops->getHandlerMember();
300
        $thisUser = $member_handler->getUser($this->getVar('uid'));
301
        if (is_object($thisUser)) {
302
            $ret = $xoops->service('avatar')->getAvatarUrl($thisUser)->getValue();
303
        }
304
        return $ret;
305
    }
306
307
    /**
308
     * @return string
309
     */
310
    public function linkedPosterName()
311
    {
312
        $ret = $this->getVar('author_alias');
313
        if ($ret == '') {
314
            $ret = XoopsUserUtility::getUnameFromId($this->getVar('uid'), $this->publisher->getConfig('format_realname'), true);
315
        }
316
        return $ret;
317
    }
318
319
    /**
320
     * @return mixed
321
     */
322
    public function updateCounter()
323
    {
324
        return $this->publisher->getItemHandler()->updateCounter($this->getVar('itemid'));
325
    }
326
327
    /**
328
     * @param bool $force
329
     *
330
     * @return bool
331
     */
332
    public function store($force = true)
333
    {
334
        $xoops = Xoops::getInstance();
335
        $isNew = $this->isNew();
336
        if (!$this->publisher->getItemHandler()->insert($this, $force)) {
337
            return false;
338
        }
339
        if ($isNew && $this->getVar('status') == _PUBLISHER_STATUS_PUBLISHED) {
340
            // Increment user posts
341
            $user_handler = $xoops->getHandlerUser();
342
            $member_handler = $xoops->getHandlerMember();
343
            $poster = $user_handler->get($this->getVar('uid'));
344
            if (is_object($poster) && !$poster->isNew()) {
345
                $poster->setVar('posts', $poster->getVar('posts') + 1);
346
                if (!$member_handler->insertUser($poster, true)) {
347
                    $this->setErrors('Article created but could not increment user posts.');
348
                    return false;
349
                }
350
            }
351
        }
352
        return true;
353
    }
354
355
    /**
356
     * @return string
357
     */
358
    public function getCategoryName()
359
    {
360
        return $this->category()->getVar('name');
361
    }
362
363
    /**
364
     * @return string
365
     */
366
    public function getCategoryUrl()
367
    {
368
        return $this->category()->getCategoryUrl();
369
    }
370
371
    /**
372
     * @return string
373
     */
374
    public function getCategoryLink()
375
    {
376
        return $this->category()->getCategoryLink();
377
    }
378
379
    /**
380
     * @param bool $withAllLink
381
     *
382
     * @return string
383
     */
384
    public function getCategoryPath($withAllLink = true)
385
    {
386
        return $this->category()->getCategoryPath($withAllLink);
387
    }
388
389
    /**
390
     * @return string
391
     */
392
    public function getCategoryImagePath()
393
    {
394
        return PublisherUtils::getImageDir('category', false) . $this->category()->image();
395
    }
396
397
    /**
398
     * @return mixed
399
     */
400
    public function getFiles()
401
    {
402
        return $this->publisher->getFileHandler()->getAllFiles($this->getVar('itemid'), _PUBLISHER_STATUS_FILE_ACTIVE);
403
    }
404
405
    /**
406
     * @return string
407
     */
408
    public function getAdminLinks()
409
    {
410
        $xoops = Xoops::getInstance();
411
        $adminLinks = '';
412
        if ($xoops->isUser() && (PublisherUtils::IsUserAdmin() || PublisherUtils::IsUserAuthor($this) || $this->publisher->getPermissionHandler()->isGranted('item_submit', $this->getVar('categoryid')))) {
413
            if (PublisherUtils::IsUserAdmin() || PublisherUtils::IsUserAuthor($this) || PublisherUtils::IsUserModerator($this)) {
414
                if ($this->publisher->getConfig('perm_edit') || PublisherUtils::IsUserModerator($this) || PublisherUtils::IsUserAdmin()) {
415
                    // Edit button
416
                    $adminLinks .= "<a href='" . PUBLISHER_URL . "/submit.php?itemid=" . $this->getVar('itemid') . "'><img src='" . PUBLISHER_URL . "/images/links/edit.gif'" . " title='" . _CO_PUBLISHER_EDIT . "' alt='" . _CO_PUBLISHER_EDIT . "'/></a>";
417
                    $adminLinks .= " ";
418
                }
419
                if ($this->publisher->getConfig('perm_delete') || PublisherUtils::IsUserModerator($this) || PublisherUtils::IsUserAdmin()) {
420
                    // Delete button
421
                    $adminLinks .= "<a href='" . PUBLISHER_URL . "/submit.php?op=del&amp;itemid=" . $this->getVar('itemid') . "'><img src='" . PUBLISHER_URL . "/images/links/delete.png'" . " title='" . _CO_PUBLISHER_DELETE . "' alt='" . _CO_PUBLISHER_DELETE . "' /></a>";
422
                    $adminLinks .= " ";
423
                }
424
            }
425
            if ($this->publisher->getConfig('perm_clone') || PublisherUtils::IsUserModerator($this) || PublisherUtils::IsUserAdmin()) {
426
                // Duplicate button
427
                $adminLinks .= "<a href='" . PUBLISHER_URL . "/submit.php?op=clone&amp;itemid=" . $this->getVar('itemid') . "'><img src='" . PUBLISHER_URL . "/images/links/clone.gif'" . " title='" . _CO_PUBLISHER_CLONE . "' alt='" . _CO_PUBLISHER_CLONE . "' /></a>";
428
                $adminLinks .= " ";
429
            }
430
        }
431
        // PDF button
432
        if ($xoops->service('htmltopdf')->isAvailable()) {
433
            $adminLinks .= "<a href='" . PUBLISHER_URL . "/makepdf.php?itemid=" . $this->getVar('itemid') . "' rel='nofollow' target='_blank'><img src='" . PUBLISHER_URL . "/images/links/pdf.gif' title='" . _CO_PUBLISHER_PDF . "' alt='" . _CO_PUBLISHER_PDF . "' /></a>";
434
            $adminLinks .= " ";
435
        }
436
        // Print button
437
        $adminLinks .= "<a href='" . PublisherUtils::seoGenUrl("print", $this->getVar('itemid'), $this->getVar('short_url')) . "' rel='nofollow' target='_blank'><img src='" . PUBLISHER_URL . "/images/links/print.gif' title='" . _CO_PUBLISHER_PRINT . "' alt='" . _CO_PUBLISHER_PRINT . "' /></a>";
438
        $adminLinks .= " ";
439
        // Email button
440
        if ($xoops->isActiveModule('tellafriend')) {
441
            $subject = sprintf(_CO_PUBLISHER_INTITEMFOUND, $xoops->getConfig('sitename'));
442
            $subject = $this->_convert_for_japanese($subject);
443
            $maillink = PublisherUtils::tellafriend($subject);
444
            $adminLinks .= '<a href="' . $maillink . '"><img src="' . PUBLISHER_URL . '/images/links/friend.gif" title="' . _CO_PUBLISHER_MAIL . '" alt="' . _CO_PUBLISHER_MAIL . '" /></a>';
445
            $adminLinks .= " ";
446
        }
447
        return $adminLinks;
448
    }
449
450
    /**
451
     * @param array $notifications
452
     */
453
    public function sendNotifications($notifications = array())
454
    {
455
        $xoops = Xoops::getInstance();
456
        if ($xoops->isActiveModule('notifications')) {
457
458
            $notification_handler = Notifications::getInstance()->getHandlerNotification();
459
            $tags = array();
460
            $tags['MODULE_NAME'] = $this->publisher->getModule()->getVar('name');
461
            $tags['ITEM_NAME'] = $this->title();
462
            $tags['CATEGORY_NAME'] = $this->getCategoryName();
463
            $tags['CATEGORY_URL'] = PUBLISHER_URL . '/category.php?categoryid=' . $this->getVar('categoryid');
464
            $tags['ITEM_BODY'] = $this->body();
465
            $tags['DATESUB'] = $this->datesub();
466
            foreach ($notifications as $notification) {
467
                switch ($notification) {
468
                    case _PUBLISHER_NOT_ITEM_PUBLISHED :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
469
                        $tags['ITEM_URL'] = PUBLISHER_URL . '/item.php?itemid=' . $this->getVar('itemid');
470
                        $notification_handler->triggerEvent('global', 0, 'published', $tags, array(), $this->publisher->getModule()->getVar('mid'));
471
                        $notification_handler->triggerEvent('category', $this->getVar('categoryid'), 'published', $tags, array(), $this->publisher->getModule()->getVar('mid'));
472
                        $notification_handler->triggerEvent('item', $this->getVar('itemid'), 'approved', $tags, array(), $this->publisher->getModule()->getVar('mid'));
473
                        break;
474
                    case _PUBLISHER_NOT_ITEM_SUBMITTED :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
475
                        $tags['WAITINGFILES_URL'] = PUBLISHER_URL . '/admin/item.php?itemid=' . $this->getVar('itemid');
476
                        $notification_handler->triggerEvent('global', 0, 'submitted', $tags, array(), $this->publisher->getModule()->getVar('mid'));
477
                        $notification_handler->triggerEvent('category', $this->getVar('categoryid'), 'submitted', $tags, array(), $this->publisher->getModule()->getVar('mid'));
478
                        break;
479
                    case _PUBLISHER_NOT_ITEM_REJECTED :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
480
                        $notification_handler->triggerEvent('item', $this->getVar('itemid'), 'rejected', $tags, array(), $this->publisher->getModule()->getVar('mid'));
481
                        break;
482
                    case -1 :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
483
                    default:
484
                        break;
485
                }
486
            }
487
        }
488
    }
489
490
    /**
491
     * @return bool
492
     */
493
    public function notLoaded()
494
    {
495
        return $this->getVar('itemid') == -1;
496
    }
497
498
    /**
499
     * @return string
500
     */
501
    public function getItemUrl()
502
    {
503
        return PublisherUtils::seoGenUrl('item', $this->getVar('itemid'), $this->getVar('short_url'));
504
    }
505
506
    /**
507
     * @param bool $class
508
     * @param int  $maxsize
509
     *
510
     * @return string
511
     */
512
    public function getItemLink($class = false, $maxsize = 0)
513
    {
514
        if ($class) {
515
            return '<a class=' . $class . ' href="' . $this->getItemUrl() . '">' . $this->title($maxsize) . '</a>';
0 ignored issues
show
Bug introduced by
Are you sure $class of type true can be used in concatenation? ( Ignorable by Annotation )

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

515
            return '<a class=' . /** @scrutinizer ignore-type */ $class . ' href="' . $this->getItemUrl() . '">' . $this->title($maxsize) . '</a>';
Loading history...
516
        } else {
517
            return '<a href="' . $this->getItemUrl() . '">' . $this->title($maxsize) . '</a>';
518
        }
519
    }
520
521
    /**
522
     * @return string
523
     */
524
    public function getWhoAndWhen()
525
    {
526
        $posterName = $this->linkedPosterName();
527
        $postdate = $this->datesub();
528
        return sprintf(_CO_PUBLISHER_POSTEDBY, $posterName, $postdate);
529
    }
530
531
    /**
532
     * @param null|string $body
533
     *
534
     * @return string
535
     */
536
    public function plain_maintext($body = null)
537
    {
538
        $ret = '';
539
        if (!$body) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $body of type null|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
540
            $body = $this->body();
541
        }
542
        $ret .= str_replace('[pagebreak]', '<br /><br />', $body);
543
        return $ret;
544
    }
545
546
    /**
547
     * @param int         $item_page_id
548
     * @param null|string $body
549
     *
550
     * @return string
551
     */
552
    public function buildmaintext($item_page_id = -1, $body = null)
553
    {
554
        if (!$body) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $body of type null|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
555
            $body = $this->body();
556
        }
557
        $body_parts = explode('[pagebreak]', $body);
558
        $this->setVar('pagescount', count($body_parts));
559
        if (count($body_parts) <= 1) {
560
            return $this->plain_maintext($body);
561
        }
562
        $ret = '';
563
        if ($item_page_id == -1) {
564
            $ret .= trim($body_parts[0]);
565
            return $ret;
566
        }
567
        if ($item_page_id >= count($body_parts)) {
568
            $item_page_id = count($body_parts) - 1;
569
        }
570
        $ret .= trim($body_parts[$item_page_id]);
571
        return $ret;
572
    }
573
574
    /**
575
     * @return mixed
576
     */
577
    public function getImages()
578
    {
579
        static $ret;
580
581
        $xoops = Xoops::getInstance();
582
        if (!$xoops->isActiveModule('images')) {
583
            return array();
584
        }
585
        $itemid = $this->getVar('itemid');
586
        if (!isset($ret[$itemid])) {
587
            $ret[$itemid]['main'] = '';
588
            $ret[$itemid]['others'] = array();
589
            $images_ids = array();
590
            $image = $this->getVar('image');
591
            $images = $this->getVar('images');
592
            if ($images != '') {
593
                $images_ids = explode('|', $images);
0 ignored issues
show
Bug introduced by
It seems like $images can also be of type array; however, parameter $string of explode() 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

593
                $images_ids = explode('|', /** @scrutinizer ignore-type */ $images);
Loading history...
594
            }
595
            if ($image > 0) {
596
                $images_ids = array_merge($images_ids, array($image));
597
            }
598
            $imageObjs = array();
599
            if (count($images_ids) > 0) {
600
                $image_handler = Images::getInstance()->getHandlerImages();
601
                $criteria = new CriteriaCompo(new Criteria('image_id', '(' . implode(',', $images_ids) . ')', 'IN'));
602
                $imageObjs = $image_handler->getObjects($criteria, true);
603
                unset($criteria);
604
            }
605
            foreach ($imageObjs as $id => $imageObj) {
606
                if ($id == $image) {
607
                    $ret[$itemid]['main'] = $imageObj;
608
                } else {
609
                    $ret[$itemid]['others'][] = $imageObj;
610
                }
611
                unset($imageObj);
612
            }
613
            unset($imageObjs);
614
        }
615
        return $ret[$itemid];
616
    }
617
618
    /**
619
     * @param string $display
620
     * @param int    $max_char_title
621
     * @param int    $max_char_summary
622
     * @param bool   $full_summary
623
     *
624
     * @return array
625
     */
626
    public function toArray($display = 'default', $max_char_title = 0, $max_char_summary = 0, $full_summary = false)
0 ignored issues
show
Unused Code introduced by
The parameter $full_summary is not used and could be removed. ( Ignorable by Annotation )

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

626
    public function toArray($display = 'default', $max_char_title = 0, $max_char_summary = 0, /** @scrutinizer ignore-unused */ $full_summary = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
627
    {
628
        $item_page_id = -1;
629
        if (is_numeric($display)) {
630
            $item_page_id = $display;
631
            $display = 'all';
632
        }
633
        $item['itemid'] = $this->getVar('itemid');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$item was never initialized. Although not strictly required by PHP, it is generally a good practice to add $item = array(); before regardless.
Loading history...
634
        $item['uid'] = $this->getVar('uid');
635
        $item['titlelink'] = $this->getItemLink(false, $max_char_title);
636
        $item['subtitle'] = $this->subtitle();
637
        $item['datesub'] = $this->datesub();
638
        $item['counter'] = $this->getVar('counter');
639
        switch ($display) {
640
            case 'summary':
641
            case 'list':
642
                break;
643
            case 'full':
644
            case 'wfsection':
645
            case 'default':
646
                $summary = $this->summary($max_char_summary);
647
                if (!$summary) {
648
                    $summary = $this->body($max_char_summary);
649
                }
650
                $item['summary'] = $summary;
651
                $item = $this->toArrayFull($item);
652
                break;
653
            case 'all':
654
                $item = $this->toArrayFull($item);
655
                $item = $this->toArrayAll($item, $item_page_id);
656
                break;
657
        }
658
        // Highlighting searched words
659
        $highlight = true;
660
        if ($highlight && isset($_GET['keywords'])) {
661
            $myts = \Xoops\Core\Text\Sanitizer::getInstance();
662
            $keywords = $myts->htmlSpecialChars(trim(urldecode($_GET['keywords'])));
663
            $fields = array('title', 'maintext', 'summary');
664
            foreach ($fields as $field) {
665
                if (isset($item[$field])) {
666
                    $item[$field] = $this->highlight($item[$field], $keywords);
667
                }
668
            }
669
        }
670
        return $item;
671
    }
672
673
    /**
674
     * @param array $item
675
     *
676
     * @return array
677
     */
678
    public function toArrayFull($item)
679
    {
680
        $item['title'] = $this->title();
681
        $item['clean_title'] = $this->title();
682
        $item['itemurl'] = $this->getItemUrl();
683
        $item['cancomment'] = $this->getVar('cancomment');
684
        $item['comments'] = $this->getVar('comments');
685
        $item['adminlink'] = $this->getAdminLinks();
686
        $item['categoryPath'] = $this->getCategoryPath($this->publisher->getConfig('format_linked_path'));
687
        $item['who_when'] = $this->getWhoAndWhen();
688
        $item = $this->getMainImage($item);
689
        return $item;
690
    }
691
692
    /**
693
     * @param array $item
694
     * @param int   $item_page_id
695
     *
696
     * @return array
697
     */
698
    public function toArrayAll($item, $item_page_id)
699
    {
700
        $item['maintext'] = $this->buildmaintext($item_page_id, $this->body());
701
        $item = $this->getOtherImages($item);
702
        return $item;
703
    }
704
705
    /**
706
     * @param array $item
707
     *
708
     * @return array
709
     */
710
    public function getMainImage($item = array())
711
    {
712
        $images = $this->getImages();
713
        $item['image_path'] = '';
714
        $item['image_name'] = '';
715
        if (is_object($images['main'])) {
716
            /* @var $image ImagesImage */
717
            $image = $images['main'];
718
            $dimensions = getimagesize(\XoopsBaseConfig::get('root-path') . '/uploads/' . $image->getVar('image_name'));
719
            $item['image_width'] = $dimensions[0];
720
            $item['image_height'] = $dimensions[1];
721
            $item['image_path'] = \XoopsBaseConfig::get('url') . '/uploads/' . $image->getVar('image_name');
722
            // pass this on since some consumers build custom thumbnails
723
            $item['image_vpath'] = 'uploads/' . $image->getVar('image_name');
724
            $item['image_thumb'] = \Xoops::getInstance()
725
                ->service('thumbnail')
726
                ->getImgUrl($item['image_vpath'], 0, 180)
727
                ->getValue();
728
            $item['image_name'] = $image->getVar('image_nicename');
729
        }
730
        return $item;
731
    }
732
733
    /**
734
     * @param array $item
735
     *
736
     * @return array
737
     */
738
    public function getOtherImages($item = array())
739
    {
740
        $thumbService = \Xoops::getInstance()->service('thumbnail');
741
        $images = $this->getImages();
742
        $item['images'] = array();
743
        $i = 0;
744
        /* @var $image ImagesImage */
745
        foreach ($images['others'] as $image) {
746
            $dimensions = getimagesize(\XoopsBaseConfig::get('root-path') . '/uploads/' . $image->getVar('image_name'));
747
            $item['images'][$i]['width'] = $dimensions[0];
748
            $item['images'][$i]['height'] = $dimensions[1];
749
            $item['images'][$i]['path'] = \XoopsBaseConfig::get('url') . '/uploads/' . $image->getVar('image_name');
750
            $item['images'][$i]['thumb'] = $thumbService
751
                ->getImgUrl('uploads/' . $image->getVar('image_name'), 240, 0)
752
                ->getValue();
753
            $item['images'][$i]['name'] = $image->getVar('image_nicename');
754
            ++$i;
755
        }
756
        return $item;
757
    }
758
759
    /**
760
     * @param string       $content
761
     * @param string|array $keywords
762
     *
763
     * @return string Text
764
     */
765
    public function highlight($content, $keywords)
766
    {
767
        $color = $this->publisher->getConfig('format_highlight_color');
768
        if (substr($color, 0, 1) !== '#') {
769
            $color = '#' . $color;
770
        }
771
        $pre = '<span style="font-weight: bolder; background-color: ' . $color . ';">';
772
        $post = '</span>';
773
        return \Xmf\Highlighter::apply($keywords, $content, $pre, $post);
774
    }
775
776
    /**
777
     *  Create metada and assign it to template
778
     */
779
    public function createMetaTags()
780
    {
781
        $publisher_metagen = new PublisherMetagen($this->title(), $this->getVar('meta_keywords'), $this->getVar('meta_description'), $this->_category->_categoryPath);
0 ignored issues
show
Bug introduced by
It seems like $this->getVar('meta_keywords') can also be of type array; however, parameter $keywords of PublisherMetagen::__construct() 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

781
        $publisher_metagen = new PublisherMetagen($this->title(), /** @scrutinizer ignore-type */ $this->getVar('meta_keywords'), $this->getVar('meta_description'), $this->_category->_categoryPath);
Loading history...
Bug introduced by
$this->_category->_categoryPath of type array is incompatible with the type boolean expected by parameter $categoryPath of PublisherMetagen::__construct(). ( Ignorable by Annotation )

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

781
        $publisher_metagen = new PublisherMetagen($this->title(), $this->getVar('meta_keywords'), $this->getVar('meta_description'), /** @scrutinizer ignore-type */ $this->_category->_categoryPath);
Loading history...
Bug introduced by
It seems like $this->getVar('meta_description') can also be of type array; however, parameter $description of PublisherMetagen::__construct() 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

781
        $publisher_metagen = new PublisherMetagen($this->title(), $this->getVar('meta_keywords'), /** @scrutinizer ignore-type */ $this->getVar('meta_description'), $this->_category->_categoryPath);
Loading history...
782
        $publisher_metagen->createMetaTags();
783
    }
784
785
    /**
786
     * @param string $str
787
     *
788
     * @return string
789
     */
790
    public function _convert_for_japanese($str)
791
    {
792
        global $xoopsConfig;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
793
        // no action, if not flag
794
        if (!defined('_PUBLISHER_FLAG_JP_CONVERT')) {
795
            return $str;
796
        }
797
        // no action, if not Japanese
798
        if ($xoopsConfig['language'] !== 'japanese') {
799
            return $str;
800
        }
801
        // presume OS Browser
802
        $agent = $_SERVER["HTTP_USER_AGENT"];
803
        $os = '';
804
        $browser = '';
805
        if (preg_match("/Win/i", $agent)) {
806
            $os = 'win';
807
        }
808
        if (preg_match("/MSIE/i", $agent)) {
809
            $browser = 'msie';
810
        }
811
        // if msie
812
        if (($os === 'win') && ($browser === 'msie')) {
813
            // if multibyte
814
            if (function_exists('mb_convert_encoding')) {
815
                $str = mb_convert_encoding($str, 'SJIS', 'EUC-JP');
816
                $str = rawurlencode($str);
817
            }
818
        }
819
        return $str;
820
    }
821
822
    /**
823
     * Checks if a user has access to a selected item. if no item permissions are
824
     * set, access permission is denied. The user needs to have necessary category
825
     * permission as well.
826
     * Also, the item needs to be Published
827
     *
828
     * @return boolean : TRUE if the no errors occured
829
     */
830
    public function accessGranted()
831
    {
832
        if (PublisherUtils::IsUserAdmin()) {
833
            return true;
834
        }
835
        if ($this->getVar('status') != _PUBLISHER_STATUS_PUBLISHED) {
836
            return false;
837
        }
838
        // Do we have access to the parent category
839
        if ($this->publisher->getPermissionHandler()->isGranted('category_read', $this->getVar('categoryid'))) {
840
            return true;
841
        }
842
        return false;
843
    }
844
845
    /**
846
     * The name says it all
847
     */
848
    public function setVarsFromRequest()
849
    {
850
        $xoops = Xoops::getInstance();
851
        //Required fields
852
        if (isset($_REQUEST['categoryid'])) {
853
            $this->setVar('categoryid', Request::getInt('categoryid'));
854
        }
855
        if (isset($_REQUEST['title'])) {
856
            $this->setVar('title', Request::getString('title'));
857
        }
858
        if (isset($_REQUEST['body'])) {
859
            $this->setVar('body', Request::getText('body'));
860
        }
861
        //Not required fields
862
        if (isset($_REQUEST['summary'])) {
863
            $this->setVar('summary', Request::getText('summary'));
864
        }
865
        if (isset($_REQUEST['subtitle'])) {
866
            $this->setVar('subtitle', Request::getString('subtitle'));
867
        }
868
        if (isset($_REQUEST['item_tag'])) {
869
            $this->setVar('item_tag', Request::getString('item_tag'));
870
        }
871
        if (isset($_REQUEST['image_featured'])) {
872
            $image_item = Request::getArray('image_item');
873
            $image_featured = Request::getString('image_featured');
874
            //Todo: get a better image class for xoops!
875
            //Image hack
876
            $image_item_ids = array();
877
878
            $qb = \Xoops::getInstance()->db()->createXoopsQueryBuilder();
879
            $qb ->select('i.image_id', 'i.image_name')
880
                ->fromPrefix('image', 'i')
881
                ->orderBy('i.image_id');
882
            $result = $qb->execute();
883
884
            while ($myrow = $result->fetch(\PDO::FETCH_ASSOC)) {
885
                $image_name = $myrow['image_name'];
886
                $id = $myrow['image_id'];
887
                if ($image_name == $image_featured) {
888
                    $this->setVar('image', $id);
889
                }
890
                if (in_array($image_name, $image_item)) {
891
                    $image_item_ids[] = $id;
892
                }
893
            }
894
            $this->setVar('images', implode('|', $image_item_ids));
895
        }
896
        if (isset($_REQUEST['uid'])) {
897
            $this->setVar('uid', Request::getInt('uid'));
898
        } elseif ($this->isNew()) {
899
            $this->setVar('uid', $xoops->isUser() ? $xoops->user->getVar('uid') : 0);
900
        }
901
        if (isset($_REQUEST['author_alias'])) {
902
            $this->setVar('author_alias', Request::getString('author_alias'));
903
            if ($this->getVar('author_alias') != '') {
904
                $this->setVar('uid', 0);
905
            }
906
        }
907
        if (isset($_REQUEST['datesub'])) {
908
            $this->setVar('datesub', strtotime($_REQUEST['datesub']['date']) + $_REQUEST['datesub']['time']);
909
        } elseif ($this->isNew()) {
910
            $this->setVar('datesub', time());
911
        }
912
        if (isset($_REQUEST['item_short_url'])) {
913
            $this->setVar('short_url', Request::getString('item_short_url'));
914
        }
915
        if (isset($_REQUEST['item_meta_keywords'])) {
916
            $this->setVar('meta_keywords', Request::getString('item_meta_keywords'));
917
        }
918
        if (isset($_REQUEST['item_meta_description'])) {
919
            $this->setVar('meta_description', Request::getString('item_meta_description'));
920
        }
921
        if (isset($_REQUEST['weight'])) {
922
            $this->setVar('weight', Request::getInt('weight'));
923
        }
924
        if (isset($_REQUEST['allowcomments'])) {
925
            $this->setVar('cancomment', Request::getInt('allowcomments'));
926
        } elseif ($this->isNew()) {
927
            $this->setVar('cancoment', $this->publisher->getConfig('submit_allowcomments'));
928
        }
929
        if (isset($_REQUEST['status'])) {
930
            $this->setVar('status', Request::getInt('status'));
931
        } elseif ($this->isNew()) {
932
            $this->setVar('status', $this->publisher->getConfig('submit_status'));
933
        }
934
        if (isset($_REQUEST['dohtml'])) {
935
            $this->setVar('dohtml', Request::getInt('dohtml'));
936
        } elseif ($this->isNew()) {
937
            $this->setVar('dohtml', $this->publisher->getConfig('submit_dohtml'));
938
        }
939
        if (isset($_REQUEST['dosmiley'])) {
940
            $this->setVar('dosmiley', Request::getInt('dosmiley'));
941
        } elseif ($this->isNew()) {
942
            $this->setVar('dosmiley', $this->publisher->getConfig('submit_dosmiley'));
943
        }
944
        if (isset($_REQUEST['doxcode'])) {
945
            $this->setVar('doxcode', Request::getInt('doxcode'));
946
        } elseif ($this->isNew()) {
947
            $this->setVar('doxcode', $this->publisher->getConfig('submit_doxcode'));
948
        }
949
        if (isset($_REQUEST['doimage'])) {
950
            $this->setVar('doimage', Request::getInt('doimage'));
951
        } elseif ($this->isNew()) {
952
            $this->setVar('doimage', $this->publisher->getConfig('submit_doimage'));
953
        }
954
        if (isset($_REQUEST['dolinebreak'])) {
955
            $this->setVar('dobr', Request::getInt('dolinebreak'));
956
        } elseif ($this->isNew()) {
957
            $this->setVar('dobr', $this->publisher->getConfig('submit_dobr'));
958
        }
959
        if (isset($_REQUEST['notify'])) {
960
            $this->setVar('notifypub', Request::getInt('notify'));
961
        }
962
    }
963
}
964
965
/**
966
 * Items handler class.
967
 * This class is responsible for providing data access mechanisms to the data source
968
 * of Q&A class objects.
969
 *
970
 * @author  marcan <[email protected]>
971
 * @package Publisher
972
 */
973
class PublisherItemHandler extends XoopsPersistableObjectHandler
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
974
{
975
    /**
976
     * @var Publisher
977
     * @access public
978
     */
979
    public $publisher = null;
980
981
    /**
982
     * @param Connection $db
983
     */
984
    public function __construct(Connection $db)
985
    {
986
        parent::__construct($db, "publisher_items", 'PublisherItem', "itemid", "title");
987
        $this->publisher = Publisher::getInstance();
988
    }
989
990
    /**
991
     * insert a new item in the database
992
     *
993
     * @param XoopsObject $item reference to the {@link PublisherItem} object
994
     * @param bool        $force
995
     *
996
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
997
     */
998
    public function insert(XoopsObject $item, $force = true)
999
    {
1000
        $xoops = Xoops::getInstance();
1001
        if (!$item->getVar('meta_keywords') || !$item->getVar('meta_description') || !$item->getVar('short_url')) {
1002
            $publisher_metagen = new PublisherMetagen($item->title(), $item->getVar('meta_keywords'), $item->getVar('summary'));
0 ignored issues
show
Bug introduced by
The method title() does not exist on Xoops\Core\Kernel\XoopsObject. It seems like you code against a sub-type of Xoops\Core\Kernel\XoopsObject such as PublisherItem or Xoops\Core\Kernel\Handlers\XoopsBlock. ( Ignorable by Annotation )

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

1002
            $publisher_metagen = new PublisherMetagen($item->/** @scrutinizer ignore-call */ title(), $item->getVar('meta_keywords'), $item->getVar('summary'));
Loading history...
Bug introduced by
It seems like $item->getVar('meta_keywords') can also be of type array; however, parameter $keywords of PublisherMetagen::__construct() 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

1002
            $publisher_metagen = new PublisherMetagen($item->title(), /** @scrutinizer ignore-type */ $item->getVar('meta_keywords'), $item->getVar('summary'));
Loading history...
Bug introduced by
It seems like $item->getVar('summary') can also be of type array; however, parameter $description of PublisherMetagen::__construct() 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

1002
            $publisher_metagen = new PublisherMetagen($item->title(), $item->getVar('meta_keywords'), /** @scrutinizer ignore-type */ $item->getVar('summary'));
Loading history...
1003
            // Auto create meta tags if empty
1004
            if (!$item->getVar('meta_keywords')) {
1005
                $item->setVar('meta_keywords', $publisher_metagen->_keywords);
1006
            }
1007
            if (!$item->getVar('meta_description')) {
1008
                $item->setVar('meta_description', $publisher_metagen->_description);
1009
            }
1010
            // Auto create short_url if empty
1011
            if (!$item->getVar('short_url')) {
1012
                $item->setVar('short_url', $publisher_metagen->generateSeoTitle($item->getVar('title', 'n'), false));
1013
            }
1014
        }
1015
        if (!parent::insert($item, $force)) {
1016
            return false;
1017
        }
1018
        if ($xoops->isActiveModule('tag')) {
1019
            // Storing tags information
1020
            $tag_handler = $xoops->getModuleHandler('tag', 'tag');
1021
            $tag_handler->updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), PUBLISHER_DIRNAME, 0);
0 ignored issues
show
Bug introduced by
The method updateByItem() does not exist on XoopsPersistableObjectHandler. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

1021
            $tag_handler->/** @scrutinizer ignore-call */ 
1022
                          updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), PUBLISHER_DIRNAME, 0);
Loading history...
Bug introduced by
The method updateByItem() does not exist on XoopsObjectHandler. ( Ignorable by Annotation )

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

1021
            $tag_handler->/** @scrutinizer ignore-call */ 
1022
                          updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), PUBLISHER_DIRNAME, 0);

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...
1022
        }
1023
        return true;
1024
    }
1025
1026
    /**
1027
     * delete an item from the database
1028
     *
1029
     * @param XoopsObject $item reference to the ITEM to delete
1030
     * @param bool        $force
1031
     *
1032
     * @return bool FALSE if failed.
1033
     */
1034
    public function delete(XoopsObject $item, $force = false)
1035
    {
1036
        $xoops = Xoops::getInstance();
1037
        // Deleting the files
1038
        if (!$this->publisher->getFileHandler()->deleteItemFiles($item)) {
1039
            $item->setErrors('An error while deleting a file.');
1040
        }
1041
        if (!parent::delete($item, $force)) {
1042
            $item->setErrors('An error while deleting.');
1043
            return false;
1044
        }
1045
        // Removing tags information
1046
        if ($xoops->isActiveModule('tag')) {
1047
            $tag_handler = $xoops->getModuleHandler('tag', 'tag');
1048
            $tag_handler->updateByItem('', $item->getVar('itemid'), PUBLISHER_DIRNAME, 0);
1049
        }
1050
        return true;
1051
    }
1052
1053
    /**
1054
     * retrieve items from the database
1055
     *
1056
     * @param object $criteria      {@link CriteriaElement} conditions to be met
1057
     * @param string $id_key        what shall we use as array key ? none, itemid, categoryid
1058
     * @param string $notNullFields fields that cannot be null or empty
1059
     *
1060
     * @return array array of {@link PublisherItem} objects
1061
     */
1062
    public function getItemObjects($criteria = null, $id_key = 'none', $notNullFields = '')
1063
    {
1064
        $ret = array();
1065
        $whereMode = '';
1066
1067
        $qb = $this->db2->createXoopsQueryBuilder();
1068
        $qb ->select('*')
1069
            ->fromPrefix('publisher_items', '');
1070
        if (isset($criteria) && is_subclass_of($criteria, 'Xoops\Core\Kernel\CriteriaElement')) {
1071
            $criteria->renderQb($qb, '');
1072
            $whereMode = 'AND';
1073
        }
1074
        $this->addNotNullFieldClause($qb, $notNullFields, $whereMode);
1075
        $theObjects = array();
1076
        $result = $qb->execute();
1077
        while ($myrow = $result->fetch(\PDO::FETCH_ASSOC)) {
1078
            $item = new PublisherItem();
1079
            $item->assignVars($myrow);
1080
            $theObjects[$myrow['itemid']] = $item;
1081
            unset($item);
1082
        }
1083
1084
        /* @var $theObject PublisherItem */
1085
        foreach ($theObjects as $theObject) {
1086
            if ($id_key === 'none') {
1087
                $ret[] = $theObject;
1088
            } elseif ($id_key === 'itemid') {
1089
                $ret[$theObject->getVar('itemid')] = $theObject;
1090
            } else {
1091
                $ret[$theObject->getVar($id_key)][$theObject->getVar('itemid')] = $theObject;
1092
            }
1093
            unset($theObject);
1094
        }
1095
        return $ret;
1096
    }
1097
1098
    /**
1099
     * count items matching a condition
1100
     *
1101
     * @param object $criteria {@link CriteriaElement} to match
1102
     * @param string $notNullFields fields that cannot be null or empty
1103
     *
1104
     * @return int count of items
1105
     */
1106
    public function getItemCount($criteria = null, $notNullFields = '')
1107
    {
1108
        $whereMode = '';
1109
1110
        $qb = $this->db2->createXoopsQueryBuilder();
1111
        $qb ->select('COUNT(*)')
1112
            ->fromPrefix('publisher_items', '');
1113
        if (isset($criteria) && is_subclass_of($criteria, 'Xoops\Core\Kernel\CriteriaElement')) {
1114
            $whereClause = $criteria->renderQb($qb, '');
0 ignored issues
show
Unused Code introduced by
The assignment to $whereClause is dead and can be removed.
Loading history...
1115
            $whereMode = 'AND';
1116
        }
1117
        $this->addNotNullFieldClause($qb, $notNullFields, $whereMode);
1118
        $result = $qb->execute();
1119
1120
        if (!$result) {
1121
            return 0;
1122
        }
1123
        list($count) = $result->fetch(PDO::FETCH_NUM);
1124
        return $count;
1125
    }
1126
1127
    /**
1128
     * @param        $categoryid
1129
     * @param string $status
1130
     * @param string $notNullFields
1131
     *
1132
     * @return int
1133
     */
1134
    public function getItemsCount($categoryid = -1, $status = '', $notNullFields = '')
1135
    {
1136
        global $publisher_isAdmin;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1137
        if (!$publisher_isAdmin) {
1138
            $criteriaPermissions = new CriteriaCompo();
1139
            // Categories for which user has access
1140
            $categoriesGranted = $this->publisher->getPermissionHandler()->getGrantedItems('category_read');
1141
            if (!empty($categoriesGranted)) {
1142
                $grantedCategories = new Criteria('categoryid', "(" . implode(',', $categoriesGranted) . ")", 'IN');
1143
                $criteriaPermissions->add($grantedCategories, 'AND');
1144
            } else {
1145
                return 0;
1146
            }
1147
        }
1148
        if (isset($categoryid) && $categoryid != -1) {
1149
            $criteriaCategory = new criteria('categoryid', $categoryid);
1150
        }
1151
        $criteriaStatus = new CriteriaCompo();
1152
        if (!empty($status) && is_array($status)) {
0 ignored issues
show
introduced by
The condition ! empty($status) && is_array($status) can never be true.
Loading history...
1153
            foreach ($status as $v) {
1154
                $criteriaStatus->add(new Criteria('status', $v), 'OR');
1155
            }
1156
        } elseif (!empty($status) && $status != -1) {
1157
            $criteriaStatus->add(new Criteria('status', $status), 'OR');
1158
        }
1159
        $criteria = new CriteriaCompo();
1160
        if (!empty($criteriaCategory)) {
1161
            $criteria->add($criteriaCategory);
1162
        }
1163
        if (!empty($criteriaPermissions)) {
1164
            $criteria->add($criteriaPermissions);
1165
        }
1166
        if (!empty($criteriaStatus)) {
1167
            $criteria->add($criteriaStatus);
1168
        }
1169
        return $this->getItemCount($criteria, $notNullFields);
1170
    }
1171
1172
    /**
1173
     * @param int    $limit
1174
     * @param int    $start
1175
     * @param int    $categoryid
1176
     * @param string $sort
1177
     * @param string $order
1178
     * @param string $notNullFields
1179
     * @param bool   $asobject
1180
     * @param string $id_key
1181
     *
1182
     * @return array
1183
     */
1184
    public function getAllPublished($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none')
1185
    {
1186
        $otherCriteria = new Criteria('datesub', time(), '<=');
1187
        return $this->getItems($limit, $start, array(_PUBLISHER_STATUS_PUBLISHED), $categoryid, $sort, $order, $notNullFields, $asobject, $otherCriteria, $id_key);
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_PUBLISHED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of PublisherItemHandler::getItems(). ( Ignorable by Annotation )

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

1187
        return $this->getItems($limit, $start, /** @scrutinizer ignore-type */ array(_PUBLISHER_STATUS_PUBLISHED), $categoryid, $sort, $order, $notNullFields, $asobject, $otherCriteria, $id_key);
Loading history...
1188
    }
1189
1190
    /**
1191
     * @param PublisherItem $obj
1192
     *
1193
     * @return bool
1194
     */
1195
    public function getPreviousPublished($obj)
1196
    {
1197
        $ret = false;
1198
        $otherCriteria = new CriteriaCompo();
1199
        $otherCriteria->add(new Criteria('datesub', $obj->getVar('datesub'), '<'));
0 ignored issues
show
Bug introduced by
It seems like $obj->getVar('datesub') can also be of type array; however, parameter $value of Xoops\Core\Kernel\Criteria::__construct() 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

1199
        $otherCriteria->add(new Criteria('datesub', /** @scrutinizer ignore-type */ $obj->getVar('datesub'), '<'));
Loading history...
1200
        $objs = $this->getItems(1, 0, array(_PUBLISHER_STATUS_PUBLISHED), $obj->getVar('categoryid'), 'datesub', 'DESC', '', true, $otherCriteria, 'none');
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_PUBLISHED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of PublisherItemHandler::getItems(). ( Ignorable by Annotation )

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

1200
        $objs = $this->getItems(1, 0, /** @scrutinizer ignore-type */ array(_PUBLISHER_STATUS_PUBLISHED), $obj->getVar('categoryid'), 'datesub', 'DESC', '', true, $otherCriteria, 'none');
Loading history...
1201
        if (count($objs) > 0) {
1202
            $ret = $objs[0];
1203
        }
1204
        return $ret;
1205
    }
1206
1207
    /**
1208
     * @param PublisherItem $obj
1209
     *
1210
     * @return bool
1211
     */
1212
    public function getNextPublished($obj)
1213
    {
1214
        $ret = false;
1215
        $otherCriteria = new CriteriaCompo();
1216
        $otherCriteria->add(new Criteria('datesub', $obj->getVar('datesub'), '>'));
0 ignored issues
show
Bug introduced by
It seems like $obj->getVar('datesub') can also be of type array; however, parameter $value of Xoops\Core\Kernel\Criteria::__construct() 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

1216
        $otherCriteria->add(new Criteria('datesub', /** @scrutinizer ignore-type */ $obj->getVar('datesub'), '>'));
Loading history...
1217
        $otherCriteria->add(new Criteria('datesub', time(), '<='));
1218
        $objs = $this->getItems(1, 0, array(_PUBLISHER_STATUS_PUBLISHED), $obj->getVar('categoryid'), 'datesub', 'ASC', '', true, $otherCriteria, 'none');
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_PUBLISHED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of PublisherItemHandler::getItems(). ( Ignorable by Annotation )

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

1218
        $objs = $this->getItems(1, 0, /** @scrutinizer ignore-type */ array(_PUBLISHER_STATUS_PUBLISHED), $obj->getVar('categoryid'), 'datesub', 'ASC', '', true, $otherCriteria, 'none');
Loading history...
1219
        if (count($objs) > 0) {
1220
            $ret = $objs[0];
1221
        }
1222
        return $ret;
1223
    }
1224
1225
    /**
1226
     * @param int    $limit
1227
     * @param int    $start
1228
     * @param int    $categoryid
1229
     * @param string $sort
1230
     * @param string $order
1231
     * @param string $notNullFields
1232
     * @param bool   $asobject
1233
     * @param string $id_key
1234
     *
1235
     * @return array
1236
     */
1237
    public function getAllSubmitted($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none')
1238
    {
1239
        return $this->getItems($limit, $start, array(_PUBLISHER_STATUS_SUBMITTED), $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_SUBMITTED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of PublisherItemHandler::getItems(). ( Ignorable by Annotation )

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

1239
        return $this->getItems($limit, $start, /** @scrutinizer ignore-type */ array(_PUBLISHER_STATUS_SUBMITTED), $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
Loading history...
1240
    }
1241
1242
    /**
1243
     * @param int    $limit
1244
     * @param int    $start
1245
     * @param int    $categoryid
1246
     * @param string $sort
1247
     * @param string $order
1248
     * @param string $notNullFields
1249
     * @param bool   $asobject
1250
     * @param string $id_key
1251
     *
1252
     * @return array
1253
     */
1254
    public function getAllOffline($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none')
1255
    {
1256
        return $this->getItems($limit, $start, array(_PUBLISHER_STATUS_OFFLINE), $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_OFFLINE) of type array<integer,integer> is incompatible with the type string expected by parameter $status of PublisherItemHandler::getItems(). ( Ignorable by Annotation )

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

1256
        return $this->getItems($limit, $start, /** @scrutinizer ignore-type */ array(_PUBLISHER_STATUS_OFFLINE), $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
Loading history...
1257
    }
1258
1259
    /**
1260
     * @param int    $limit
1261
     * @param int    $start
1262
     * @param int    $categoryid
1263
     * @param string $sort
1264
     * @param string $order
1265
     * @param string $notNullFields
1266
     * @param bool   $asobject
1267
     * @param string $id_key
1268
     *
1269
     * @return array
1270
     */
1271
    public function getAllRejected($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none')
1272
    {
1273
        return $this->getItems($limit, $start, array(_PUBLISHER_STATUS_REJECTED), $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
0 ignored issues
show
Bug introduced by
array(_PUBLISHER_STATUS_REJECTED) of type array<integer,integer> is incompatible with the type string expected by parameter $status of PublisherItemHandler::getItems(). ( Ignorable by Annotation )

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

1273
        return $this->getItems($limit, $start, /** @scrutinizer ignore-type */ array(_PUBLISHER_STATUS_REJECTED), $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
Loading history...
1274
    }
1275
1276
    /**
1277
     * @param int    $limit
1278
     * @param int    $start
1279
     * @param string $status
1280
     * @param  int   $categoryid
1281
     * @param string $sort
1282
     * @param string $order
1283
     * @param string $notNullFields
1284
     * @param bool   $asobject
1285
     * @param null   $otherCriteria
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $otherCriteria is correct as it would always require null to be passed?
Loading history...
1286
     * @param string $id_key
1287
     *
1288
     * @return array
1289
     */
1290
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $otherCriteria = null, $id_key = 'none')
0 ignored issues
show
Unused Code introduced by
The parameter $asobject is not used and could be removed. ( Ignorable by Annotation )

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

1290
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', /** @scrutinizer ignore-unused */ $asobject = true, $otherCriteria = null, $id_key = 'none')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1291
    {
1292
        global $publisher_isAdmin;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1293
        if (!$publisher_isAdmin) {
1294
            $criteriaPermissions = new CriteriaCompo();
1295
            // Categories for which user has access
1296
            $categoriesGranted = $this->publisher->getPermissionHandler()->getGrantedItems('category_read');
1297
            if (!empty($categoriesGranted)) {
1298
                $grantedCategories = new Criteria('categoryid', "(" . implode(',', $categoriesGranted) . ")", 'IN');
1299
                $criteriaPermissions->add($grantedCategories, 'AND');
1300
            } else {
1301
                return array();
1302
            }
1303
        }
1304
        if (isset($categoryid) && ($categoryid != -1)) {
1305
            $criteriaCategory = new criteria('categoryid', $categoryid);
1306
        }
1307
        if (!empty($status) && is_array($status)) {
0 ignored issues
show
introduced by
The condition ! empty($status) && is_array($status) can never be true.
Loading history...
1308
            $criteriaStatus = new CriteriaCompo();
1309
            foreach ($status as $v) {
1310
                $criteriaStatus->add(new Criteria('status', $v), 'OR');
1311
            }
1312
        } elseif (!empty($status) && $status != -1) {
1313
            $criteriaStatus = new CriteriaCompo();
1314
            $criteriaStatus->add(new Criteria('status', $status), 'OR');
1315
        }
1316
        $criteria = new CriteriaCompo();
1317
        if (!empty($criteriaCategory)) {
1318
            $criteria->add($criteriaCategory);
1319
        }
1320
        if (!empty($criteriaPermissions)) {
1321
            $criteria->add($criteriaPermissions);
1322
        }
1323
        if (!empty($criteriaStatus)) {
1324
            $criteria->add($criteriaStatus);
1325
        }
1326
        if (!empty($otherCriteria)) {
1327
            $criteria->add($otherCriteria);
1328
        }
1329
        $criteria->setLimit($limit);
1330
        $criteria->setStart($start);
1331
        $criteria->setSort($sort);
1332
        $criteria->setOrder($order);
1333
        $ret = $this->getItemObjects($criteria, $id_key, $notNullFields);
1334
        return $ret;
1335
    }
1336
1337
    /**
1338
     * @param string $field
1339
     * @param string $status
1340
     * @param int    $categoryId
1341
     *
1342
     * @return bool
1343
     */
1344
    public function getRandomItem($field = '', $status = '', $categoryId = -1)
1345
    {
1346
        $ret = false;
1347
        $notNullFields = $field;
1348
        // Getting the number of published Items
1349
        $totalItems = $this->getItemsCount($categoryId, $status, $notNullFields);
1350
        if ($totalItems > 0) {
1351
            $totalItems = $totalItems - 1;
1352
            mt_srand((double)microtime() * 1000000);
0 ignored issues
show
Bug introduced by
(double)microtime() * 1000000 of type double is incompatible with the type integer expected by parameter $seed of mt_srand(). ( Ignorable by Annotation )

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

1352
            mt_srand(/** @scrutinizer ignore-type */ (double)microtime() * 1000000);
Loading history...
1353
            $entrynumber = mt_rand(0, $totalItems);
1354
            $item = $this->getItems(1, $entrynumber, $status, $categoryId, $sort = 'datesub', $order = 'DESC', $notNullFields);
1355
            if ($item) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $item of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1356
                $ret = $item[0];
1357
            }
1358
        }
1359
        return $ret;
1360
    }
1361
1362
    /**
1363
     * @param $itemid
1364
     *
1365
     * @return bool
1366
     */
1367
    public function updateCounter($itemid)
1368
    {
1369
        $qb = $this->db2->createXoopsQueryBuilder();
1370
        $qb->updatePrefix('publisher_items', 'i')
1371
            ->set('i.counter', 'i.counter+1')
1372
            ->where('i.itemid = :itemid')
1373
            ->setParameter(':itemid', $itemid, \PDO::PARAM_INT);
1374
        $result = $qb->execute();
1375
        if ($result) {
1376
            return true;
1377
        } else {
1378
            return false;
1379
        }
1380
    }
1381
1382
    /**
1383
     * addNotNullFieldClause exclude rows where specified columns are empty or null
1384
     *
1385
     * @param QueryBuilder $qb            QueryBuilder instance
0 ignored issues
show
Bug introduced by
The type QueryBuilder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1386
     * @param string|array $notNullFields fields that should not be empty
1387
     * @param string       $whereMode     Initial where method, 'AND' andWhere(), otherwise where()
1388
     *
1389
     * @return QueryBuilder instance
1390
     */
1391
    protected function addNotNullFieldClause(\Xoops\Core\Database\QueryBuilder $qb, $notNullFields = array(), $whereMode = '')
1392
    {
1393
        $eb = $qb->expr();
1394
        if (!empty($notNullFields)) {
1395
            if (!is_array($notNullFields)) {
1396
                $notNullFields = (array) $notNullFields;
1397
            }
1398
            foreach ($notNullFields as $v) {
1399
                if ($whereMode === 'AND') {
1400
                    $qb ->andWhere($eb->isNotNull($v, ''))
0 ignored issues
show
Unused Code introduced by
The call to Doctrine\DBAL\Query\Expr...ionBuilder::isNotNull() has too many arguments starting with ''. ( Ignorable by Annotation )

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

1400
                    $qb ->andWhere($eb->/** @scrutinizer ignore-call */ isNotNull($v, ''))

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1401
                        ->andWhere($eb->neq($v, "''"));
1402
                } else {
1403
                    $qb ->where($eb->isNotNull($v, ''))
1404
                        ->andWhere($eb->neq($v, "''"));
1405
                    $whereMode = 'AND';
1406
                }
1407
            }
1408
        }
1409
1410
        return $qb;
1411
    }
1412
1413
    /**
1414
     * @param array  $queryarray
1415
     * @param string $andor
1416
     * @param int    $limit
1417
     * @param int    $offset
1418
     * @param int    $userid
1419
     * @param array  $categories
1420
     * @param int    $sortby
1421
     * @param string $searchin
1422
     * @param string $extra
1423
     *
1424
     * @return array
1425
     */
1426
    public function getItemsFromSearch($queryarray = array(), $andor = 'AND', $limit = 0, $offset = 0, $userid = 0, $categories = array(), $sortby = 0, $searchin = "", $extra = "")
0 ignored issues
show
Unused Code introduced by
The parameter $extra is not used and could be removed. ( Ignorable by Annotation )

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

1426
    public function getItemsFromSearch($queryarray = array(), $andor = 'AND', $limit = 0, $offset = 0, $userid = 0, $categories = array(), $sortby = 0, $searchin = "", /** @scrutinizer ignore-unused */ $extra = "")

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1427
    {
1428
        $xoops = Xoops::getInstance();
1429
        $ret = array();
1430
        $gperm_handler = $xoops->getHandlerGroupPermission();
1431
        $groups = $xoops->getUserGroups();
1432
        $searchin = empty($searchin) ? array(
1433
            "title",
1434
            "body",
1435
            "summary"
1436
        ) : (is_array($searchin) ? $searchin : array($searchin));
0 ignored issues
show
introduced by
The condition is_array($searchin) can never be true.
Loading history...
1437
        if (in_array("all", $searchin) || count($searchin) == 0) {
1438
            $searchin = array("title", "subtitle", "body", "summary", "meta_keywords");
1439
        }
1440
        if (is_array($userid) && count($userid) > 0) {
0 ignored issues
show
introduced by
The condition is_array($userid) && count($userid) > 0 can never be true.
Loading history...
1441
            $userid = array_map("intval", $userid);
1442
            $criteriaUser = new CriteriaCompo();
1443
            $criteriaUser->add(new Criteria('uid', '(' . implode(',', $userid) . ')', 'IN'), 'OR');
1444
        } elseif (is_numeric($userid) && $userid > 0) {
1445
            $criteriaUser = new CriteriaCompo();
1446
            $criteriaUser->add(new Criteria('uid', $userid), 'OR');
1447
        }
1448
        $count = count($queryarray);
1449
        if (is_array($queryarray) && $count > 0) {
1450
            $criteriaKeywords = new CriteriaCompo();
1451
            for ($i = 0; $i < count($queryarray); ++$i) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1452
                $criteriaKeyword = new CriteriaCompo();
1453
                if (in_array('title', $searchin)) {
1454
                    $criteriaKeyword->add(new Criteria('title', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1455
                }
1456
                if (in_array('subtitle', $searchin)) {
1457
                    $criteriaKeyword->add(new Criteria('subtitle', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1458
                }
1459
                if (in_array('body', $searchin)) {
1460
                    $criteriaKeyword->add(new Criteria('body', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1461
                }
1462
                if (in_array('summary', $searchin)) {
1463
                    $criteriaKeyword->add(new Criteria('summary', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1464
                }
1465
                if (in_array('meta_keywords', $searchin)) {
1466
                    $criteriaKeyword->add(new Criteria('meta_keywords', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1467
                }
1468
                $criteriaKeywords->add($criteriaKeyword, $andor);
1469
                unset($criteriaKeyword);
1470
            }
1471
        }
1472
        if (!PublisherUtils::IsUserAdmin() && (count($categories) > 0)) {
1473
            $criteriaPermissions = new CriteriaCompo();
1474
            // Categories for which user has access
1475
            $categoriesGranted = $gperm_handler->getItemIds('category_read', $groups, $this->publisher->getModule()->getVar('mid'));
1476
            if (count($categories) > 0) {
1477
                $categoriesGranted = array_intersect($categoriesGranted, $categories);
1478
            }
1479
            if (count($categoriesGranted) == 0) {
1480
                return $ret;
1481
            }
1482
            $grantedCategories = new Criteria('categoryid', "(" . implode(',', $categoriesGranted) . ")", 'IN');
1483
            $criteriaPermissions->add($grantedCategories, 'AND');
1484
        } elseif (count($categories) > 0) {
1485
            $criteriaPermissions = new CriteriaCompo();
1486
            $grantedCategories = new Criteria('categoryid', "(" . implode(',', $categories) . ")", 'IN');
1487
            $criteriaPermissions->add($grantedCategories, 'AND');
1488
        }
1489
        $criteriaItemsStatus = new CriteriaCompo();
1490
        $criteriaItemsStatus->add(new Criteria('status', _PUBLISHER_STATUS_PUBLISHED));
1491
        $criteria = new CriteriaCompo();
1492
        if (!empty($criteriaUser)) {
1493
            $criteria->add($criteriaUser, 'AND');
1494
        }
1495
        if (!empty($criteriaKeywords)) {
1496
            $criteria->add($criteriaKeywords, 'AND');
1497
        }
1498
        if (!empty($criteriaPermissions)) {
1499
            $criteria->add($criteriaPermissions);
1500
        }
1501
        if (!empty($criteriaItemsStatus)) {
1502
            $criteria->add($criteriaItemsStatus, 'AND');
1503
        }
1504
        $criteria->setLimit($limit);
1505
        $criteria->setStart($offset);
1506
        if (empty($sortby)) {
1507
            $sortby = "datesub";
1508
        }
1509
        $criteria->setSort($sortby);
1510
        $order = 'ASC';
1511
        if ($sortby === "datesub") {
1512
            $order = 'DESC';
1513
        }
1514
        $criteria->setOrder($order);
1515
        $ret = $this->getItemObjects($criteria);
1516
        return $ret;
1517
    }
1518
1519
    /**
1520
     * @param array  $categoriesObj
1521
     * @param array  $status
1522
     *
1523
     * @return array
1524
     */
1525
    public function getLastPublishedByCat($categoriesObj, $status = array(_PUBLISHER_STATUS_PUBLISHED))
1526
    {
1527
        $ret = array();
1528
        $catIds = array();
1529
        /* @var $category PublisherCategory */
1530
        foreach ($categoriesObj as $parentid) {
1531
            foreach ($parentid as $category) {
1532
                $catId = $category->getVar('categoryid');
1533
                $catIds[$catId] = $catId;
1534
            }
1535
        }
1536
        if (empty($catIds)) {
1537
            return $ret;
1538
        }
1539
1540
        // $sql = "SELECT mi.categoryid, mi.itemid, mi.title, mi.short_url, mi.uid, mi.datesub";
1541
        // $sql .= " FROM (SELECT categoryid, MAX(datesub) AS date FROM " . $this->db->prefix('publisher_items');
1542
        // $sql .= " WHERE status IN (" . implode(',', $status) . ")";
1543
        // $sql .= " AND categoryid IN (" . implode(',', $catIds) . ")";
1544
        // $sql .= " GROUP BY categoryid)mo";
1545
        // $sql .= " JOIN " . $this->db->prefix('publisher_items') . " mi ON mi.datesub = mo.date";
1546
1547
        $qb = $this->db2->createXoopsQueryBuilder();
1548
        $qb->select('mi.categoryid', 'mi.itemid', 'mi.title', 'mi.short_url', 'mi.uid', 'mi.datesub');
1549
1550
        $subqb = $this->db2->createXoopsQueryBuilder();
1551
        $subqb->select('categoryid', 'MAX(datesub) AS date')
1552
            ->fromPrefix('publisher_items', '')
1553
            ->where($subqb->expr()->in('status', $status))
1554
            ->andWhere($subqb->expr()->in('categoryid', $catIds))
1555
            ->groupBy('categoryid');
1556
        $subquery = '('.$subqb->getSQL().')';
1557
1558
        $qb ->from($subquery, 'mo')
1559
            ->joinPrefix('mo', 'publisher_items', 'mi', 'mi.datesub = mo.date');
1560
1561
        $result = $qb->execute();
1562
        while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
1563
            $item = new PublisherItem();
1564
            $item->assignVars($row);
1565
            $ret[$row['categoryid']] = $item;
1566
            unset($item);
1567
        }
1568
        return $ret;
1569
    }
1570
1571
    /**
1572
     * @param int         $parentid
1573
     * @param array       $catsCount
1574
     * @param string      $spaces
1575
     * @param array       $resultCatCounts
1576
     *
1577
     * @return int
1578
     */
1579
    public function countArticlesByCat($parentid, &$catsCount, $spaces = '', $resultCatCounts = array())
1580
    {
1581
        $newspaces = $spaces . '--';
1582
        $thecount = 0;
1583
        foreach ($catsCount[$parentid] as $subCatId => $count) {
1584
            $thecount = $thecount + $count;
1585
            $resultCatCounts[$subCatId] = $count;
1586
            if (isset($catsCount[$subCatId])) {
1587
                $thecount = $thecount + $this->countArticlesByCat($subCatId, $catsCount, $newspaces, $resultCatCounts);
1588
                $resultCatCounts[$subCatId] = $thecount;
1589
            }
1590
        }
1591
        return $thecount;
1592
    }
1593
1594
    /**
1595
     * @param int     $cat_id
1596
     * @param array   $status
1597
     * @param bool    $inSubCat
1598
     *
1599
     * @return array
1600
     */
1601
    public function getCountsByCat($cat_id = 0, $status, $inSubCat = false)
1602
    {
1603
        $ret = array();
1604
        $catsCount = array();
1605
1606
        $qb = $this->db2->createXoopsQueryBuilder();
1607
        $qb ->select('c.parentid', 'i.categoryid', 'COUNT(*) AS count')
1608
            ->fromPrefix('publisher_items', 'i')
1609
            ->innerJoinPrefix('i', 'publisher_categories', 'c', 'i.categoryid=c.categoryid')
1610
            ->where($qb->expr()->in('i.status', $status))
1611
            ->groupBy('i.categoryid')
1612
            ->orderBy('c.parentid', 'ASC')
1613
            ->addOrderBy('i.categoryid', 'ASC');
1614
        if ((int)($cat_id) > 0) {
1615
            $qb ->andWhere($qb->expr()->eq('i.categoryid', ':catid'))
1616
                ->setParameter(':catid', $cat_id, \PDO::PARAM_INT);
1617
        }
1618
1619
        //$sql = 'SELECT c.parentid, i.categoryid, COUNT(*) AS count FROM ' . $this->db->prefix('publisher_items')
1620
        //. ' AS i INNER JOIN ' . $this->db->prefix('publisher_categories') . ' AS c ON i.categoryid=c.categoryid';
1621
        //if ((int)($cat_id) > 0) {
1622
        //    $sql .= ' WHERE i.categoryid = ' . (int)($cat_id);
1623
        //    $sql .= ' AND i.status IN (' . implode(',', $status) . ')';
1624
        //} else {
1625
        //    $sql .= ' WHERE i.status IN (' . implode(',', $status) . ')';
1626
        //}
1627
        //$sql .= ' GROUP BY i.categoryid ORDER BY c.parentid ASC, i.categoryid ASC';
1628
1629
        $result = $qb->execute();
1630
1631
        if (!$result) {
1632
            return $ret;
1633
        }
1634
        if (!$inSubCat) {
1635
            while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
1636
                $catsCount[$row['categoryid']] = $row['count'];
1637
            }
1638
            return $catsCount;
1639
        }
1640
        while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
1641
            $catsCount[$row['parentid']][$row['categoryid']] = $row['count'];
1642
        }
1643
        $resultCatCounts = array();
1644
        foreach ($catsCount[0] as $subCatId => $count) {
1645
            $resultCatCounts[$subCatId] = $count;
1646
            if (isset($catsCount[$subCatId])) {
1647
                $resultCatCounts[$subCatId] = $resultCatCounts[$subCatId] + $this->countArticlesByCat($subCatId, $catsCount, $spaces = '', $resultCatCounts);
1648
            }
1649
        }
1650
        return $resultCatCounts;
1651
    }
1652
}
1653