Completed
Branch master (b963e0)
by Michael
03:39
created

PublisherItemHandler::getRandomItem()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 3
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 31 and the first side effect is on line 26.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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
/**
13
 * @copyright       The XUUPS Project http://sourceforge.net/projects/xuups/
14
 * @license         http://www.fsf.org/copyleft/gpl.html GNU public license
15
 * @package         Publisher
16
 * @since           1.0
17
 * @author          trabis <[email protected]>
18
 * @author          The SmartFactory <www.smartfactory.ca>
19
 */
20
21
use Xmf\Request;
22
23
//namespace Publisher;
24
25
// defined('XOOPS_ROOT_PATH') || exit('Restricted access.');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
26
require_once dirname(__DIR__) . '/include/common.php';
27
28
/**
29
 * Class PublisherItem
30
 */
31
class PublisherItem extends XoopsObject
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
32
{
33
    /**
34
     * @var Publisher
35
     * @access public
36
     */
37
    public $publisher;
38
    public $groupsRead = [];
39
40
    /**
41
     * @var PublisherCategory
42
     * @access public
43
     */
44
    public $category;
45
46
    /**
47
     * @param int|null $id
48
     */
49
    public function __construct($id = null)
50
    {
51
        $this->publisher = Publisher::getInstance();
52
        $this->db        = XoopsDatabaseFactory::getDatabaseConnection();
53
        $this->initVar('itemid', XOBJ_DTYPE_INT, 0);
54
        $this->initVar('categoryid', XOBJ_DTYPE_INT, 0, false);
55
        $this->initVar('title', XOBJ_DTYPE_TXTBOX, '', true, 255);
56
        $this->initVar('subtitle', XOBJ_DTYPE_TXTBOX, '', false, 255);
57
        $this->initVar('summary', XOBJ_DTYPE_TXTAREA, '', false);
58
        $this->initVar('body', XOBJ_DTYPE_TXTAREA, '', false);
59
        $this->initVar('uid', XOBJ_DTYPE_INT, 0, false);
60
        $this->initVar('author_alias', XOBJ_DTYPE_TXTBOX, '', false, 255);
61
        $this->initVar('datesub', XOBJ_DTYPE_INT, '', false);
62
        $this->initVar('status', XOBJ_DTYPE_INT, -1, false);
63
        $this->initVar('image', XOBJ_DTYPE_INT, 0, false);
64
        $this->initVar('images', XOBJ_DTYPE_TXTBOX, '', false, 255);
65
        $this->initVar('counter', XOBJ_DTYPE_INT, 0, false);
66
        $this->initVar('rating', XOBJ_DTYPE_OTHER, 0, false);
67
        $this->initVar('votes', XOBJ_DTYPE_INT, 0, false);
68
        $this->initVar('weight', XOBJ_DTYPE_INT, 0, false);
69
        $this->initVar('dohtml', XOBJ_DTYPE_INT, 1, true);
70
        $this->initVar('dosmiley', XOBJ_DTYPE_INT, 1, true);
71
        $this->initVar('doimage', XOBJ_DTYPE_INT, 1, true);
72
        $this->initVar('dobr', XOBJ_DTYPE_INT, 1, false);
73
        $this->initVar('doxcode', XOBJ_DTYPE_INT, 1, true);
74
        $this->initVar('cancomment', XOBJ_DTYPE_INT, 1, true);
75
        $this->initVar('comments', XOBJ_DTYPE_INT, 0, false);
76
        $this->initVar('notifypub', XOBJ_DTYPE_INT, 1, false);
77
        $this->initVar('meta_keywords', XOBJ_DTYPE_TXTAREA, '', false);
78
        $this->initVar('meta_description', XOBJ_DTYPE_TXTAREA, '', false);
79
        $this->initVar('short_url', XOBJ_DTYPE_TXTBOX, '', false, 255);
80
        $this->initVar('item_tag', XOBJ_DTYPE_TXTAREA, '', false);
81
        // Non consistent values
82
        $this->initVar('pagescount', XOBJ_DTYPE_INT, 0, false);
83 View Code Duplication
        if (isset($id)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
84
            $item = $this->publisher->getHandler('item')->get($id);
85
            foreach ($item->vars as $k => $v) {
86
                $this->assignVar($k, $v['value']);
87
            }
88
        }
89
    }
90
91
    /**
92
     * @param string $method
93
     * @param array  $args
94
     *
95
     * @return mixed
96
     */
97
    public function __call($method, $args)
98
    {
99
        $arg = isset($args[0]) ? $args[0] : null;
100
101
        return $this->getVar($method, $arg);
102
    }
103
104
    /**
105
     * @return null|PublisherCategory
106
     */
107
    public function getCategory()
108
    {
109
        if (!isset($this->category)) {
110
            $this->category = $this->publisher->getHandler('category')->get($this->getVar('categoryid'));
111
        }
112
113
        return $this->category;
114
    }
115
116
    /**
117
     * @param int    $maxLength
118
     * @param string $format
119
     *
120
     * @return mixed|string
121
     */
122 View Code Duplication
    public function getTitle($maxLength = 0, $format = 'S')
123
    {
124
        $ret = $this->getVar('title', $format);
125
        if (0 != $maxLength) {
126
            if (!XOOPS_USE_MULTIBYTES) {
127
                if (strlen($ret) >= $maxLength) {
128
                    $ret = PublisherUtility::substr($ret, 0, $maxLength);
129
                }
130
            }
131
        }
132
133
        return $ret;
134
    }
135
136
    /**
137
     * @param int    $maxLength
138
     * @param string $format
139
     *
140
     * @return mixed|string
141
     */
142 View Code Duplication
    public function getSubtitle($maxLength = 0, $format = 'S')
143
    {
144
        $ret = $this->getVar('subtitle', $format);
145
        if (0 != $maxLength) {
146
            if (!XOOPS_USE_MULTIBYTES) {
147
                if (strlen($ret) >= $maxLength) {
148
                    $ret = PublisherUtility::substr($ret, 0, $maxLength);
149
                }
150
            }
151
        }
152
153
        return $ret;
154
    }
155
156
    /**
157
     * @param int    $maxLength
158
     * @param string $format
159
     * @param string $stripTags
160
     *
161
     * @return mixed|string
162
     */
163
    public function getSummary($maxLength = 0, $format = 'S', $stripTags = '')
164
    {
165
        $ret = $this->getVar('summary', $format);
166
        if (!empty($stripTags)) {
167
            $ret = strip_tags($ret, $stripTags);
168
        }
169 View Code Duplication
        if (0 != $maxLength) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
170
            if (!XOOPS_USE_MULTIBYTES) {
171
                if (strlen($ret) >= $maxLength) {
172
                    //$ret = PublisherUtility::substr($ret , 0, $maxLength);
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
173
                    $ret = PublisherUtility::truncateTagSafe($ret, $maxLength, $etc = '...', $breakWords = false);
174
                }
175
            }
176
        }
177
178
        return $ret;
179
    }
180
181
    /**
182
     * @param int  $maxLength
183
     * @param bool $fullSummary
184
     *
185
     * @return mixed|string
186
     */
187
    public function getBlockSummary($maxLength = 0, $fullSummary = false)
188
    {
189
        if ($fullSummary) {
190
            $ret = $this->getSummary(0, 's', '<br><br>');
191
        } else {
192
            $ret = $this->getSummary($maxLength, 's', '<br><br>');
193
        }
194
        //no summary? get body!
195
        if ('' === $ret) {
196
            $ret = $this->getBody($maxLength, 's', '<br><br>');
197
        }
198
199
        return $ret;
200
    }
201
202
    /**
203
     * @param string $fileName
204
     *
205
     * @return string
206
     */
207
    public function wrapPage($fileName)
208
    {
209
        $content = '';
210
        $page    = PublisherUtility::getUploadDir(true, 'content') . $fileName;
211
        if (file_exists($page)) {
212
            // this page uses smarty template
213
            ob_start();
214
            include $page;
215
            $content = ob_get_contents();
216
            ob_end_clean();
217
            // Cleaning the content
218
            $bodyStartPos = strpos($content, '<body>');
219
            if ($bodyStartPos) {
220
                $bodyEndPos = strpos($content, '</body>', $bodyStartPos);
221
                $content    = substr($content, $bodyStartPos + strlen('<body>'), $bodyEndPos - strlen('<body>') - $bodyStartPos);
222
            }
223
            // Check if ML Hack is installed, and if yes, parse the $content in formatForML
224
            $myts = MyTextSanitizer::getInstance();
225
            if (method_exists($myts, 'formatForML')) {
226
                $content = $myts->formatForML($content);
227
            }
228
        }
229
230
        return $content;
231
    }
232
233
    /**
234
     * This method returns the body to be displayed. Not to be used for editing
235
     *
236
     * @param int    $maxLength
237
     * @param string $format
238
     * @param string $stripTags
239
     *
240
     * @return mixed|string
241
     */
242
    public function getBody($maxLength = 0, $format = 'S', $stripTags = '')
243
    {
244
        $ret     = $this->getVar('body', $format);
245
        $wrapPos = strpos($ret, '[pagewrap=');
246
        if (!(false === $wrapPos)) {
247
            $wrapPages      = [];
248
            $wrapCodeLength = strlen('[pagewrap=');
249
            while (!(false === $wrapPos)) {
250
                $endWrapPos = strpos($ret, ']', $wrapPos);
251
                if ($endWrapPos) {
252
                    $wrap_page_name = substr($ret, $wrapPos + $wrapCodeLength, $endWrapPos - $wrapCodeLength - $wrapPos);
253
                    $wrapPages[]    = $wrap_page_name;
254
                }
255
                $wrapPos = strpos($ret, '[pagewrap=', $endWrapPos - 1);
256
            }
257
            foreach ($wrapPages as $page) {
258
                $wrapPageContent = $this->wrapPage($page);
259
                $ret             = str_replace("[pagewrap={$page}]", $wrapPageContent, $ret);
260
            }
261
        }
262
        if ($this->publisher->getConfig('item_disp_blocks_summary')) {
263
            $summary = $this->getSummary($maxLength, $format, $stripTags);
264
            if ($summary) {
265
                $ret = $this->getSummary() . '<br><br>' . $ret;
266
            }
267
        }
268
        if (!empty($stripTags)) {
269
            $ret = strip_tags($ret, $stripTags);
270
        }
271 View Code Duplication
        if (0 != $maxLength) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
272
            if (!XOOPS_USE_MULTIBYTES) {
273
                if (strlen($ret) >= $maxLength) {
274
                    //$ret = PublisherUtility::substr($ret , 0, $maxLength);
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
275
                    $ret = PublisherUtility::truncateTagSafe($ret, $maxLength, $etc = '...', $breakWords = false);
276
                }
277
            }
278
        }
279
280
        return $ret;
281
    }
282
283
    /**
284
     * @param string $dateFormat
285
     * @param string $format
286
     *
287
     * @return string
288
     */
289
    public function getDatesub($dateFormat = '', $format = 'S')
290
    {
291
        if (empty($dateFormat)) {
292
            $dateFormat = $this->publisher->getConfig('format_date');
293
        }
294
295
        return formatTimestamp($this->getVar('datesub', $format), $dateFormat);
296
    }
297
298
    /**
299
     * @param int $realName
300
     *
301
     * @return string
302
     */
303
    public function posterName($realName = -1)
304
    {
305
        xoops_load('XoopsUserUtility');
306
        if ($realName == -1) {
307
            $realName = $this->publisher->getConfig('format_realname');
308
        }
309
        $ret = $this->author_alias();
310
        if ('' == $ret) {
311
            $ret = XoopsUserUtility::getUnameFromId($this->uid(), $realName);
312
        }
313
314
        return $ret;
315
    }
316
317
    /**
318
     * @return string
319
     */
320
    public function posterAvatar()
321
    {
322
        $ret           = 'blank.gif';
323
        $memberHandler = xoops_getHandler('member');
324
        $thisUser      = $memberHandler->getUser($this->uid());
325
        if (is_object($thisUser)) {
326
            $ret = $thisUser->getVar('user_avatar');
327
        }
328
329
        return $ret;
330
    }
331
332
    /**
333
     * @return string
334
     */
335
    public function getLinkedPosterName()
336
    {
337
        xoops_load('XoopsUserUtility');
338
        $ret = $this->author_alias();
339
        if ('' === $ret) {
340
            $ret = XoopsUserUtility::getUnameFromId($this->uid(), $this->publisher->getConfig('format_realname'), true);
341
        }
342
343
        return $ret;
344
    }
345
346
    /**
347
     * @return mixed
348
     */
349
    public function updateCounter()
350
    {
351
        return $this->publisher->getHandler('item')->updateCounter($this->itemid());
352
    }
353
354
    /**
355
     * @param bool $force
356
     *
357
     * @return bool
358
     */
359
    public function store($force = true)
360
    {
361
        $isNew = $this->isNew();
362
        if (!$this->publisher->getHandler('item')->insert($this, $force)) {
363
            return false;
364
        }
365
        if ($isNew && $this->status() == PublisherConstants::PUBLISHER_STATUS_PUBLISHED) {
366
            // Increment user posts
367
            $userHandler   = xoops_getHandler('user');
368
            $memberHandler = xoops_getHandler('member');
369
            $poster        = $userHandler->get($this->uid());
370
            if (is_object($poster) && !$poster->isNew()) {
371
                $poster->setVar('posts', $poster->getVar('posts') + 1);
372
                if (!$memberHandler->insertUser($poster, true)) {
373
                    $this->setErrors('Article created but could not increment user posts.');
374
375
                    return false;
376
                }
377
            }
378
        }
379
380
        return true;
381
    }
382
383
    /**
384
     * @return string
385
     */
386
    public function getCategoryName()
387
    {
388
        return $this->getCategory()->name();
389
    }
390
391
    /**
392
     * @return string
393
     */
394
    public function getCategoryUrl()
395
    {
396
        return $this->getCategory()->getCategoryUrl();
397
    }
398
399
    /**
400
     * @return string
401
     */
402
    public function getCategoryLink()
403
    {
404
        return $this->getCategory()->getCategoryLink();
405
    }
406
407
    /**
408
     * @param bool $withAllLink
409
     *
410
     * @return string
411
     */
412
    public function getCategoryPath($withAllLink = true)
413
    {
414
        return $this->getCategory()->getCategoryPath($withAllLink);
415
    }
416
417
    /**
418
     * @return string
419
     */
420
    public function getCategoryImagePath()
421
    {
422
        return PublisherUtility::getImageDir('category', false) . $this->getCategory()->getImage();
423
    }
424
425
    /**
426
     * @return mixed
427
     */
428
    public function getFiles()
429
    {
430
        return $this->publisher->getHandler('file')->getAllFiles($this->itemid(), PublisherConstants::PUBLISHER_STATUS_FILE_ACTIVE);
431
    }
432
433
    /**
434
     * @return string
435
     */
436
    public function getAdminLinks()
0 ignored issues
show
Coding Style introduced by
getAdminLinks uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
437
    {
438
        $adminLinks = '';
439
        if (is_object($GLOBALS['xoopsUser'])
440
            && (PublisherUtility::userIsAdmin() || PublisherUtility::userIsAuthor($this)
441
                || $this->publisher->getHandler('permission')->isGranted('item_submit', $this->categoryid()))) {
442
            if (PublisherUtility::userIsAdmin() || PublisherUtility::userIsAuthor($this) || PublisherUtility::userIsModerator($this)) {
443 View Code Duplication
                if ($this->publisher->getConfig('perm_edit') || PublisherUtility::userIsModerator($this) || PublisherUtility::userIsAdmin()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
444
                    // Edit button
445
                    $adminLinks .= "<a href='" . PUBLISHER_URL . '/submit.php?itemid=' . $this->itemid() . "'><img src='" . PUBLISHER_URL . "/assets/images/links/edit.gif'" . " title='" . _CO_PUBLISHER_EDIT . "' alt='" . _CO_PUBLISHER_EDIT . "'></a>";
446
                    $adminLinks .= ' ';
447
                }
448 View Code Duplication
                if ($this->publisher->getConfig('perm_delete') || PublisherUtility::userIsModerator($this) || PublisherUtility::userIsAdmin()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
449
                    // Delete button
450
                    $adminLinks .= "<a href='" . PUBLISHER_URL . '/submit.php?op=del&amp;itemid=' . $this->itemid() . "'><img src='" . PUBLISHER_URL . "/assets/images/links/delete.png'" . " title='" . _CO_PUBLISHER_DELETE . "' alt='" . _CO_PUBLISHER_DELETE . "'></a>";
451
                    $adminLinks .= ' ';
452
                }
453
            }
454 View Code Duplication
            if ($this->publisher->getConfig('perm_clone') || PublisherUtility::userIsModerator($this) || PublisherUtility::userIsAdmin()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
455
                // Duplicate button
456
                $adminLinks .= "<a href='" . PUBLISHER_URL . '/submit.php?op=clone&amp;itemid=' . $this->itemid() . "'><img src='" . PUBLISHER_URL . "/assets/images/links/clone.gif'" . " title='" . _CO_PUBLISHER_CLONE . "' alt='" . _CO_PUBLISHER_CLONE . "'></a>";
457
                $adminLinks .= ' ';
458
            }
459
        }
460
461
        // PDF button
462
        if ($this->publisher->getConfig('display_pdf')) {
463
            if (!is_file(XOOPS_ROOT_PATH . '/class/libraries/vendor/tecnickcom/tcpdf/tcpdf.php')) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
464
                //                if (is_object($GLOBALS['xoopsUser']) && PublisherUtility::userIsAdmin()) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
465
                //                    $GLOBALS['xoTheme']->addStylesheet('/modules/system/css/jquery.jgrowl.min.css');
0 ignored issues
show
Unused Code Comprehensibility introduced by
82% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
466
                //                    $GLOBALS['xoTheme']->addScript('browse.php?Frameworks/jquery/plugins/jquery.jgrowl.js');
0 ignored issues
show
Unused Code Comprehensibility introduced by
82% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
467
                //                    $adminLinks .= '<script type="text/javascript">
468
                //                    (function($){
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
469
                //                        $(document).ready(function(){
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
470
                //                            $.jGrowl("' . _MD_PUBLISHER_ERROR_NO_PDF . '");});
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
471
                //                        })(jQuery);
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
472
                //                        </script>';
473
                //                }
474
            } else {
475
                $adminLinks .= "<a href='" . PUBLISHER_URL . '/makepdf.php?itemid=' . $this->itemid() . "' rel='nofollow' target='_blank'><img src='" . PUBLISHER_URL . "/assets/images/links/pdf.gif'" . " title='" . _CO_PUBLISHER_PDF . "' alt='" . _CO_PUBLISHER_PDF . "'></a>";
476
                $adminLinks .= ' ';
477
            }
478
        }
479
480
        // Print button
481
        $adminLinks .= "<a href='" . PublisherSeo::generateUrl('print', $this->itemid(), $this->short_url()) . "' rel='nofollow' target='_blank'><img src='" . PUBLISHER_URL . "/assets/images/links/print.gif' title='" . _CO_PUBLISHER_PRINT . "' alt='" . _CO_PUBLISHER_PRINT . "'></a>";
482
        $adminLinks .= ' ';
483
        // Email button
484
        if (xoops_isActiveModule('tellafriend')) {
485
            $subject    = sprintf(_CO_PUBLISHER_INTITEMFOUND, $GLOBALS['xoopsConfig']['sitename']);
486
            $subject    = $this->convertForJapanese($subject);
487
            $maillink   = PublisherUtility::tellAFriend($subject);
488
            $adminLinks .= '<a href="' . $maillink . '"><img src="' . PUBLISHER_URL . '/assets/images/links/friend.gif" title="' . _CO_PUBLISHER_MAIL . '" alt="' . _CO_PUBLISHER_MAIL . '"></a>';
489
            $adminLinks .= ' ';
490
        }
491
492
        return $adminLinks;
493
    }
494
495
    /**
496
     * @param array $notifications
497
     */
498
    public function sendNotifications($notifications = [])
499
    {
500
        $notificationHandler = xoops_getHandler('notification');
501
        $tags                = [];
502
503
        $tags['MODULE_NAME']   = $this->publisher->getModule()->getVar('name');
504
        $tags['ITEM_NAME']     = $this->getTitle();
505
        $tags['ITEM_NAME']     = $this->subtitle();
506
        $tags['CATEGORY_NAME'] = $this->getCategoryName();
507
        $tags['CATEGORY_URL']  = PUBLISHER_URL . '/category.php?categoryid=' . $this->categoryid();
508
        $tags['ITEM_BODY']     = $this->body();
509
        $tags['DATESUB']       = $this->getDatesub();
510
        foreach ($notifications as $notification) {
511
            switch ($notification) {
512
                case PublisherConstants::PUBLISHER_NOTIFY_ITEM_PUBLISHED:
513
                    $tags['ITEM_URL'] = PUBLISHER_URL . '/item.php?itemid=' . $this->itemid();
514
                    $notificationHandler->triggerEvent('global_item', 0, 'published', $tags, [], $this->publisher->getModule()->getVar('mid'));
515
                    $notificationHandler->triggerEvent('category_item', $this->categoryid(), 'published', $tags, [], $this->publisher->getModule()->getVar('mid'));
516
                    $notificationHandler->triggerEvent('item', $this->itemid(), 'approved', $tags, [], $this->publisher->getModule()->getVar('mid'));
517
                    break;
518
                case PublisherConstants::PUBLISHER_NOTIFY_ITEM_SUBMITTED:
519
                    $tags['WAITINGFILES_URL'] = PUBLISHER_URL . '/admin/item.php?itemid=' . $this->itemid();
520
                    $notificationHandler->triggerEvent('global_item', 0, 'submitted', $tags, [], $this->publisher->getModule()->getVar('mid'));
521
                    $notificationHandler->triggerEvent('category_item', $this->categoryid(), 'submitted', $tags, [], $this->publisher->getModule()->getVar('mid'));
522
                    break;
523
                case PublisherConstants::PUBLISHER_NOTIFY_ITEM_REJECTED:
524
                    $notificationHandler->triggerEvent('item', $this->itemid(), 'rejected', $tags, [], $this->publisher->getModule()->getVar('mid'));
525
                    break;
526
                case -1:
527
                default:
528
                    break;
529
            }
530
        }
531
    }
532
533
    /**
534
     * Sets default permissions for this item
535
     */
536 View Code Duplication
    public function setDefaultPermissions()
537
    {
538
        $memberHandler = xoops_getHandler('member');
539
        $groups        = $memberHandler->getGroupList();
540
        $j             = 0;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $j. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
541
        $groupIds      = [];
542
        foreach (array_keys($groups) as $i) {
543
            $groupIds[$j] = $i;
544
            ++$j;
545
        }
546
        $this->groupsRead = $groupIds;
547
    }
548
549
    /**
550
     * @todo look at this
551
     *
552
     * @param $groupIds
553
     */
554 View Code Duplication
    public function setPermissions($groupIds)
555
    {
556
        if (!isset($groupIds)) {
557
            $memberHandler = xoops_getHandler('member');
558
            $groups        = $memberHandler->getGroupList();
559
            $j             = 0;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $j. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
560
            $groupIds      = [];
561
            foreach (array_keys($groups) as $i) {
562
                $groupIds[$j] = $i;
563
                ++$j;
564
            }
565
        }
566
    }
567
568
    /**
569
     * @return bool
570
     */
571
    public function notLoaded()
572
    {
573
        return $this->getVar('itemid') == -1;
574
    }
575
576
    /**
577
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
578
     */
579
    public function getItemUrl()
580
    {
581
        return PublisherSeo::generateUrl('item', $this->itemid(), $this->short_url());
582
    }
583
584
    /**
585
     * @param bool $class
586
     * @param int  $maxsize
587
     *
588
     * @return string
589
     */
590
    public function getItemLink($class = false, $maxsize = 0)
591
    {
592
        if ($class) {
593
            return '<a class=' . $class . ' href="' . $this->getItemUrl() . '">' . $this->getTitle($maxsize) . '</a>';
594
        } else {
595
            return '<a href="' . $this->getItemUrl() . '">' . $this->getTitle($maxsize) . '</a>';
596
        }
597
    }
598
599
    /**
600
     * @return string
601
     */
602
    public function getWhoAndWhen()
603
    {
604
        $posterName = $this->getLinkedPosterName();
605
        $postdate   = $this->getDatesub();
606
607
        return sprintf(_CO_PUBLISHER_POSTEDBY, $posterName, $postdate);
608
    }
609
610
    /**
611
     * @return string
612
     */
613
    public function getWho()
614
    {
615
        $posterName = $this->getLinkedPosterName();
616
617
        return $posterName;
618
    }
619
620
    /**
621
     * @return string
622
     */
623
    public function getWhen()
624
    {
625
        $postdate = $this->getDatesub();
626
627
        return $postdate;
628
    }
629
630
    /**
631
     * @param null|string $body
632
     *
633
     * @return string
634
     */
635
    public function plainMaintext($body = null)
636
    {
637
        $ret = '';
638
        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...
639
            $body = $this->body();
640
        }
641
        $ret .= str_replace('[pagebreak]', '<br><br>', $body);
642
643
        return $ret;
644
    }
645
646
    /**
647
     * @param int         $itemPageId
648
     * @param null|string $body
649
     *
650
     * @return string
651
     */
652
    public function buildMainText($itemPageId = -1, $body = null)
653
    {
654
        if (null === $body) {
655
            $body = $this->body();
656
        }
657
        $bodyParts = explode('[pagebreak]', $body);
658
        $this->setVar('pagescount', count($bodyParts));
659
        if (count($bodyParts) <= 1) {
660
            return $this->plainMaintext($body);
661
        }
662
        $ret = '';
663
        if ($itemPageId == -1) {
664
            $ret .= trim($bodyParts[0]);
665
666
            return $ret;
667
        }
668
        if ($itemPageId >= count($bodyParts)) {
669
            $itemPageId = count($bodyParts) - 1;
670
        }
671
        $ret .= trim($bodyParts[$itemPageId]);
672
673
        return $ret;
674
    }
675
676
    /**
677
     * @return mixed
678
     */
679
    public function getImages()
680
    {
681
        static $ret;
682
        $itemid = $this->getVar('itemid');
683
        if (!isset($ret[$itemid])) {
684
            $ret[$itemid]['main']   = '';
685
            $ret[$itemid]['others'] = [];
686
            $imagesIds              = [];
687
            $image                  = $this->getVar('image');
688
            $images                 = $this->getVar('images');
689
            if ('' != $images) {
690
                $imagesIds = explode('|', $images);
691
            }
692
            if ($image > 0) {
693
                $imagesIds = array_merge($imagesIds, [$image]);
694
            }
695
            $imageObjs = [];
696
            if (count($imagesIds) > 0) {
697
                $imageHandler = xoops_getHandler('image');
698
                $criteria     = new CriteriaCompo(new Criteria('image_id', '(' . implode(',', $imagesIds) . ')', 'IN'));
699
                $imageObjs    = $imageHandler->getObjects($criteria, true);
700
                unset($criteria);
701
            }
702
            foreach ($imageObjs as $id => $imageObj) {
703
                if ($id == $image) {
704
                    $ret[$itemid]['main'] = $imageObj;
705
                } else {
706
                    $ret[$itemid]['others'][] = $imageObj;
707
                }
708
                unset($imageObj);
709
            }
710
            unset($imageObjs);
711
        }
712
713
        return $ret[$itemid];
714
    }
715
716
    /**
717
     * @param string $display
718
     * @param int    $maxCharTitle
719
     * @param int    $maxCharSummary
720
     * @param bool   $fullSummary
721
     *
722
     * @return array
723
     */
724
    public function toArraySimple($display = 'default', $maxCharTitle = 0, $maxCharSummary = 0, $fullSummary = false)
725
    {
726
        $itemPageId = -1;
727
        if (is_numeric($display)) {
728
            $itemPageId = $display;
729
            $display    = 'all';
730
        }
731
        $item['itemid']    = $this->itemid();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$item was never initialized. Although not strictly required by PHP, it is generally a good practice to add $item = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
732
        $item['uid']       = $this->uid();
733
        $item['itemurl']   = $this->getItemUrl();
734
        $item['titlelink'] = $this->getItemLink('titlelink', $maxCharTitle);
735
        $item['subtitle']  = $this->subtitle();
736
        $item['datesub']   = $this->getDatesub();
737
        $item['counter']   = $this->counter();
738
        $item['who']       = $this->getWho();
739
        $item['when']      = $this->getWhen();
740
        $item['category']  = $this->getCategoryName();
741
        $item              = $this->getMainImage($item);
742
        switch ($display) {
743
            case 'summary':
744
            case 'list':
745
                break;
746
            case 'full':
747
            case 'wfsection':
748
            case 'default':
749
                $summary = $this->getSummary($maxCharSummary);
750
                if (!$summary) {
751
                    $summary = $this->getBody($maxCharSummary);
752
                }
753
                $item['summary'] = $summary;
754
                $item            = $this->toArrayFull($item);
755
                break;
756
            case 'all':
757
                $item = $this->toArrayFull($item);
758
                $item = $this->toArrayAll($item, $itemPageId);
759
                break;
760
        }
761
        // Highlighting searched words
762
        $highlight = true;
763
        if ($highlight && Request::getString('keywords', '', 'GET')) {
764
            $myts     = MyTextSanitizer::getInstance();
765
            $keywords = $myts->htmlSpecialChars(trim(urldecode(Request::getString('keywords', '', 'GET'))));
766
            $fields   = ['title', 'maintext', 'summary'];
767
            foreach ($fields as $field) {
768
                if (isset($item[$field])) {
769
                    $item[$field] = $this->highlight($item[$field], $keywords);
770
                }
771
            }
772
        }
773
774
        return $item;
775
    }
776
777
    /**
778
     * @param array $item
779
     *
780
     * @return array
781
     */
782
    public function toArrayFull($item)
783
    {
784
        $item['title']        = $this->getTitle();
785
        $item['clean_title']  = $this->getTitle();
786
        $item['itemurl']      = $this->getItemUrl();
787
        $item['cancomment']   = $this->cancomment();
788
        $item['comments']     = $this->comments();
789
        $item['adminlink']    = $this->getAdminLinks();
790
        $item['categoryPath'] = $this->getCategoryPath($this->publisher->getConfig('format_linked_path'));
791
        $item['who_when']     = $this->getWhoAndWhen();
792
        $item['who']          = $this->getWho();
793
        $item['when']         = $this->getWhen();
794
        $item['category']     = $this->getCategoryName();
795
        $item                 = $this->getMainImage($item);
796
797
        return $item;
798
    }
799
800
    /**
801
     * @param array $item
802
     * @param int   $itemPageId
803
     *
804
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
805
     */
806
    public function toArrayAll($item, $itemPageId)
807
    {
808
        $item['maintext'] = $this->buildMainText($itemPageId, $this->getBody());
809
        $item             = $this->getOtherImages($item);
810
811
        return $item;
812
    }
813
814
    /**
815
     * @param array $item
816
     *
817
     * @return array
818
     */
819
    public function getMainImage($item = [])
0 ignored issues
show
Coding Style introduced by
getMainImage uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
820
    {
821
        $images             = $this->getImages();
822
        $item['image_path'] = '';
823
        $item['image_name'] = '';
824
        if (is_object($images['main'])) {
825
            $dimensions           = getimagesize($GLOBALS['xoops']->path('uploads/' . $images['main']->getVar('image_name')));
826
            $item['image_width']  = $dimensions[0];
827
            $item['image_height'] = $dimensions[1];
828
            $item['image_path']   = XOOPS_URL . '/uploads/' . $images['main']->getVar('image_name');
829
            // check to see if GD function exist
830 View Code Duplication
            if (!function_exists('imagecreatetruecolor')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
831
                $item['image_thumb'] = XOOPS_URL . '/uploads/' . $images['main']->getVar('image_name');
832
            } else {
833
                $item['image_thumb'] = PUBLISHER_URL . '/thumb.php?src=' . XOOPS_URL . '/uploads/' . $images['main']->getVar('image_name') . '&amp;h=180';
834
            }
835
            $item['image_name'] = $images['main']->getVar('image_nicename');
836
        }
837
838
        return $item;
839
    }
840
841
    /**
842
     * @param array $item
843
     *
844
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
845
     */
846
    public function getOtherImages($item = [])
0 ignored issues
show
Coding Style introduced by
getOtherImages uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
847
    {
848
        $images         = $this->getImages();
849
        $item['images'] = [];
850
        $i              = 0;
851
        foreach ($images['others'] as $image) {
852
            $dimensions                   = getimagesize($GLOBALS['xoops']->path('uploads/' . $image->getVar('image_name')));
853
            $item['images'][$i]['width']  = $dimensions[0];
854
            $item['images'][$i]['height'] = $dimensions[1];
855
            $item['images'][$i]['path']   = XOOPS_URL . '/uploads/' . $image->getVar('image_name');
856
            // check to see if GD function exist
857 View Code Duplication
            if (!function_exists('imagecreatetruecolor')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
858
                $item['images'][$i]['thumb'] = XOOPS_URL . '/uploads/' . $image->getVar('image_name');
859
            } else {
860
                $item['images'][$i]['thumb'] = PUBLISHER_URL . '/thumb.php?src=' . XOOPS_URL . '/uploads/' . $image->getVar('image_name') . '&amp;w=240';
861
            }
862
            $item['images'][$i]['name'] = $image->getVar('image_nicename');
863
            ++$i;
864
        }
865
866
        return $item;
867
    }
868
869
    /**
870
     * @param string       $content
871
     * @param string|array $keywords
872
     *
873
     * @return string Text
874
     */
875
    public function highlight($content, $keywords)
876
    {
877
        $color = $this->publisher->getConfig('format_highlight_color');
878
        if (0 !== strpos($color, '#')) {
879
            $color = '#' . $color;
880
        }
881
        require_once __DIR__ . '/highlighter.php';
882
        $highlighter = new PublisherHighlighter();
883
        $highlighter->setReplacementString('<span style="font-weight: bolder; background-color: ' . $color . ';">\1</span>');
884
885
        return $highlighter->highlight($content, $keywords);
886
    }
887
888
    /**
889
     *  Create metada and assign it to template
890
     */
891
    public function createMetaTags()
892
    {
893
        $publisherMetagen = new PublisherMetagen($this->getTitle(), $this->meta_keywords(), $this->meta_description(), $this->category->categoryPath);
0 ignored issues
show
Documentation introduced by
$this->category->categoryPath is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
894
        $publisherMetagen->createMetaTags();
895
    }
896
897
    /**
898
     * @param string $str
899
     *
900
     * @return string
901
     */
902
    protected function convertForJapanese($str)
0 ignored issues
show
Coding Style introduced by
convertForJapanese uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
903
    {
904
        // no action, if not flag
905
        if (!defined('_PUBLISHER_FLAG_JP_CONVERT')) {
906
            return $str;
907
        }
908
        // no action, if not Japanese
909
        if ('japanese' !== $GLOBALS['xoopsConfig']['language']) {
910
            return $str;
911
        }
912
        // presume OS Browser
913
        $agent   = Request::getString('HTTP_USER_AGENT', '', 'SERVER');
914
        $os      = '';
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $os. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
915
        $browser = '';
916
        //        if (preg_match("/Win/i", $agent)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
917
        if (false !== stripos($agent, 'Win')) {
918
            $os = 'win';
919
        }
920
        //        if (preg_match("/MSIE/i", $agent)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
921
        if (false !== stripos($agent, 'MSIE')) {
922
            $browser = 'msie';
923
        }
924
        // if msie
925
        if (('win' === $os) && ('msie' === $browser)) {
926
            // if multibyte
927
            if (function_exists('mb_convert_encoding')) {
928
                $str = mb_convert_encoding($str, 'SJIS', 'EUC-JP');
929
                $str = rawurlencode($str);
930
            }
931
        }
932
933
        return $str;
934
    }
935
936
    /**
937
     * @param string $title
938
     * @param bool   $checkperm
939
     *
940
     * @return PublisherItemForm
941
     */
942
    public function getForm($title = 'default', $checkperm = true)
0 ignored issues
show
Coding Style introduced by
getForm uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
943
    {
944
        require_once $GLOBALS['xoops']->path('modules/' . PUBLISHER_DIRNAME . '/class/form/item.php');
945
        $form = new PublisherItemForm($title, 'form', xoops_getenv('PHP_SELF'), 'post', true);
946
        $form->setCheckPermissions($checkperm);
947
        $form->createElements($this);
948
949
        return $form;
950
    }
951
952
    /**
953
     * Checks if a user has access to a selected item. if no item permissions are
954
     * set, access permission is denied. The user needs to have necessary category
955
     * permission as well.
956
     * Also, the item needs to be Published
957
     *
958
     * @return boolean : TRUE if the no errors occured
959
     */
960
    public function accessGranted()
961
    {
962
        if (PublisherUtility::userIsAdmin()) {
963
            return true;
964
        }
965
        if ($this->status() != PublisherConstants::PUBLISHER_STATUS_PUBLISHED) {
966
            return false;
967
        }
968
        // Do we have access to the parent category
969
        if ($this->publisher->getHandler('permission')->isGranted('category_read', $this->categoryid())) {
970
            return true;
971
        }
972
973
        return false;
974
    }
975
976
    /**
977
     * The name says it all
978
     */
979
    public function setVarsFromRequest()
0 ignored issues
show
Coding Style introduced by
setVarsFromRequest uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
980
    {
981
        //Required fields
982
        //        if (!empty($categoryid = Request::getInt('categoryid', 0, 'POST'))) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
983
        //            $this->setVar('categoryid', $categoryid);}
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
984
985
        $this->setVar('categoryid', Request::getInt('categoryid', 0, 'POST'));
986
        $this->setVar('title', Request::getString('title', '', 'POST'));
987
        $this->setVar('body', Request::getText('body', '', 'POST'));
988
989
        //Not required fields
990
        $this->setVar('summary', Request::getText('summary', '', 'POST'));
991
        $this->setVar('subtitle', Request::getString('subtitle', '', 'POST'));
992
        $this->setVar('item_tag', Request::getString('item_tag', '', 'POST'));
993
994
        if (false !== ($imageFeatured = Request::getString('image_featured', '', 'POST'))) {
995
            $imageItem = Request::getArray('image_item', [], 'POST');
996
            //            $imageFeatured = Request::getString('image_featured', '', 'POST');
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
997
            //Todo: get a better image class for xoops!
998
            //Image hack
999
            $imageItemIds = [];
1000
1001
            $sql    = 'SELECT image_id, image_name FROM ' . $GLOBALS['xoopsDB']->prefix('image');
1002
            $result = $GLOBALS['xoopsDB']->query($sql, 0, 0);
1003
            while (false !== ($myrow = $GLOBALS['xoopsDB']->fetchArray($result))) {
1004
                $imageName = $myrow['image_name'];
1005
                $id        = $myrow['image_id'];
1006
                if ($imageName == $imageFeatured) {
1007
                    $this->setVar('image', $id);
1008
                }
1009
                if (in_array($imageName, $imageItem)) {
1010
                    $imageItemIds[] = $id;
1011
                }
1012
            }
1013
            $this->setVar('images', implode('|', $imageItemIds));
1014
        } else {
1015
            $this->setVar('image', 0);
1016
            $this->setVar('images', '');
1017
        }
1018
1019
        if (false !== ($authorAlias = Request::getString('author_alias', '', 'POST'))) {
1020
            $this->setVar('author_alias', $authorAlias);
1021
            if ('' !== $this->getVar('author_alias')) {
1022
                $this->setVar('uid', 0);
1023
            }
1024
        }
1025
1026
        //mb TODO check on version
1027
        //check if date is set and convert it to GMT date
1028
        //        if (($datesub = Request::getString('datesub', '', 'POST'))) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1029
        if ('' !== Request::getString('datesub', '', 'POST')) {
1030
            //            if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1031
            //                $this->setVar('datesub', strtotime(Request::getArray('datesub', array(), 'POST')['date']) + Request::getArray('datesub', array(), 'POST')['time']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1032
            //            } else {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1033
            $resDate = Request::getArray('datesub', [], 'POST');
1034
            $resTime = Request::getArray('datesub', [], 'POST');
1035
            //            $this->setVar('datesub', strtotime($resDate['date']) + $resTime['time']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1036
            $localTimestamp = strtotime($resDate['date']) + $resTime['time'];
1037
1038
            // get user Timezone offset and use it to find out the Timezone, needed for PHP DataTime
1039
            $userTimeoffset = $GLOBALS['xoopsUser']->getVar('timezone_offset');
1040
            $tz             = timezone_name_from_abbr(null, $userTimeoffset * 3600);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $tz. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1041
            if (false === $tz) {
1042
                $tz = timezone_name_from_abbr(null, $userTimeoffset * 3600, false);
1043
            }
1044
1045
            $userTimezone = new DateTimeZone($tz);
1046
            $gmtTimezone  = new DateTimeZone('GMT');
1047
            $myDateTime   = new DateTime('now', $gmtTimezone);
1048
            $offset       = $userTimezone->getOffset($myDateTime);
1049
1050
            $gmtTimestamp = $localTimestamp - $offset;
1051
            $this->setVar('datesub', $gmtTimestamp);
1052
1053
            //            }
1054
        } elseif ($this->isNew()) {
1055
            $this->setVar('datesub', time());
1056
        }
1057
1058
        $this->setVar('short_url', Request::getString('item_short_url', '', 'POST'));
1059
        $this->setVar('meta_keywords', Request::getString('item_meta_keywords', '', 'POST'));
1060
        $this->setVar('meta_description', Request::getString('item_meta_description', '', 'POST'));
1061
        $this->setVar('weight', Request::getInt('weight', 0, 'POST'));
1062
1063
        if ($this->isNew()) {
1064
            $this->setVar('uid', is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->uid() : 0);
1065
            $this->setVar('cancoment', $this->publisher->getConfig('submit_allowcomments'));
1066
            $this->setVar('status', $this->publisher->getConfig('submit_status'));
1067
            $this->setVar('dohtml', $this->publisher->getConfig('submit_dohtml'));
1068
            $this->setVar('dosmiley', $this->publisher->getConfig('submit_dosmiley'));
1069
            $this->setVar('doxcode', $this->publisher->getConfig('submit_doxcode'));
1070
            $this->setVar('doimage', $this->publisher->getConfig('submit_doimage'));
1071
            $this->setVar('dobr', $this->publisher->getConfig('submit_dobr'));
1072
        } else {
1073
            $this->setVar('uid', Request::getInt('uid', 0, 'POST'));
1074
            $this->setVar('cancomment', Request::getInt('allowcomments', 1, 'POST'));
1075
            $this->setVar('status', Request::getInt('status', 1, 'POST'));
1076
            $this->setVar('dohtml', Request::getInt('dohtml', 1, 'POST'));
1077
            $this->setVar('dosmiley', Request::getInt('dosmiley', 1, 'POST'));
1078
            $this->setVar('doxcode', Request::getInt('doxcode', 1, 'POST'));
1079
            $this->setVar('doimage', Request::getInt('doimage', 1, 'POST'));
1080
            $this->setVar('dobr', Request::getInt('dolinebreak', 1, 'POST'));
1081
        }
1082
1083
        $this->setVar('notifypub', Request::getString('notify', '', 'POST'));
1084
    }
1085
}
1086
1087
/**
1088
 * Items handler class.
1089
 * This class is responsible for providing data access mechanisms to the data source
1090
 * of Q&A class objects.
1091
 *
1092
 * @author  marcan <[email protected]>
1093
 * @package Publisher
1094
 */
1095
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...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
1096
{
1097
    /**
1098
     * @var Publisher
1099
     * @access public
1100
     */
1101
    public $publisher;
1102
1103
    protected $resultCatCounts = [];
1104
1105
    /**
1106
     * @param null|XoopsDatabase $db
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $db a bit more specific; maybe use XoopsDatabase.
Loading history...
1107
     */
1108
    public function __construct(XoopsDatabase $db)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $db. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1109
    {
1110
        parent::__construct($db, 'publisher_items', 'PublisherItem', 'itemid', 'title');
1111
        $this->publisher = Publisher::getInstance();
1112
    }
1113
1114
    /**
1115
     * @param bool $isNew
1116
     *
1117
     * @return XoopsObject
1118
     */
1119
    public function create($isNew = true)
1120
    {
1121
        $obj = parent::create($isNew);
1122
        if ($isNew) {
1123
            $obj->setDefaultPermissions();
1124
        }
1125
1126
        return $obj;
1127
    }
1128
1129
    /**
1130
     * retrieve an item
1131
     *
1132
     * @param int   $id     itemid of the user
0 ignored issues
show
Documentation introduced by
Should the type for parameter $id not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1133
     *
1134
     * @param  null $fields
1135
     * @return mixed reference to the <a href='psi_element://PublisherItem'>PublisherItem</a> object, FALSE if failed
1136
     *                      object, FALSE if failed
1137
     */
1138
    public function get($id = null, $fields = null)
1139
    {
1140
        $obj = parent::get($id);
1141
        if (is_object($obj)) {
1142
            $obj->assignOtherProperties();
1143
        }
1144
1145
        return $obj;
1146
    }
1147
1148
    /**
1149
     * insert a new item in the database
1150
     *
1151
     * @param XoopsObject $item reference to the {@link PublisherItem} object
1152
     * @param bool        $force
1153
     *
1154
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
1155
     */
1156
    public function insert(XoopsObject $item, $force = false)  //insert(&$item, $force = false)
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1157
    {
1158
        if (!$item->meta_keywords() || !$item->meta_description() || !$item->short_url()) {
1159
            $publisherMetagen = new PublisherMetagen($item->getTitle(), $item->getVar('meta_keywords'), $item->getVar('summary'));
1160
            // Auto create meta tags if empty
1161
            if (!$item->meta_keywords()) {
1162
                $item->setVar('meta_keywords', $publisherMetagen->keywords);
1163
            }
1164
            if (!$item->meta_description()) {
1165
                $item->setVar('meta_description', $publisherMetagen->description);
1166
            }
1167
            // Auto create short_url if empty
1168
            if (!$item->short_url()) {
1169
                $item->setVar('short_url', substr(PublisherMetagen::generateSeoTitle($item->getVar('title', 'n'), false), 0, 254));
1170
            }
1171
        }
1172
        if (!parent::insert($item, $force)) {
1173
            return false;
1174
        }
1175 View Code Duplication
        if (xoops_isActiveModule('tag')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1176
            // Storing tags information
1177
            $tagHandler = xoops_getModuleHandler('tag', 'tag');
1178
            $tagHandler->updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), PUBLISHER_DIRNAME, 0);
1179
        }
1180
1181
        return true;
1182
    }
1183
1184
    /**
1185
     * delete an item from the database
1186
     *
1187
     * @param XoopsObject $item reference to the ITEM to delete
1188
     * @param bool        $force
1189
     *
1190
     * @return bool FALSE if failed.
1191
     */
1192
    public function delete(XoopsObject $item, $force = false)
1193
    {
1194
        // Deleting the files
1195
        if (!$this->publisher->getHandler('file')->deleteItemFiles($item)) {
1196
            $item->setErrors(_AM_PUBLISHER_FILE_DELETE_ERROR);
1197
        }
1198
        if (!parent::delete($item, $force)) {
1199
            $item->setErrors(_AM_PUBLISHER_ITEM_DELETE_ERROR);
1200
1201
            return false;
1202
        }
1203
        // Removing tags information
1204 View Code Duplication
        if (xoops_isActiveModule('tag')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1205
            $tagHandler = xoops_getModuleHandler('tag', 'tag');
1206
            $tagHandler->updateByItem('', $item->getVar('itemid'), PUBLISHER_DIRNAME, 0);
1207
        }
1208
1209
        return true;
1210
    }
1211
1212
    /**
1213
     * retrieve items from the database
1214
     *
1215
     * @param  CriteriaElement $criteria     {@link CriteriaElement} conditions to be met
1216
     * @param  bool|string     $idKey        what shall we use as array key ? none, itemid, categoryid
0 ignored issues
show
Documentation introduced by
Should the type for parameter $criteria not be null|CriteriaElement?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1217
     * @param  bool            $as_object
1218
     * @param  string          $notNullFields
1219
     * @return array           array of <a href='psi_element://PublisherItem'>PublisherItem</a> objects
0 ignored issues
show
Documentation introduced by
Should the type for parameter $notNullFields not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1220
     *                                       objects
1221
     */
1222
1223
    public function &getObjects(CriteriaElement $criteria = null, $idKey = 'none', $as_object = true, $notNullFields = null)
0 ignored issues
show
Coding Style introduced by
getObjects uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1224
    {
1225
        $limit = $start = 0;
1226
        $ret = [];
1227
        $notNullFields = (null !== $notNullFields) ?: '';
1228
1229
        $sql   = 'SELECT * FROM ' . $this->db->prefix($this->publisher->getDirname() . '_items');
1230
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
1231
            $whereClause = $criteria->renderWhere();
1232 View Code Duplication
            if ('WHERE ()' !== $whereClause) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1233
                $sql .= ' ' . $criteria->renderWhere();
1234
                if (!empty($notNullFields)) {
1235
                    $sql .= $this->notNullFieldClause($notNullFields, true);
1236
                }
1237
            } elseif (!empty($notNullFields)) {
1238
                $sql .= ' WHERE ' . $this->notNullFieldClause($notNullFields);
1239
            }
1240
            if ('' != $criteria->getSort()) {
1241
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
1242
            }
1243
            $limit = $criteria->getLimit();
1244
            $start = $criteria->getStart();
1245
        } elseif (!empty($notNullFields)) {
1246
            $sql .= $sql .= ' WHERE ' . $this->notNullFieldClause($notNullFields);
1247
        }
1248
        $result = $this->db->query($sql, $limit, $start);
1249
        if (!$result || 0 === $GLOBALS['xoopsDB']->getRowsNum($result)) {
1250
            return $ret;
1251
        }
1252
        $theObjects = [];
1253 View Code Duplication
        while (false !== ($myrow = $this->db->fetchArray($result))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1254
            $item = new PublisherItem();
1255
            $item->assignVars($myrow);
1256
            $theObjects[$myrow['itemid']] = $item;
1257
            unset($item);
1258
        }
1259
        foreach ($theObjects as $theObject) {
1260
            if ('none' === $idKey) {
1261
                $ret[] = $theObject;
1262
            } elseif ('itemid' === $idKey) {
1263
                $ret[$theObject->itemid()] = $theObject;
1264
            } else {
1265
                $ret[$theObject->getVar($idKey)][$theObject->itemid()] = $theObject;
1266
            }
1267
            unset($theObject);
1268
        }
1269
1270
        return $ret;
1271
    }
1272
1273
    /**
1274
     * count items matching a condition
1275
     *
1276
     * @param CriteriaElement $criteria {@link CriteriaElement} to match
0 ignored issues
show
Documentation introduced by
Should the type for parameter $criteria not be null|CriteriaElement?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1277
     * @param string          $notNullFields
1278
     *
1279
     * @return int count of items
1280
     */
1281
    public function getCount(CriteriaElement $criteria = null, $notNullFields = '')
1282
    {
1283
1284
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix($this->publisher->getDirname() . '_items');
1285
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
1286
            $whereClause = $criteria->renderWhere();
1287 View Code Duplication
            if ('WHERE ()' !== $whereClause) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1288
                $sql .= ' ' . $criteria->renderWhere();
1289
                if (!empty($notNullFields)) {
1290
                    $sql .= $this->notNullFieldClause($notNullFields, true);
1291
                }
1292
            } elseif (!empty($notNullFields)) {
1293
                $sql .= ' WHERE ' . $this->notNullFieldClause($notNullFields);
1294
            }
1295
        } elseif (!empty($notNullFields)) {
1296
            $sql .= ' WHERE ' . $this->notNullFieldClause($notNullFields);
1297
        }
1298
        $result = $this->db->query($sql);
1299
        if (!$result) {
1300
            return 0;
1301
        }
1302
        list($count) = $this->db->fetchRow($result);
1303
1304
        return $count;
1305
    }
1306
1307
    /**
1308
     * @param  int           $categoryid
1309
     * @param  string        $status
1310
     * @param  string        $notNullFields
1311
     * @param                $criteriaPermissions
1312
     * @return CriteriaCompo
1313
     */
1314
    private function getItemsCriteria($categoryid = -1, $status = '', $notNullFields = '', $criteriaPermissions)
1315
    {
1316
        //        global $publisherIsAdmin;
1317
        //        $ret = 0;
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1318
        //        if (!$publisherIsAdmin) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1319
        //            $criteriaPermissions = new CriteriaCompo();
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1320
        //            // Categories for which user has access
1321
        //            $categoriesGranted = $this->publisher->getHandler('permission')->getGrantedItems('category_read');
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1322
        //            if (!empty($categoriesGranted)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1323
        //                $grantedCategories = new Criteria('categoryid', "(" . implode(',', $categoriesGranted) . ")", 'IN');
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1324
        //                $criteriaPermissions->add($grantedCategories, 'AND');
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1325
        //            } else {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1326
        //                return $ret;
1327
        //            }
1328
        //        }
1329
        if (isset($categoryid) && $categoryid != -1) {
1330
            $criteriaCategory = new criteria('categoryid', $categoryid);
1331
        }
1332
        $criteriaStatus = new CriteriaCompo();
1333
        if (!empty($status) && is_array($status)) {
1334
            foreach ($status as $v) {
1335
                $criteriaStatus->add(new Criteria('status', $v), 'OR');
1336
            }
1337
        } elseif (!empty($status) && $status != -1) {
1338
            $criteriaStatus->add(new Criteria('status', $status), 'OR');
1339
        }
1340
        $criteria = new CriteriaCompo();
1341
        if (!empty($criteriaCategory)) {
1342
            $criteria->add($criteriaCategory);
1343
        }
1344
        if (!empty($criteriaPermissions)) {
1345
            $criteria->add($criteriaPermissions);
1346
        }
1347
        if (!empty($criteriaStatus)) {
1348
            $criteria->add($criteriaStatus);
1349
        }
1350
1351
        return $criteria;
1352
    }
1353
1354
    /**
1355
     * @param        $categoryid
1356
     * @param string $status
1357
     * @param string $notNullFields
1358
     *
1359
     * @return int
1360
     */
1361
    public function getItemsCount($categoryid = -1, $status = '', $notNullFields = '')
0 ignored issues
show
Coding Style introduced by
getItemsCount uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1362
    {
1363
1364
        //        global $publisherIsAdmin;
1365
        $criteriaPermissions = '';
1366 View Code Duplication
        if (!$GLOBALS['publisherIsAdmin']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1367
            $criteriaPermissions = new CriteriaCompo();
1368
            // Categories for which user has access
1369
            $categoriesGranted = $this->publisher->getHandler('permission')->getGrantedItems('category_read');
1370
            if (!empty($categoriesGranted)) {
1371
                $grantedCategories = new Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
1372
                $criteriaPermissions->add($grantedCategories, 'AND');
1373
            } else {
1374
                return 0;
1375
            }
1376
        }
1377
        //        $ret = array();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1378
        $criteria = $this->getItemsCriteria($categoryid, $status, $notNullFields, $criteriaPermissions);
1379
        /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1380
                if (isset($categoryid) && $categoryid != -1) {
1381
                    $criteriaCategory = new criteria('categoryid', $categoryid);
1382
                }
1383
                $criteriaStatus = new CriteriaCompo();
1384
                if (!empty($status) && is_array($status)) {
1385
                    foreach ($status as $v) {
1386
                        $criteriaStatus->add(new Criteria('status', $v), 'OR');
1387
                    }
1388
                } elseif (!empty($status) && $status != -1) {
1389
                    $criteriaStatus->add(new Criteria('status', $status), 'OR');
1390
                }
1391
                $criteria = new CriteriaCompo();
1392
                if (!empty($criteriaCategory)) {
1393
                    $criteria->add($criteriaCategory);
1394
                }
1395
                if (!empty($criteriaPermissions)) {
1396
                    $criteria->add($criteriaPermissions);
1397
                }
1398
                if (!empty($criteriaStatus)) {
1399
                    $criteria->add($criteriaStatus);
1400
                }
1401
        */
1402
        $ret = $this->getCount($criteria, $notNullFields);
1403
1404
        return $ret;
1405
    }
1406
1407
    /**
1408
     * @param int    $limit
1409
     * @param int    $start
1410
     * @param int    $categoryid
1411
     * @param string $sort
1412
     * @param string $order
1413
     * @param string $notNullFields
1414
     * @param bool   $asObject
1415
     * @param string $idKey
1416
     *
1417
     * @return array
1418
     */
1419
    public function getAllPublished($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
1420
    {
1421
        $otherCriteria = new Criteria('datesub', time(), '<=');
1422
1423
        return $this->getItems($limit, $start, [PublisherConstants::PUBLISHER_STATUS_PUBLISHED], $categoryid, $sort, $order, $notNullFields, $asObject, $otherCriteria, $idKey);
1424
    }
1425
1426
    /**
1427
     * @param PublisherItem $obj
1428
     *
1429
     * @return bool
1430
     */
1431
    public function getPreviousPublished($obj)
1432
    {
1433
        $ret           = false;
1434
        $otherCriteria = new CriteriaCompo();
1435
        $otherCriteria->add(new Criteria('datesub', $obj->getVar('datesub'), '<'));
1436
        $objs = $this->getItems(1, 0, [PublisherConstants::PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'DESC', '', true, $otherCriteria, 'none');
1437
        if (count($objs) > 0) {
1438
            $ret = $objs[0];
1439
        }
1440
1441
        return $ret;
1442
    }
1443
1444
    /**
1445
     * @param PublisherItem $obj
1446
     *
1447
     * @return bool
1448
     */
1449
    public function getNextPublished($obj)
1450
    {
1451
        $ret           = false;
1452
        $otherCriteria = new CriteriaCompo();
1453
        $otherCriteria->add(new Criteria('datesub', $obj->getVar('datesub'), '>'));
1454
        $otherCriteria->add(new Criteria('datesub', time(), '<='));
1455
        $objs = $this->getItems(1, 0, [PublisherConstants::PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'ASC', '', true, $otherCriteria, 'none');
1456
        if (count($objs) > 0) {
1457
            $ret = $objs[0];
1458
        }
1459
1460
        return $ret;
1461
    }
1462
1463
    /**
1464
     * @param int    $limit
1465
     * @param int    $start
1466
     * @param int    $categoryid
1467
     * @param string $sort
1468
     * @param string $order
1469
     * @param string $notNullFields
1470
     * @param bool   $asObject
1471
     * @param string $idKey
1472
     *
1473
     * @return array
1474
     */
1475
    public function getAllSubmitted($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
1476
    {
1477
        return $this->getItems($limit, $start, [PublisherConstants::PUBLISHER_STATUS_SUBMITTED], $categoryid, $sort, $order, $notNullFields, $asObject, null, $idKey);
1478
    }
1479
1480
    /**
1481
     * @param int    $limit
1482
     * @param int    $start
1483
     * @param int    $categoryid
1484
     * @param string $sort
1485
     * @param string $order
1486
     * @param string $notNullFields
1487
     * @param bool   $asObject
1488
     * @param string $idKey
1489
     *
1490
     * @return array
1491
     */
1492
    public function getAllOffline($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
1493
    {
1494
        return $this->getItems($limit, $start, [PublisherConstants::PUBLISHER_STATUS_OFFLINE], $categoryid, $sort, $order, $notNullFields, $asObject, null, $idKey);
1495
    }
1496
1497
    /**
1498
     * @param int    $limit
1499
     * @param int    $start
1500
     * @param int    $categoryid
1501
     * @param string $sort
1502
     * @param string $order
1503
     * @param string $notNullFields
1504
     * @param bool   $asObject
1505
     * @param string $idKey
1506
     *
1507
     * @return array
1508
     */
1509
    public function getAllRejected($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $idKey = 'none')
1510
    {
1511
        return $this->getItems($limit, $start, [PublisherConstants::PUBLISHER_STATUS_REJECTED], $categoryid, $sort, $order, $notNullFields, $asObject, null, $idKey);
1512
    }
1513
1514
    /**
1515
     * @param  int    $limit
1516
     * @param  int    $start
1517
     * @param  string $status
1518
     * @param  int    $categoryid
1519
     * @param  string $sort
1520
     * @param  string $order
1521
     * @param  string $notNullFields
1522
     * @param  bool   $asObject
1523
     * @param  null   $otherCriteria
1524
     * @param  string $idKey
1525
     * @return array
1526
     * @internal param bool $asObject
1527
     */
1528
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asObject = true, $otherCriteria = null, $idKey = 'none')
0 ignored issues
show
Coding Style introduced by
getItems uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1529
    {
1530
        //        global $publisherIsAdmin;
1531
        $criteriaPermissions = '';
1532 View Code Duplication
        if (!$GLOBALS['publisherIsAdmin']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1533
            $criteriaPermissions = new CriteriaCompo();
1534
            // Categories for which user has access
1535
            $categoriesGranted = $this->publisher->getHandler('permission')->getGrantedItems('category_read');
1536
            if (!empty($categoriesGranted)) {
1537
                $grantedCategories = new Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
1538
                $criteriaPermissions->add($grantedCategories, 'AND');
1539
            } else {
1540
                return [];
1541
            }
1542
        }
1543
1544
        $criteria = $this->getItemsCriteria($categoryid, $status, $notNullFields, $criteriaPermissions);
1545
        /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1546
                if (isset($categoryid) && $categoryid != -1) {
1547
                    $criteriaCategory = new criteria('categoryid', $categoryid);
1548
                }
1549
                $criteriaStatus = new CriteriaCompo();
1550
                if (!empty($status) && is_array($status)) {
1551
                    foreach ($status as $v) {
1552
                        $criteriaStatus->add(new Criteria('status', $v), 'OR');
1553
                    }
1554
                } elseif (!empty($status) && $status != -1) {
1555
                    $criteriaStatus->add(new Criteria('status', $status), 'OR');
1556
                }
1557
                $criteria = new CriteriaCompo();
1558
                if (!empty($criteriaCategory)) {
1559
                    $criteria->add($criteriaCategory);
1560
                }
1561
                if (!empty($criteriaPermissions)) {
1562
                    $criteria->add($criteriaPermissions);
1563
                }
1564
                if (!empty($criteriaStatus)) {
1565
                    $criteria->add($criteriaStatus);
1566
                }
1567
        */
1568
        //        $ret = array();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1569
1570
        if (!empty($otherCriteria)) {
1571
            $criteria->add($otherCriteria);
1572
        }
1573
        $criteria->setLimit($limit);
1574
        $criteria->setStart($start);
1575
        $criteria->setSort($sort);
1576
        $criteria->setOrder($order);
1577
        $ret = $this->getObjects($criteria, $idKey, $notNullFields);
1578
1579
        return $ret;
1580
    }
1581
1582
    /**
1583
     * @param string $field
1584
     * @param string $status
1585
     * @param int    $categoryId
1586
     *
1587
     * @return bool
1588
     */
1589
    public function getRandomItem($field = '', $status = '', $categoryId = -1)
1590
    {
1591
        $ret           = false;
1592
        $notNullFields = $field;
1593
        // Getting the number of published Items
1594
        $totalItems = $this->getItemsCount($categoryId, $status, $notNullFields);
1595
        if ($totalItems > 0) {
1596
            --$totalItems;
1597
            mt_srand((double)microtime() * 1000000);
1598
            $entryNumber = mt_rand(0, $totalItems);
1599
            $item        = $this->getItems(1, $entryNumber, $status, $categoryId, $sort = 'datesub', $order = 'DESC', $notNullFields);
1600
            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...
1601
                $ret = $item[0];
1602
            }
1603
        }
1604
1605
        return $ret;
1606
    }
1607
1608
    /**
1609
     * delete Items matching a set of conditions
1610
     *
1611
     * @param CriteriaElement $criteria {@link CriteriaElement}
0 ignored issues
show
Documentation introduced by
Should the type for parameter $criteria not be null|CriteriaElement?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1612
     *
1613
     * @param  bool           $force
1614
     * @param  bool           $asObject
1615
     * @return bool FALSE if deletion failed
1616
     */
1617 View Code Duplication
    public function deleteAll(CriteriaElement $criteria = null, $force = true, $asObject = false) //deleteAll($criteria = null)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1618
    {
1619
        //todo resource consuming, use get list instead?
1620
        $items = $this->getObjects($criteria);
1621
        foreach ($items as $item) {
1622
            $this->delete($item);
1623
        }
1624
1625
        return true;
1626
    }
1627
1628
    /**
1629
     * @param $itemid
1630
     *
1631
     * @return bool
1632
     */
1633
    public function updateCounter($itemid)
1634
    {
1635
1636
        $sql = 'UPDATE ' . $this->db->prefix($this->publisher->getDirname() . '_items') . ' SET counter=counter+1 WHERE itemid = ' . $itemid;
1637
        if ($this->db->queryF($sql)) {
1638
            return true;
1639
        } else {
1640
            return false;
1641
        }
1642
    }
1643
1644
    /**
1645
     * @param string|array $notNullFields
1646
     * @param bool         $withAnd
1647
     *
1648
     * @return string
1649
     */
1650
    public function notNullFieldClause($notNullFields = '', $withAnd = false)
1651
    {
1652
        $ret = '';
1653
        if ($withAnd) {
1654
            $ret .= ' AND ';
1655
        }
1656
        if (!empty($notNullFields) && is_array($notNullFields)) {
1657
            foreach ($notNullFields as $v) {
1658
                $ret .= " ($v IS NOT NULL AND $v <> ' ' )";
1659
            }
1660
        } elseif (!empty($notNullFields)) {
1661
            $ret .= " ($notNullFields IS NOT NULL AND $notNullFields <> ' ' )";
1662
        }
1663
1664
        return $ret;
1665
    }
1666
1667
    /**
1668
     * @param array        $queryArray
1669
     * @param string       $andor
1670
     * @param int          $limit
1671
     * @param int          $offset
1672
     * @param int          $userid
1673
     * @param array        $categories
1674
     * @param int          $sortby
1675
     * @param string|array $searchin
1676
     * @param string       $extra
1677
     *
1678
     * @return array
1679
     */
1680
    public function getItemsFromSearch($queryArray = [], $andor = 'AND', $limit = 0, $offset = 0, $userid = 0, $categories = [], $sortby = 0, $searchin = '', $extra = '')
0 ignored issues
show
Coding Style introduced by
getItemsFromSearch uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1681
    {
1682
        //        global $publisherIsAdmin;
1683
        $ret = [];
1684
        /* @var  $gpermHandler XoopsGroupPermHandler */
1685
        $gpermHandler = xoops_getHandler('groupperm');
1686
        $groups       = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getGroups() : XOOPS_GROUP_ANONYMOUS;
1687
        $searchin     = empty($searchin) ? ['title', 'body', 'summary'] : (is_array($searchin) ? $searchin : [$searchin]);
1688
        if (in_array('all', $searchin) || 0 == count($searchin)) {
1689
            $searchin = ['title', 'subtitle', 'body', 'summary', 'meta_keywords'];
1690
        }
1691
        if (is_array($userid) && count($userid) > 0) {
1692
            $userid       = array_map('intval', $userid);
1693
            $criteriaUser = new CriteriaCompo();
1694
            $criteriaUser->add(new Criteria('uid', '(' . implode(',', $userid) . ')', 'IN'), 'OR');
1695
        } elseif (is_numeric($userid) && $userid > 0) {
1696
            $criteriaUser = new CriteriaCompo();
1697
            $criteriaUser->add(new Criteria('uid', $userid), 'OR');
1698
        }
1699
        $count = count($queryArray);
1700
        if (is_array($queryArray) && $count > 0) {
1701
            $criteriaKeywords = new CriteriaCompo();
1702
            $elementCount     = count($queryArray);
1703
            for ($i = 0; $i < $elementCount; ++$i) {
1704
                $criteriaKeyword = new CriteriaCompo();
1705 View Code Duplication
                if (in_array('title', $searchin)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1706
                    $criteriaKeyword->add(new Criteria('title', '%' . $queryArray[$i] . '%', 'LIKE'), 'OR');
1707
                }
1708 View Code Duplication
                if (in_array('subtitle', $searchin)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1709
                    $criteriaKeyword->add(new Criteria('subtitle', '%' . $queryArray[$i] . '%', 'LIKE'), 'OR');
1710
                }
1711 View Code Duplication
                if (in_array('body', $searchin)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1712
                    $criteriaKeyword->add(new Criteria('body', '%' . $queryArray[$i] . '%', 'LIKE'), 'OR');
1713
                }
1714 View Code Duplication
                if (in_array('summary', $searchin)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1715
                    $criteriaKeyword->add(new Criteria('summary', '%' . $queryArray[$i] . '%', 'LIKE'), 'OR');
1716
                }
1717 View Code Duplication
                if (in_array('meta_keywords', $searchin)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1718
                    $criteriaKeyword->add(new Criteria('meta_keywords', '%' . $queryArray[$i] . '%', 'LIKE'), 'OR');
1719
                }
1720
                $criteriaKeywords->add($criteriaKeyword, $andor);
1721
                unset($criteriaKeyword);
1722
            }
1723
        }
1724
        if (!$GLOBALS['publisherIsAdmin'] && (count($categories) > 0)) {
1725
            $criteriaPermissions = new CriteriaCompo();
1726
            // Categories for which user has access
1727
            $categoriesGranted = $gpermHandler->getItemIds('category_read', $groups, $this->publisher->getModule()->getVar('mid'));
1728
            if (count($categories) > 0) {
1729
                $categoriesGranted = array_intersect($categoriesGranted, $categories);
1730
            }
1731
            if (0 == count($categoriesGranted)) {
1732
                return $ret;
1733
            }
1734
            $grantedCategories = new Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
1735
            $criteriaPermissions->add($grantedCategories, 'AND');
1736
        } elseif (count($categories) > 0) {
1737
            $criteriaPermissions = new CriteriaCompo();
1738
            $grantedCategories   = new Criteria('categoryid', '(' . implode(',', $categories) . ')', 'IN');
1739
            $criteriaPermissions->add($grantedCategories, 'AND');
1740
        }
1741
        $criteriaItemsStatus = new CriteriaCompo();
1742
        $criteriaItemsStatus->add(new Criteria('status', PublisherConstants::PUBLISHER_STATUS_PUBLISHED));
1743
        $criteria = new CriteriaCompo();
1744
        if (!empty($criteriaUser)) {
1745
            $criteria->add($criteriaUser, 'AND');
1746
        }
1747
        if (!empty($criteriaKeywords)) {
1748
            $criteria->add($criteriaKeywords, 'AND');
1749
        }
1750
        if (!empty($criteriaPermissions)) {
1751
            $criteria->add($criteriaPermissions);
1752
        }
1753
        if (!empty($criteriaItemsStatus)) {
1754
            $criteria->add($criteriaItemsStatus, 'AND');
1755
        }
1756
        $criteria->setLimit($limit);
1757
        $criteria->setStart($offset);
1758
        if (empty($sortby)) {
1759
            $sortby = 'datesub';
1760
        }
1761
        $criteria->setSort($sortby);
1762
        $order = 'ASC';
1763
        if ('datesub' === $sortby) {
1764
            $order = 'DESC';
1765
        }
1766
        $criteria->setOrder($order);
1767
        $ret = $this->getObjects($criteria);
1768
1769
        return $ret;
1770
    }
1771
1772
    /**
1773
     * @param array $categoriesObj
1774
     * @param array $status
1775
     *
1776
     * @return array
1777
     */
1778
    public function getLastPublishedByCat($categoriesObj, $status = [PublisherConstants::PUBLISHER_STATUS_PUBLISHED])
1779
    {
1780
1781
        $ret    = [];
1782
        $catIds = [];
1783
        foreach ($categoriesObj as $parentid) {
1784
            foreach ($parentid as $category) {
1785
                $catId          = $category->getVar('categoryid');
1786
                $catIds[$catId] = $catId;
1787
            }
1788
        }
1789
        if (empty($catIds)) {
1790
            return $ret;
1791
        }
1792
        /*$cat = array();
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1793
1794
        $sql = "SELECT categoryid, MAX(datesub) as date FROM " . $this->db->prefix($this->publisher->getDirname() . '_items') . " WHERE status IN (" . implode(',', $status) . ") GROUP BY categoryid";
1795
        $result = $this->db->query($sql);
1796
        while ($row = $this->db->fetchArray($result)) {
1797
            $cat[$row['categoryid']] = $row['date'];
1798
        }
1799
        if (count($cat) == 0) return $ret;
1800
        $sql = "SELECT categoryid, itemid, title, short_url, uid, datesub FROM " . $this->db->prefix($this->publisher->getDirname() . '_items');
1801
        $criteriaBig = new CriteriaCompo();
1802
        foreach ($cat as $id => $date) {
1803
            $criteria = new CriteriaCompo(new Criteria('categoryid', $id));
1804
            $criteria->add(new Criteria('datesub', $date));
1805
            $criteriaBig->add($criteria, 'OR');
1806
            unset($criteria);
1807
        }
1808
        $sql .= " " . $criteriaBig->renderWhere();
1809
        $result = $this->db->query($sql);
1810
        while ($row = $this->db->fetchArray($result)) {
1811
            $item = new PublisherItem();
1812
            $item->assignVars($row);
1813
            $ret[$row['categoryid']] = $item;
1814
            unset($item);
1815
        }
1816
        */
1817
        $sql    = 'SELECT mi.categoryid, mi.itemid, mi.title, mi.short_url, mi.uid, mi.datesub';
1818
        $sql    .= ' FROM (SELECT categoryid, MAX(datesub) AS date FROM ' . $this->db->prefix($this->publisher->getDirname() . '_items');
1819
        $sql    .= ' WHERE status IN (' . implode(',', $status) . ')';
1820
        $sql    .= ' AND categoryid IN (' . implode(',', $catIds) . ')';
1821
        $sql    .= ' GROUP BY categoryid)mo';
1822
        $sql    .= ' JOIN ' . $this->db->prefix($this->publisher->getDirname() . '_items') . ' mi ON mi.datesub = mo.date';
1823
        $result = $this->db->query($sql);
1824 View Code Duplication
        while (false !== ($row = $this->db->fetchArray($result))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1825
            $item = new PublisherItem();
1826
            $item->assignVars($row);
1827
            $ret[$row['categoryid']] = $item;
1828
            unset($item);
1829
        }
1830
1831
        return $ret;
1832
    }
1833
1834
    /**
1835
     * @param         $parentid
1836
     * @param         $catsCount
1837
     * @param  string $spaces
1838
     * @return int
1839
     */
1840
    public function countArticlesByCat($parentid, $catsCount, $spaces = '')
1841
    {
1842
        //        global $resultCatCounts;
1843
        $newspaces = $spaces . '--';
1844
        $thecount  = 0;
1845
        foreach ($catsCount[$parentid] as $subCatId => $count) {
1846
            $thecount                         += $count;
1847
            $this->resultCatCounts[$subCatId] = $count;
1848
            if (isset($catsCount[$subCatId])) {
1849
                $thecount                         += $this->countArticlesByCat($subCatId, $catsCount, $newspaces);
1850
                $this->resultCatCounts[$subCatId] = $thecount;
1851
            }
1852
        }
1853
1854
        return $thecount;
1855
    }
1856
1857
    /**
1858
     * @param int   $catId
1859
     * @param array $status
1860
     * @param bool  $inSubCat
1861
     *
1862
     * @return array
1863
     */
1864
    public function getCountsByCat($catId = 0, $status, $inSubCat = false)
1865
    {
1866
        //        global $resultCatCounts;
1867
1868
        $ret       = [];
1869
        $catsCount = [];
1870
        $sql       = 'SELECT c.parentid, i.categoryid, COUNT(*) AS count FROM ' . $this->db->prefix($this->publisher->getDirname() . '_items') . ' AS i INNER JOIN ' . $this->db->prefix($this->publisher->getDirname() . '_categories') . ' AS c ON i.categoryid=c.categoryid';
1871
        if ((int)$catId > 0) {
1872
            $sql .= ' WHERE i.categoryid = ' . (int)$catId;
1873
            $sql .= ' AND i.status IN (' . implode(',', $status) . ')';
1874
        } else {
1875
            $sql .= ' WHERE i.status IN (' . implode(',', $status) . ')';
1876
        }
1877
        $sql    .= ' GROUP BY i.categoryid ORDER BY c.parentid ASC, i.categoryid ASC';
1878
        $result = $this->db->query($sql);
1879
        if (!$result) {
1880
            return $ret;
1881
        }
1882
        if (!$inSubCat) {
1883 View Code Duplication
            while (false !== ($row = $this->db->fetchArray($result))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1884
                $catsCount[$row['categoryid']] = $row['count'];
1885
            }
1886
1887
            return $catsCount;
1888
        }
1889
        //        while ($row = $this->db->fetchArray($result)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1890 View Code Duplication
        while (false !== ($row = $this->db->fetchArray($result))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1891
            $catsCount[$row['parentid']][$row['categoryid']] = $row['count'];
1892
        }
1893
        //        $resultCatCounts = array();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1894
        foreach ($catsCount[0] as $subCatId => $count) {
1895
            $this->resultCatCounts[$subCatId] = $count;
1896
            if (isset($catsCount[$subCatId])) {
1897
                $this->resultCatCounts[$subCatId] += $this->countArticlesByCat($subCatId, $catsCount, '');
1898
            }
1899
        }
1900
1901
        return $this->resultCatCounts;
1902
    }
1903
}
1904