Completed
Push — master ( 59d8d3...c14d6b )
by Michael
14:50
created

PublisherItemHandler   D

Complexity

Total Complexity 133

Size/Duplication

Total Lines 734
Duplicated Lines 12.53 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 2
Bugs 0 Features 1
Metric Value
dl 92
loc 734
rs 4
c 2
b 0
f 1
wmc 133
lcom 1
cbo 6

23 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 9 2
C getObjects() 14 47 14
C getCount() 8 24 8
B NotNullFieldClause() 0 16 6
B getLastPublishedByCat() 6 54 5
C getCountsByCat() 6 37 8
F getItemsFromSearch() 20 90 29
A __construct() 0 5 1
A get() 0 9 2
D insert() 5 27 9
A delete() 4 19 4
C getItemsCount() 14 38 13
A getAllPublished() 0 6 1
A getPreviousPublished() 0 12 2
A getNextPublished() 0 13 2
A getAllSubmitted() 0 4 1
A getAllOffline() 0 4 1
A getAllRejected() 0 4 1
D getItems() 15 47 14
A getRandomItem() 0 18 3
A deleteAll() 0 10 2
A updateCounter() 0 9 2
A countArticlesByCat() 0 16 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like PublisherItemHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PublisherItemHandler, and based on these observations, apply Extract Interface, too.

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 26 and the first side effect is on line 20.

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
 * @copyright           The XUUPS Project http://sourceforge.net/projects/xuups/
13
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
14
 * @license             GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
15
 * @package             Publisher
16
 * @since               1.0
17
 * @author              trabis <[email protected]>
18
 * @author              The SmartFactory <www.smartfactory.ca>
19
 */
20
defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
21
include_once dirname(__DIR__) . '/include/common.php';
22
23
/**
24
 * Class PublisherItem
25
 */
26
class PublisherItem extends XoopsObject
27
{
28
    /**
29
     * @var PublisherPublisher
30
     * @access public
31
     */
32
    public $publisher;
33
34
    /**
35
     * @var PublisherCategory
36
     * @access public
37
     */
38
    public $_category;
39
40
    /**
41
     * @param int|null $id
42
     */
43
    public function __construct($id = null)
44
    {
45
        $this->publisher = PublisherPublisher::getInstance();
46
        $this->db        = XoopsDatabaseFactory::getDatabaseConnection();
0 ignored issues
show
Bug introduced by
The property db does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
47
        $this->initVar('itemid', XOBJ_DTYPE_INT, 0);
48
        $this->initVar('categoryid', XOBJ_DTYPE_INT, 0, false);
49
        $this->initVar('title', XOBJ_DTYPE_TXTBOX, '', true, 255);
50
        $this->initVar('subtitle', XOBJ_DTYPE_TXTBOX, '', false, 255);
51
        $this->initVar('summary', XOBJ_DTYPE_TXTAREA, '', false);
52
        $this->initVar('body', XOBJ_DTYPE_TXTAREA, '', false);
53
        $this->initVar('uid', XOBJ_DTYPE_INT, 0, false);
54
        $this->initVar('author_alias', XOBJ_DTYPE_TXTBOX, '', false, 255);
55
        $this->initVar('datesub', XOBJ_DTYPE_INT, '', false);
56
        $this->initVar('status', XOBJ_DTYPE_INT, -1, false);
57
        $this->initVar('image', XOBJ_DTYPE_INT, 0, false);
58
        $this->initVar('images', XOBJ_DTYPE_TXTBOX, '', false, 255);
59
        $this->initVar('counter', XOBJ_DTYPE_INT, 0, false);
60
        $this->initVar('rating', XOBJ_DTYPE_OTHER, 0, false);
61
        $this->initVar('votes', XOBJ_DTYPE_INT, 0, false);
62
        $this->initVar('weight', XOBJ_DTYPE_INT, 0, false);
63
        $this->initVar('dohtml', XOBJ_DTYPE_INT, 1, true);
64
        $this->initVar('dosmiley', XOBJ_DTYPE_INT, 1, true);
65
        $this->initVar('doimage', XOBJ_DTYPE_INT, 1, true);
66
        $this->initVar('dobr', XOBJ_DTYPE_INT, 1, false);
67
        $this->initVar('doxcode', XOBJ_DTYPE_INT, 1, true);
68
        $this->initVar('cancomment', XOBJ_DTYPE_INT, 1, true);
69
        $this->initVar('comments', XOBJ_DTYPE_INT, 0, false);
70
        $this->initVar('notifypub', XOBJ_DTYPE_INT, 1, false);
71
        $this->initVar('meta_keywords', XOBJ_DTYPE_TXTAREA, '', false);
72
        $this->initVar('meta_description', XOBJ_DTYPE_TXTAREA, '', false);
73
        $this->initVar('short_url', XOBJ_DTYPE_TXTBOX, '', false, 255);
74
        $this->initVar('item_tag', XOBJ_DTYPE_TXTAREA, '', false);
75
        // Non consistent values
76
        $this->initVar('pagescount', XOBJ_DTYPE_INT, 0, false);
77
        if (isset($id)) {
78
            $item = $this->publisher->getHandler('item')->get($id);
79
            foreach ($item->vars as $k => $v) {
80
                $this->assignVar($k, $v['value']);
81
            }
82
        }
83
    }
84
85
    /**
86
     * @param string $method
87
     * @param array  $args
88
     *
89
     * @return mixed
90
     */
91
    public function __call($method, $args)
92
    {
93
        $arg = isset($args[0]) ? $args[0] : null;
94
95
        return $this->getVar($method, $arg);
96
    }
97
98
    /**
99
     * @return null|PublisherCategory
100
     */
101
    public function category()
102
    {
103
        if (!isset($this->_category)) {
104
            $this->_category = $this->publisher->getHandler('category')->get($this->getVar('categoryid'));
105
        }
106
107
        return $this->_category;
108
    }
109
110
    /**
111
     * @param int    $maxLength
112
     * @param string $format
113
     *
114
     * @return mixed|string
115
     */
116 View Code Duplication
    public function title($maxLength = 0, $format = 'S')
117
    {
118
        $ret = $this->getVar('title', $format);
119
        if ($maxLength != 0) {
120
            if (!XOOPS_USE_MULTIBYTES) {
121
                if (strlen($ret) >= $maxLength) {
122
                    $ret = publisher_substr($ret, 0, $maxLength);
123
                }
124
            }
125
        }
126
127
        return $ret;
128
    }
129
130
    /**
131
     * @param int    $maxLength
132
     * @param string $format
133
     *
134
     * @return mixed|string
135
     */
136 View Code Duplication
    public function subtitle($maxLength = 0, $format = 'S')
137
    {
138
        $ret = $this->getVar('subtitle', $format);
139
        if ($maxLength != 0) {
140
            if (!XOOPS_USE_MULTIBYTES) {
141
                if (strlen($ret) >= $maxLength) {
142
                    $ret = publisher_substr($ret, 0, $maxLength);
143
                }
144
            }
145
        }
146
147
        return $ret;
148
    }
149
150
    /**
151
     * @param int    $maxLength
152
     * @param string $format
153
     * @param string $stripTags
154
     *
155
     * @return mixed|string
156
     */
157
    public function summary($maxLength = 0, $format = 'S', $stripTags = '')
158
    {
159
        $ret = $this->getVar('summary', $format);
160
        if (!empty($stripTags)) {
161
            $ret = strip_tags($ret, $stripTags);
162
        }
163 View Code Duplication
        if ($maxLength != 0) {
164
            if (!XOOPS_USE_MULTIBYTES) {
165
                if (strlen($ret) >= $maxLength) {
166
                    //$ret = publisher_substr($ret , 0, $maxLength);
167
                    $ret = publisher_truncateTagSafe($ret, $maxLength, $etc = '...', $break_words = false);
168
                }
169
            }
170
        }
171
172
        return $ret;
173
    }
174
175
    /**
176
     * @param int  $maxLength
177
     * @param bool $fullSummary
178
     *
179
     * @return mixed|string
180
     */
181
    public function getBlockSummary($maxLength = 0, $fullSummary = false)
182
    {
183
        if ($fullSummary) {
184
            $ret = $this->summary(0, 's', '></ br>');
185
        } else {
186
            $ret = $this->summary($maxLength, 's', '></ br>');
187
        }
188
        //no summary? get body!
189
        if ('' === $ret) {
190
            $ret = $this->body($maxLength, 's', '></ br>');
191
        }
192
193
        return $ret;
194
    }
195
196
    /**
197
     * @param string $file_name
198
     *
199
     * @return string
200
     */
201
    public function wrappage($file_name)
202
    {
203
        $content = '';
204
        $page    = publisher_getUploadDir(true, 'content') . $file_name;
205
        if (file_exists($page)) {
206
            // this page uses smarty template
207
            ob_start();
208
            include($page);
209
            $content = ob_get_contents();
210
            ob_end_clean();
211
            // Cleaning the content
212
            $body_start_pos = strpos($content, '<body>');
213
            if ($body_start_pos) {
214
                $body_end_pos = strpos($content, '</body>', $body_start_pos);
215
                $content      = substr($content, $body_start_pos + strlen('<body>'), $body_end_pos - strlen('<body>') - $body_start_pos);
216
            }
217
            // Check if ML Hack is installed, and if yes, parse the $content in formatForML
218
            $myts = MyTextSanitizer::getInstance();
219
            if (method_exists($myts, 'formatForML')) {
220
                $content = $myts->formatForML($content);
0 ignored issues
show
Bug introduced by
The method formatForML() does not seem to exist on object<MyTextSanitizer>.

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

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

Loading history...
221
            }
222
        }
223
224
        return $content;
225
    }
226
227
    /**
228
     * This method returns the body to be displayed. Not to be used for editing
229
     *
230
     * @param int    $maxLength
231
     * @param string $format
232
     * @param string $stripTags
233
     *
234
     * @return mixed|string
235
     */
236
    public function body($maxLength = 0, $format = 'S', $stripTags = '')
237
    {
238
        $ret      = $this->getVar('body', $format);
239
        $wrap_pos = strpos($ret, '[pagewrap=');
240
        if (!($wrap_pos === false)) {
241
            $wrap_pages       = array();
242
            $wrap_code_length = strlen('[pagewrap=');
243
            while (!($wrap_pos === false)) {
244
                $end_wrap_pos = strpos($ret, ']', $wrap_pos);
245
                if ($end_wrap_pos) {
246
                    $wrap_page_name = substr($ret, $wrap_pos + $wrap_code_length, $end_wrap_pos - $wrap_code_length - $wrap_pos);
247
                    $wrap_pages[]   = $wrap_page_name;
248
                }
249
                $wrap_pos = strpos($ret, '[pagewrap=', $end_wrap_pos - 1);
250
            }
251
            foreach ($wrap_pages as $page) {
252
                $wrap_page_content = $this->wrappage($page);
253
                $ret               = str_replace("[pagewrap={$page}]", $wrap_page_content, $ret);
254
            }
255
        }
256
        if ($this->publisher->getConfig('item_disp_blocks_summary')) {
257
            $summary = $this->summary($maxLength, $format, $stripTags);
258
            if ($summary) {
259
                $ret = $this->summary() . '' . $ret;
260
            }
261
        }
262
        if (!empty($stripTags)) {
263
            $ret = strip_tags($ret, $stripTags);
264
        }
265 View Code Duplication
        if ($maxLength != 0) {
266
            if (!XOOPS_USE_MULTIBYTES) {
267
                if (strlen($ret) >= $maxLength) {
268
                    //$ret = publisher_substr($ret , 0, $maxLength);
269
                    $ret = publisher_truncateTagSafe($ret, $maxLength, $etc = '...', $break_words = false);
270
                }
271
            }
272
        }
273
274
        return $ret;
275
    }
276
277
    /**
278
     * @param string $dateFormat
279
     * @param string $format
280
     *
281
     * @return string
282
     */
283
    public function datesub($dateFormat = '', $format = 'S')
284
    {
285
        if (empty($dateformat)) {
0 ignored issues
show
Bug introduced by
The variable $dateformat does not exist. Did you mean $dateFormat?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
286
            $dateFormat = $this->publisher->getConfig('format_date');
287
        }
288
        xoops_load('XoopsLocal');
289
290
        return XoopsLocal::formatTimestamp($this->getVar('datesub', $format), $dateFormat);
291
    }
292
293
    /**
294
     * @param int $realName
295
     *
296
     * @return string
297
     */
298
    public function posterName($realName = -1)
299
    {
300
        xoops_load('XoopsUserUtility');
301
        if ($realName == -1) {
302
            $realName = $this->publisher->getConfig('format_realname');
303
        }
304
        $ret = $this->author_alias();
0 ignored issues
show
Documentation Bug introduced by
The method author_alias does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
305
        if ($ret == '') {
306
            $ret = XoopsUserUtility::getUnameFromId($this->uid(), $realName);
0 ignored issues
show
Documentation Bug introduced by
The method uid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
307
        }
308
309
        return $ret;
310
    }
311
312
    /**
313
     * @return string
314
     */
315
    public function posterAvatar()
316
    {
317
        $ret            = 'blank.gif';
318
        $member_handler = xoops_getHandler('member');
319
        $thisUser       = $member_handler->getUser($this->uid());
0 ignored issues
show
Documentation Bug introduced by
The method uid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
320
        if (is_object($thisUser)) {
321
            $ret = $thisUser->getVar('user_avatar');
322
        }
323
324
        return $ret;
325
    }
326
327
    /**
328
     * @return string
329
     */
330
    public function linkedPosterName()
331
    {
332
        xoops_load('XoopsUserUtility');
333
        $ret = $this->author_alias();
0 ignored issues
show
Documentation Bug introduced by
The method author_alias does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
334
        if ($ret == '') {
335
            $ret = XoopsUserUtility::getUnameFromId($this->uid(), $this->publisher->getConfig('format_realname'), true);
0 ignored issues
show
Documentation Bug introduced by
The method uid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
336
        }
337
338
        return $ret;
339
    }
340
341
    /**
342
     * @return mixed
343
     */
344
    public function updateCounter()
345
    {
346
        return $this->publisher->getHandler('item')->updateCounter($this->itemid());
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
347
    }
348
349
    /**
350
     * @param bool $force
351
     *
352
     * @return bool
353
     */
354
    public function store($force = true)
355
    {
356
        $isNew = $this->isNew();
357
        if (!$this->publisher->getHandler('item')->insert($this, $force)) {
358
            return false;
359
        }
360
        if ($isNew && $this->status() == _PUBLISHER_STATUS_PUBLISHED) {
0 ignored issues
show
Documentation Bug introduced by
The method status does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
361
            // Increment user posts
362
            $user_handler   = xoops_getHandler('user');
363
            $member_handler = xoops_getHandler('member');
364
            $poster         = $user_handler->get($this->uid());
0 ignored issues
show
Documentation Bug introduced by
The method uid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
365
            if (is_object($poster) && !$poster->isNew()) {
366
                $poster->setVar('posts', $poster->getVar('posts') + 1);
367
                if (!$member_handler->insertUser($poster, true)) {
368
                    $this->setErrors('Article created but could not increment user posts.');
369
370
                    return false;
371
                }
372
            }
373
        }
374
375
        return true;
376
    }
377
378
    /**
379
     * @return string
380
     */
381
    public function getCategoryName()
382
    {
383
        return $this->category()->name();
0 ignored issues
show
Documentation Bug introduced by
The method name does not exist on object<PublisherCategory>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
384
    }
385
386
    /**
387
     * @return string
388
     */
389
    public function getCategoryUrl()
390
    {
391
        return $this->category()->getCategoryUrl();
392
    }
393
394
    /**
395
     * @return string
396
     */
397
    public function getCategoryLink()
398
    {
399
        return $this->category()->getCategoryLink();
400
    }
401
402
    /**
403
     * @param bool $withAllLink
404
     *
405
     * @return string
406
     */
407
    public function getCategoryPath($withAllLink = true)
408
    {
409
        return $this->category()->getCategoryPath($withAllLink);
410
    }
411
412
    /**
413
     * @return string
414
     */
415
    public function getCategoryImagePath()
416
    {
417
        return publisher_getImageDir('category', false) . $this->category()->image();
418
    }
419
420
    /**
421
     * @return mixed
422
     */
423
    public function getFiles()
424
    {
425
        return $this->publisher->getHandler('file')->getAllFiles($this->itemid(), _PUBLISHER_STATUS_FILE_ACTIVE);
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
426
    }
427
428
    /**
429
     * @return string
430
     */
431
    public function getAdminLinks()
432
    {
433
        global $xoopsConfig, $xoopsUser;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
434
        $adminLinks = '';
435
        if (is_object($xoopsUser) && (publisher_userIsAdmin() || publisher_userIsAuthor($this) || $this->publisher->getHandler('permission')->isGranted('item_submit', $this->categoryid()))) {
0 ignored issues
show
Documentation Bug introduced by
The method categoryid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
436
            if (publisher_userIsAdmin() || publisher_userIsAuthor($this) || publisher_userIsModerator($this)) {
437 View Code Duplication
                if ($this->publisher->getConfig('perm_edit') || publisher_userIsModerator($this) || publisher_userIsAdmin()) {
438
                    // Edit button
439
                    $adminLinks .= "<a href='" . PUBLISHER_URL . '/submit.php?itemid=' . $this->itemid() . "'><img src='" . PUBLISHER_URL . "/images/links/edit.gif'" . " title='" . _CO_PUBLISHER_EDIT . "' alt='" . _CO_PUBLISHER_EDIT . "'/></a>";
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
440
                    $adminLinks .= ' ';
441
                }
442 View Code Duplication
                if ($this->publisher->getConfig('perm_delete') || publisher_userIsModerator($this) || publisher_userIsAdmin()) {
443
                    // Delete button
444
                    $adminLinks .= "<a href='" . PUBLISHER_URL . '/submit.php?op=del&amp;itemid=' . $this->itemid() . "'><img src='" . PUBLISHER_URL . "/images/links/delete.png'" . " title='" . _CO_PUBLISHER_DELETE . "' alt='" . _CO_PUBLISHER_DELETE . "' /></a>";
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
445
                    $adminLinks .= ' ';
446
                }
447
            }
448 View Code Duplication
            if ($this->publisher->getConfig('perm_clone') || publisher_userIsModerator($this) || publisher_userIsAdmin()) {
449
                // Duplicate button
450
                $adminLinks .= "<a href='" . PUBLISHER_URL . '/submit.php?op=clone&amp;itemid=' . $this->itemid() . "'><img src='" . PUBLISHER_URL . "/images/links/clone.gif'" . " title='" . _CO_PUBLISHER_CLONE . "' alt='" . _CO_PUBLISHER_CLONE . "' /></a>";
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
451
                $adminLinks .= ' ';
452
            }
453
        }
454
        // PDF button
455
        $adminLinks .= "<a href='" . PUBLISHER_URL . '/makepdf.php?itemid=' . $this->itemid() . "' rel='nofollow' target='_blank'><img src='" . PUBLISHER_URL . "/images/links/pdf.gif' title='" . _CO_PUBLISHER_PDF . "' alt='" . _CO_PUBLISHER_PDF . "' /></a>";
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
456
        $adminLinks .= ' ';
457
        // Print button
458
        $adminLinks .= "<a href='" . publisher_seo_genUrl('print', $this->itemid(), $this->short_url()) . "' rel='nofollow' target='_blank'><img src='" . PUBLISHER_URL . "/images/links/print.gif' title='" . _CO_PUBLISHER_PRINT . "' alt='" . _CO_PUBLISHER_PRINT . "' /></a>";
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
Documentation Bug introduced by
The method short_url does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
459
        $adminLinks .= ' ';
460
        // Email button
461
        if (xoops_isActiveModule('tellafriend')) {
462
            $subject  = sprintf(_CO_PUBLISHER_INTITEMFOUND, $xoopsConfig['sitename']);
463
            $subject  = $this->_convert_for_japanese($subject);
464
            $maillink = publisher_tellafriend($subject);
465
            $adminLinks .= '<a href="' . $maillink . '"><img src="' . PUBLISHER_URL . '/images/links/friend.gif" title="' . _CO_PUBLISHER_MAIL . '" alt="' . _CO_PUBLISHER_MAIL . '" /></a>';
466
            $adminLinks .= ' ';
467
        }
468
469
        return $adminLinks;
470
    }
471
472
    /**
473
     * @param array $notifications
474
     */
475
    public function sendNotifications($notifications = array())
476
    {
477
        $notification_handler  = xoops_getHandler('notification');
478
        $tags                  = array();
479
        $tags['MODULE_NAME']   = $this->publisher->getModule()->getVar('name');
480
        $tags['ITEM_NAME']     = $this->title();
481
        $tags['ITEM_NAME']     = $this->subtitle();
482
        $tags['CATEGORY_NAME'] = $this->getCategoryName();
483
        $tags['CATEGORY_URL']  = PUBLISHER_URL . '/category.php?categoryid=' . $this->categoryid();
0 ignored issues
show
Documentation Bug introduced by
The method categoryid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
484
        $tags['ITEM_BODY']     = $this->body();
485
        $tags['DATESUB']       = $this->datesub();
486
        foreach ($notifications as $notification) {
487
            switch ($notification) {
488
                case _PUBLISHER_NOT_ITEM_PUBLISHED :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

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

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

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

Loading history...
489
                    $tags['ITEM_URL'] = PUBLISHER_URL . '/item.php?itemid=' . $this->itemid();
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
490
                    $notification_handler->triggerEvent('global_item', 0, 'published', $tags, array(), $this->publisher->getModule()->getVar('mid'));
491
                    $notification_handler->triggerEvent('category_item', $this->categoryid(), 'published', $tags, array(), $this->publisher->getModule()->getVar('mid'));
0 ignored issues
show
Documentation Bug introduced by
The method categoryid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
492
                    $notification_handler->triggerEvent('item', $this->itemid(), 'approved', $tags, array(), $this->publisher->getModule()->getVar('mid'));
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
493
                    break;
494
                case _PUBLISHER_NOT_ITEM_SUBMITTED :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

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

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

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

Loading history...
495
                    $tags['WAITINGFILES_URL'] = PUBLISHER_URL . '/admin/item.php?itemid=' . $this->itemid();
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
496
                    $notification_handler->triggerEvent('global_item', 0, 'submitted', $tags, array(), $this->publisher->getModule()->getVar('mid'));
497
                    $notification_handler->triggerEvent('category_item', $this->categoryid(), 'submitted', $tags, array(), $this->publisher->getModule()->getVar('mid'));
0 ignored issues
show
Documentation Bug introduced by
The method categoryid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
498
                    break;
499
                case _PUBLISHER_NOT_ITEM_REJECTED :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

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

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

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

Loading history...
500
                    $notification_handler->triggerEvent('item', $this->itemid(), 'rejected', $tags, array(), $this->publisher->getModule()->getVar('mid'));
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
501
                    break;
502
                case -1 :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

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

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

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

Loading history...
503
                default:
504
                    break;
505
            }
506
        }
507
    }
508
509
    /**
510
     * Sets default permissions for this item
511
     */
512 View Code Duplication
    public function setDefaultPermissions()
513
    {
514
        $member_handler = xoops_getHandler('member');
515
        $groups         = $member_handler->getGroupList();
516
        $j              = 0;
517
        $group_ids      = array();
518
        foreach (array_keys($groups) as $i) {
519
            $group_ids[$j] = $i;
520
            ++$j;
521
        }
522
        $this->_groups_read = $group_ids;
0 ignored issues
show
Bug introduced by
The property _groups_read does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
523
    }
524
525
    /**
526
     * @todo look at this
527
     *
528
     * @param $group_ids
529
     */
530 View Code Duplication
    public function setPermissions($group_ids)
531
    {
532
        if (!isset($group_ids)) {
533
            $member_handler = xoops_getHandler('member');
534
            $groups         = $member_handler->getGroupList();
535
            $j              = 0;
536
            $group_ids      = array();
537
            foreach (array_keys($groups) as $i) {
538
                $group_ids[$j] = $i;
539
                ++$j;
540
            }
541
        }
542
    }
543
544
    /**
545
     * @return bool
546
     */
547
    public function notLoaded()
548
    {
549
        return $this->getVar('itemid') == -1;
550
    }
551
552
    /**
553
     * @return string
554
     */
555
    public function getItemUrl()
556
    {
557
        return publisher_seo_genUrl('item', $this->itemid(), $this->short_url());
0 ignored issues
show
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
Documentation Bug introduced by
The method short_url does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
558
    }
559
560
    /**
561
     * @param bool $class
562
     * @param int  $maxsize
563
     *
564
     * @return string
565
     */
566
    public function getItemLink($class = false, $maxsize = 0)
567
    {
568
        if ($class) {
569
            return '<a class=' . $class . ' href="' . $this->getItemUrl() . '">' . $this->title($maxsize) . '</a>';
570
        } else {
571
            return '<a href="' . $this->getItemUrl() . '">' . $this->title($maxsize) . '</a>';
572
        }
573
    }
574
575
    /**
576
     * @return string
577
     */
578
    public function getWhoAndWhen()
579
    {
580
        $posterName = $this->linkedPosterName();
581
        $postdate   = $this->datesub();
582
583
        return sprintf(_CO_PUBLISHER_POSTEDBY, $posterName, $postdate);
584
    }
585
586
    /**
587
     * @return string
588
     */
589
    public function getWho()
590
    {
591
        $posterName = $this->linkedPosterName();
592
593
        return $posterName;
594
    }
595
596
    /**
597
     * @return string
598
     */
599
    public function getWhen()
600
    {
601
        $postdate = $this->datesub();
602
603
        return $postdate;
604
    }
605
606
    /**
607
     * @param null|string $body
608
     *
609
     * @return string
610
     */
611
    public function plain_maintext($body = null)
612
    {
613
        $ret = '';
614
        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...
615
            $body = $this->body();
616
        }
617
        $ret .= str_replace('[pagebreak]', '<br /><br />', $body);
618
619
        return $ret;
620
    }
621
622
    /**
623
     * @param int         $item_page_id
624
     * @param null|string $body
625
     *
626
     * @return string
627
     */
628
    public function buildmaintext($item_page_id = -1, $body = null)
629
    {
630
        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...
631
            $body = $this->body();
632
        }
633
        $body_parts = explode('[pagebreak]', $body);
634
        $this->setVar('pagescount', count($body_parts));
635
        if (count($body_parts) <= 1) {
636
            return $this->plain_maintext($body);
637
        }
638
        $ret = '';
639
        if ($item_page_id == -1) {
640
            $ret .= trim($body_parts[0]);
641
642
            return $ret;
643
        }
644
        if ($item_page_id >= count($body_parts)) {
645
            $item_page_id = count($body_parts) - 1;
646
        }
647
        $ret .= trim($body_parts[$item_page_id]);
648
649
        return $ret;
650
    }
651
652
    /**
653
     * @return mixed
654
     */
655
    public function getImages()
656
    {
657
        static $ret;
658
        $itemid = $this->getVar('itemid');
659
        if (!isset($ret[$itemid])) {
660
            $ret[$itemid]['main']   = '';
661
            $ret[$itemid]['others'] = array();
662
            $images_ids             = array();
663
            $image                  = $this->getVar('image');
664
            $images                 = $this->getVar('images');
665
            if ($images != '') {
666
                $images_ids = explode('|', $images);
667
            }
668
            if ($image > 0) {
669
                $images_ids = array_merge($images_ids, array($image));
670
            }
671
            $imageObjs = array();
672
            if (count($images_ids) > 0) {
673
                $image_handler = xoops_getHandler('image');
674
                $criteria      = new CriteriaCompo(new Criteria('image_id', '(' . implode(',', $images_ids) . ')', 'IN'));
675
                $imageObjs     = $image_handler->getObjects($criteria, true);
676
                unset($criteria);
677
            }
678
            foreach ($imageObjs as $id => $imageObj) {
679
                if ($id == $image) {
680
                    $ret[$itemid]['main'] = $imageObj;
681
                } else {
682
                    $ret[$itemid]['others'][] = $imageObj;
683
                }
684
                unset($imageObj);
685
            }
686
            unset($imageObjs);
687
        }
688
689
        return $ret[$itemid];
690
    }
691
692
    /**
693
     * @param string $display
694
     * @param int    $max_char_title
695
     * @param int    $max_char_summary
696
     * @param bool   $full_summary
697
     *
698
     * @return array
699
     */
700
    public function ToArraySimple($display = 'default', $max_char_title = 0, $max_char_summary = 0, $full_summary = false)
0 ignored issues
show
Unused Code introduced by
The parameter $full_summary is not used and could be removed.

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

Loading history...
701
    {
702
        $item_page_id = -1;
703
        if (is_numeric($display)) {
704
            $item_page_id = $display;
705
            $display      = 'all';
706
        }
707
        $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...
Documentation Bug introduced by
The method itemid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
708
        $item['itemurl']   = $this->getItemUrl();
709
        $item['uid']       = $this->uid();
0 ignored issues
show
Documentation Bug introduced by
The method uid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
710
        $item['titlelink'] = $this->getItemLink('titlelink', $max_char_title);
711
        $item['subtitle']  = $this->subtitle();
712
        $item['datesub']   = $this->datesub();
713
        $item['counter']   = $this->counter();
0 ignored issues
show
Bug introduced by
The method counter() does not exist on PublisherItem. Did you maybe mean updateCounter()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
714
        $item['who']       = $this->getWho();
715
        $item['when']      = $this->getWhen();
716
        $item['category']  = $this->getCategoryName();
717
        $item              = $this->getMainImage($item);
718
        switch ($display) {
719
            case 'summary':
720
            case 'list':
721
                break;
722
            case 'full':
723
            case 'wfsection':
724
            case 'default':
725
                $summary = $this->summary($max_char_summary);
726
                if (!$summary) {
727
                    $summary = $this->body($max_char_summary);
728
                }
729
                $item['summary'] = $summary;
730
                $item            = $this->toArrayFull($item);
731
                break;
732
            case 'all':
733
                $item = $this->toArrayFull($item);
734
                $item = $this->toArrayAll($item, $item_page_id);
735
                break;
736
        }
737
        // Highlighting searched words
738
        $highlight = true;
739
        if ($highlight && isset($_GET['keywords'])) {
740
            $myts     = MyTextSanitizer::getInstance();
741
            $keywords = $myts->htmlSpecialChars(trim(urldecode($_GET['keywords'])));
742
            $fields   = array('title', 'maintext', 'summary');
743
            foreach ($fields as $field) {
744
                if (isset($item[$field])) {
745
                    $item[$field] = $this->highlight($item[$field], $keywords);
746
                }
747
            }
748
        }
749
750
        return $item;
751
    }
752
753
    /**
754
     * @param array $item
755
     *
756
     * @return array
757
     */
758
    public function toArrayFull($item)
759
    {
760
        $item['title']        = $this->title();
761
        $item['clean_title']  = $this->title();
762
        $item['itemurl']      = $this->getItemUrl();
763
        $item['cancomment']   = $this->cancomment();
0 ignored issues
show
Documentation Bug introduced by
The method cancomment does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
764
        $item['comments']     = $this->comments();
0 ignored issues
show
Documentation Bug introduced by
The method comments does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
765
        $item['adminlink']    = $this->getAdminLinks();
766
        $item['categoryPath'] = $this->getCategoryPath($this->publisher->getConfig('format_linked_path'));
767
        $item['who_when']     = $this->getWhoAndWhen();
768
        $item['who']          = $this->getWho();
769
        $item['when']         = $this->getWhen();
770
        $item['category']     = $this->getCategoryName();
771
        $item                 = $this->getMainImage($item);
772
773
        return $item;
774
    }
775
776
    /**
777
     * @param array $item
778
     * @param int   $item_page_id
779
     *
780
     * @return array
781
     */
782
    public function toArrayAll($item, $item_page_id)
783
    {
784
        $item['maintext'] = $this->buildmaintext($item_page_id, $this->body());
785
        $item             = $this->getOtherImages($item);
786
787
        return $item;
788
    }
789
790
    /**
791
     * @param array $item
792
     *
793
     * @return array
794
     */
795
    public function getMainImage($item = array())
796
    {
797
        $images             = $this->getImages();
798
        $item['image_path'] = '';
799
        $item['image_name'] = '';
800
        if (is_object($images['main'])) {
801
            $dimensions           = getimagesize(XOOPS_ROOT_PATH . '/uploads/' . $images['main']->getVar('image_name'));
802
            $item['image_width']  = $dimensions[0];
803
            $item['image_height'] = $dimensions[1];
804
            $item['image_path']   = XOOPS_URL . '/uploads/' . $images['main']->getVar('image_name');
805
            // check to see if GD function exist
806 View Code Duplication
            if (!function_exists('imagecreatetruecolor')) {
807
                $item['image_thumb'] = XOOPS_URL . '/uploads/' . $images['main']->getVar('image_name');
808
            } else {
809
                $item['image_thumb'] = PUBLISHER_URL . '/thumb.php?src=' . XOOPS_URL . '/uploads/' . $images['main']->getVar('image_name') . '&amp;h=180';
810
            }
811
            $item['image_name'] = $images['main']->getVar('image_nicename');
812
        }
813
814
        return $item;
815
    }
816
817
    /**
818
     * @param array $item
819
     *
820
     * @return array
821
     */
822
    public function getOtherImages($item = array())
823
    {
824
        $images         = $this->getImages();
825
        $item['images'] = array();
826
        $i              = 0;
827
        foreach ($images['others'] as $image) {
828
            $dimensions                   = getimagesize(XOOPS_ROOT_PATH . '/uploads/' . $image->getVar('image_name'));
829
            $item['images'][$i]['width']  = $dimensions[0];
830
            $item['images'][$i]['height'] = $dimensions[1];
831
            $item['images'][$i]['path']   = XOOPS_URL . '/uploads/' . $image->getVar('image_name');
832
            // check to see if GD function exist
833 View Code Duplication
            if (!function_exists('imagecreatetruecolor')) {
834
                $item['images'][$i]['thumb'] = XOOPS_URL . '/uploads/' . $image->getVar('image_name');
835
            } else {
836
                $item['images'][$i]['thumb'] = PUBLISHER_URL . '/thumb.php?src=' . XOOPS_URL . '/uploads/' . $image->getVar('image_name') . '&amp;w=240';
837
            }
838
            $item['images'][$i]['name'] = $image->getVar('image_nicename');
839
            ++$i;
840
        }
841
842
        return $item;
843
    }
844
845
    /**
846
     * @param string       $content
847
     * @param string|array $keywords
848
     *
849
     * @return Text
850
     */
851
    public function highlight($content, $keywords)
852
    {
853
        $color = $this->publisher->getConfig('format_highlight_color');
854
        if (substr($color, 0, 1) !== '#') {
855
            $color = '#' . $color;
856
        }
857
        include_once __DIR__ . '/highlighter.php';
858
        $highlighter = new PublisherHighlighter();
859
        $highlighter->setReplacementString('<span style="font-weight: bolder; background-color: ' . $color . ';">\1</span>');
860
861
        return $highlighter->highlight($content, $keywords);
862
    }
863
864
    /**
865
     *  Create metada and assign it to template
866
     */
867
    public function createMetaTags()
868
    {
869
        $publisher_metagen = new PublisherMetagen($this->title(), $this->meta_keywords(), $this->meta_description(), $this->_category->_categoryPath);
0 ignored issues
show
Documentation Bug introduced by
The method meta_keywords does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
Documentation Bug introduced by
The method meta_description does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
870
        $publisher_metagen->createMetaTags();
871
    }
872
873
    /**
874
     * @param string $str
875
     *
876
     * @return string
877
     */
878
    public function _convert_for_japanese($str)
879
    {
880
        global $xoopsConfig;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
881
        // no action, if not flag
882
        if (!defined('_PUBLISHER_FLAG_JP_CONVERT')) {
883
            return $str;
884
        }
885
        // no action, if not Japanese
886
        if ($xoopsConfig['language'] !== 'japanese') {
887
            return $str;
888
        }
889
        // presume OS Browser
890
        $agent   = $_SERVER['HTTP_USER_AGENT'];
891
        $os      = '';
892
        $browser = '';
893
        //        if (preg_match("/Win/i", $agent)) {
894
        if (false !== stripos($agent, 'Win')) {
895
            $os = 'win';
896
        }
897
        //        if (preg_match("/MSIE/i", $agent)) {
898
        if (false !== stripos($agent, 'MSIE')) {
899
            $browser = 'msie';
900
        }
901
        // if msie
902
        if (($os === 'win') && ($browser === 'msie')) {
903
            // if multibyte
904
            if (function_exists('mb_convert_encoding')) {
905
                $str = mb_convert_encoding($str, 'SJIS', 'EUC-JP');
906
                $str = rawurlencode($str);
907
            }
908
        }
909
910
        return $str;
911
    }
912
913
    /**
914
     * @param string $title
915
     * @param bool   $checkperm
916
     *
917
     * @return PublisherItemForm
918
     */
919
    public function getForm($title = 'default', $checkperm = true)
920
    {
921
        include_once XOOPS_ROOT_PATH . '/modules/publisher/class/form/item.php';
922
        $form = new PublisherItemForm($title, 'form', xoops_getenv('PHP_SELF'));
923
        $form->setCheckPermissions($checkperm);
924
        $form->createElements($this);
925
926
        return $form;
927
    }
928
929
    /**
930
     * Checks if a user has access to a selected item. if no item permissions are
931
     * set, access permission is denied. The user needs to have necessary category
932
     * permission as well.
933
     * Also, the item needs to be Published
934
     *
935
     * @return boolean : TRUE if the no errors occured
936
     */
937
    public function accessGranted()
938
    {
939
        if (publisher_userIsAdmin()) {
940
            return true;
941
        }
942
        if ($this->status() != _PUBLISHER_STATUS_PUBLISHED) {
0 ignored issues
show
Documentation Bug introduced by
The method status does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
943
            return false;
944
        }
945
        // Do we have access to the parent category
946
        if ($this->publisher->getHandler('permission')->isGranted('category_read', $this->categoryid())) {
0 ignored issues
show
Documentation Bug introduced by
The method categoryid does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
947
            return true;
948
        }
949
950
        return false;
951
    }
952
953
    /**
954
     * The name says it all
955
     */
956
    public function setVarsFromRequest()
957
    {
958
        //Required fields
959
        if (isset($_REQUEST['categoryid'])) {
960
            $this->setVar('categoryid', PublisherRequest::getInt('categoryid'));
961
        }
962
        if (isset($_REQUEST['title'])) {
963
            $this->setVar('title', PublisherRequest::getString('title'));
964
        }
965
        if (isset($_REQUEST['body'])) {
966
            $this->setVar('body', PublisherRequest::getText('body'));
967
        }
968
        //Not required fields
969
        if (isset($_REQUEST['summary'])) {
970
            $this->setVar('summary', PublisherRequest::getText('summary'));
971
        }
972
        if (isset($_REQUEST['subtitle'])) {
973
            $this->setVar('subtitle', PublisherRequest::getString('subtitle'));
974
        }
975
        if (isset($_REQUEST['item_tag'])) {
976
            $this->setVar('item_tag', PublisherRequest::getString('item_tag'));
977
        }
978
        if (isset($_REQUEST['image_featured'])) {
979
            $image_item     = PublisherRequest::getArray('image_item');
980
            $image_featured = PublisherRequest::getString('image_featured');
981
            //Todo: get a better image class for xoops!
982
            //Image hack
983
            $image_item_ids = array();
984
            global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
985
            $sql    = 'SELECT image_id, image_name FROM ' . $xoopsDB->prefix('image');
986
            $result = $xoopsDB->query($sql, 0, 0);
987
            while ($myrow = $xoopsDB->fetchArray($result)) {
988
                $image_name = $myrow['image_name'];
989
                $id         = $myrow['image_id'];
990
                if ($image_name == $image_featured) {
991
                    $this->setVar('image', $id);
992
                }
993
                if (in_array($image_name, $image_item)) {
994
                    $image_item_ids[] = $id;
995
                }
996
            }
997
            $this->setVar('images', implode('|', $image_item_ids));
998
        }
999
        if (isset($_REQUEST['uid'])) {
1000
            $this->setVar('uid', PublisherRequest::getInt('uid'));
1001
        } elseif ($this->isNew()) {
1002
            $this->setVar('uid', is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->uid() : 0);
1003
        }
1004
        if (isset($_REQUEST['author_alias'])) {
1005
            $this->setVar('author_alias', PublisherRequest::getString('author_alias'));
1006
            if ($this->getVar('autor_alias') != '') {
1007
                $this->setVar('uid', 0);
1008
            }
1009
        }
1010
        if (isset($_REQUEST['datesub'])) {
1011
            $this->setVar('datesub', strtotime($_REQUEST['datesub']['date']) + $_REQUEST['datesub']['time']);
1012
        } elseif ($this->isNew()) {
1013
            $this->setVar('datesub', time());
1014
        }
1015
        if (isset($_REQUEST['item_short_url'])) {
1016
            $this->setVar('short_url', PublisherRequest::getString('item_short_url'));
1017
        }
1018
        if (isset($_REQUEST['item_meta_keywords'])) {
1019
            $this->setVar('meta_keywords', PublisherRequest::getString('item_meta_keywords'));
1020
        }
1021
        if (isset($_REQUEST['item_meta_description'])) {
1022
            $this->setVar('meta_description', PublisherRequest::getString('item_meta_description'));
1023
        }
1024
        if (isset($_REQUEST['weight'])) {
1025
            $this->setVar('weight', PublisherRequest::getInt('weight'));
1026
        }
1027 View Code Duplication
        if (isset($_REQUEST['allowcomments'])) {
1028
            $this->setVar('cancomment', PublisherRequest::getInt('allowcomments'));
1029
        } elseif ($this->isNew()) {
1030
            $this->setVar('cancoment', $this->publisher->getConfig('submit_allowcomments'));
1031
        }
1032 View Code Duplication
        if (isset($_REQUEST['status'])) {
1033
            $this->setVar('status', PublisherRequest::getInt('status'));
1034
        } elseif ($this->isNew()) {
1035
            $this->setVar('status', $this->publisher->getConfig('submit_status'));
1036
        }
1037 View Code Duplication
        if (isset($_REQUEST['dohtml'])) {
1038
            $this->setVar('dohtml', PublisherRequest::getInt('dohtml'));
1039
        } elseif ($this->isNew()) {
1040
            $this->setVar('dohtml', $this->publisher->getConfig('submit_dohtml'));
1041
        }
1042 View Code Duplication
        if (isset($_REQUEST['dosmiley'])) {
1043
            $this->setVar('dosmiley', PublisherRequest::getInt('dosmiley'));
1044
        } elseif ($this->isNew()) {
1045
            $this->setVar('dosmiley', $this->publisher->getConfig('submit_dosmiley'));
1046
        }
1047 View Code Duplication
        if (isset($_REQUEST['doxcode'])) {
1048
            $this->setVar('doxcode', PublisherRequest::getInt('doxcode'));
1049
        } elseif ($this->isNew()) {
1050
            $this->setVar('doxcode', $this->publisher->getConfig('submit_doxcode'));
1051
        }
1052 View Code Duplication
        if (isset($_REQUEST['doimage'])) {
1053
            $this->setVar('doimage', PublisherRequest::getInt('doimage'));
1054
        } elseif ($this->isNew()) {
1055
            $this->setVar('doimage', $this->publisher->getConfig('submit_doimage'));
1056
        }
1057 View Code Duplication
        if (isset($_REQUEST['dolinebreak'])) {
1058
            $this->setVar('dobr', PublisherRequest::getInt('dolinebreak'));
1059
        } elseif ($this->isNew()) {
1060
            $this->setVar('dobr', $this->publisher->getConfig('submit_dobr'));
1061
        }
1062
        if (isset($_REQUEST['notify'])) {
1063
            $this->setVar('notifypub', PublisherRequest::getInt('notify'));
1064
        }
1065
    }
1066
}
1067
1068
/**
1069
 * Items handler class.
1070
 * This class is responsible for providing data access mechanisms to the data source
1071
 * of Q&A class objects.
1072
 *
1073
 * @author  marcan <[email protected]>
1074
 * @package Publisher
1075
 */
1076
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...
1077
{
1078
    /**
1079
     * @var PublisherPublisher
1080
     * @access public
1081
     */
1082
    public $publisher;
1083
1084
    /**
1085
     * @param null|XoopsDatabase $db
1086
     */
1087
    public function __construct(XoopsDatabase $db)
1088
    {
1089
        parent::__construct($db, 'publisher_items', 'PublisherItem', 'itemid', 'title');
1090
        $this->publisher = PublisherPublisher::getInstance();
1091
    }
1092
1093
    /**
1094
     * @param bool $isNew
1095
     *
1096
     * @return object
1097
     */
1098
    public function create($isNew = true)
1099
    {
1100
        $obj = parent::create($isNew);
1101
        if ($isNew) {
1102
            $obj->setDefaultPermissions();
1103
        }
1104
1105
        return $obj;
1106
    }
1107
1108
    /**
1109
     * retrieve an item
1110
     *
1111
     * @param int $id itemid of the user
1112
     *
1113
     * @return mixed reference to the {@link PublisherItem} object, FALSE if failed
1114
     */
1115
    public function &get($id)
1116
    {
1117
        $obj =& parent::get($id);
1118
        if (is_object($obj)) {
1119
            $obj->assignOtherProperties();
0 ignored issues
show
Bug introduced by
The method assignOtherProperties() does not seem to exist on object<XoopsObject>.

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

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

Loading history...
1120
        }
1121
1122
        return $obj;
1123
    }
1124
1125
    /**
1126
     * insert a new item in the database
1127
     *
1128
     * @param PublisherItem $item reference to the {@link PublisherItem} object
1129
     * @param bool          $force
1130
     *
1131
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
1132
     */
1133
    public function insert(PublisherItem $item, $force = false)
1134
    {
1135
        if (!$item->meta_keywords() || !$item->meta_description() || !$item->short_url()) {
0 ignored issues
show
Documentation Bug introduced by
The method meta_keywords does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
Documentation Bug introduced by
The method meta_description does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
Documentation Bug introduced by
The method short_url does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1136
            $publisher_metagen = new PublisherMetagen($item->title(), $item->getVar('meta_keywords'), $item->getVar('summary'));
1137
            // Auto create meta tags if empty
1138
            if (!$item->meta_keywords()) {
0 ignored issues
show
Documentation Bug introduced by
The method meta_keywords does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1139
                $item->setVar('meta_keywords', $publisher_metagen->_keywords);
1140
            }
1141
            if (!$item->meta_description()) {
0 ignored issues
show
Documentation Bug introduced by
The method meta_description does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1142
                $item->setVar('meta_description', $publisher_metagen->_description);
1143
            }
1144
            // Auto create short_url if empty
1145
            if (!$item->short_url()) {
0 ignored issues
show
Documentation Bug introduced by
The method short_url does not exist on object<PublisherItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1146
                $item->setVar('short_url', $publisher_metagen->generateSeoTitle($item->getVar('title', 'n'), false));
1147
            }
1148
        }
1149
        if (!parent::insert($item, $force)) {
1150
            return false;
1151
        }
1152 View Code Duplication
        if (xoops_isActiveModule('tag')) {
1153
            // Storing tags information
1154
            $tag_handler = xoops_getModuleHandler('tag', 'tag');
1155
            $tag_handler->updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), PUBLISHER_DIRNAME, 0);
0 ignored issues
show
Bug introduced by
The method updateByItem cannot be called on $tag_handler (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1156
        }
1157
1158
        return true;
1159
    }
1160
1161
    /**
1162
     * delete an item from the database
1163
     *
1164
     * @param PublisherItem $item reference to the ITEM to delete
1165
     * @param bool          $force
1166
     *
1167
     * @return bool FALSE if failed.
1168
     */
1169
    public function delete(PublisherItem $item, $force = false)
1170
    {
1171
        // Deleting the files
1172
        if (!$this->publisher->getHandler('file')->deleteItemFiles($item)) {
1173
            $item->setErrors('An error while deleting a file.');
1174
        }
1175
        if (!parent::delete($item, $force)) {
1176
            $item->setErrors('An error while deleting.');
1177
1178
            return false;
1179
        }
1180
        // Removing tags information
1181 View Code Duplication
        if (xoops_isActiveModule('tag')) {
1182
            $tag_handler = xoops_getModuleHandler('tag', 'tag');
1183
            $tag_handler->updateByItem('', $item->getVar('itemid'), PUBLISHER_DIRNAME, 0);
0 ignored issues
show
Bug introduced by
The method updateByItem cannot be called on $tag_handler (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1184
        }
1185
1186
        return true;
1187
    }
1188
1189
    /**
1190
     * retrieve items from the database
1191
     *
1192
     * @param CriteriaElement $criteria {@link CriteriaElement} conditions to be met
1193
     * @param string          $id_key   what shall we use as array key ? none, itemid, categoryid
1194
     * @param string          $notNullFields
1195
     *
1196
     * @return array array of {@link PublisherItem} objects
1197
     */
1198
    public function &getObjects(CriteriaElement $criteria = null, $id_key = 'none', $notNullFields = '')
1199
    {
1200
        $ret   = array();
1201
        $limit = $start = 0;
1202
        $sql   = 'SELECT * FROM ' . $this->db->prefix('publisher_items');
1203
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
1204
            $whereClause = $criteria->renderWhere();
0 ignored issues
show
Bug introduced by
The method renderWhere() does not exist on CriteriaElement. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1205 View Code Duplication
            if ($whereClause !== 'WHERE ()') {
1206
                $sql .= ' ' . $criteria->renderWhere();
0 ignored issues
show
Bug introduced by
The method renderWhere() does not exist on CriteriaElement. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1207
                if (!empty($notNullFields)) {
1208
                    $sql .= $this->NotNullFieldClause($notNullFields, true);
1209
                }
1210
            } elseif (!empty($notNullFields)) {
1211
                $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
1212
            }
1213
            if ($criteria->getSort() != '') {
1214
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
1215
            }
1216
            $limit = $criteria->getLimit();
1217
            $start = $criteria->getStart();
1218
        } elseif (!empty($notNullFields)) {
1219
            $sql .= $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
1220
        }
1221
        $result = $this->db->query($sql, $limit, $start);
1222
        if (!$result || count($result) == 0) {
1223
            return $ret;
1224
        }
1225
        $theObjects = array();
1226 View Code Duplication
        while ($myrow = $this->db->fetchArray($result)) {
1227
            $item = new PublisherItem();
1228
            $item->assignVars($myrow);
1229
            $theObjects[$myrow['itemid']] = $item;
1230
            unset($item);
1231
        }
1232
        foreach ($theObjects as $theObject) {
1233
            if ($id_key === 'none') {
1234
                $ret[] = $theObject;
1235
            } elseif ($id_key === 'itemid') {
1236
                $ret[$theObject->itemid()] = $theObject;
1237
            } else {
1238
                $ret[$theObject->getVar($id_key)][$theObject->itemid()] = $theObject;
1239
            }
1240
            unset($theObject);
1241
        }
1242
1243
        return $ret;
1244
    }
1245
1246
    /**
1247
     * count items matching a condition
1248
     *
1249
     * @param CriteriaElement $criteria {@link CriteriaElement} to match
1250
     * @param string          $notNullFields
1251
     *
1252
     * @return int count of items
1253
     */
1254
    public function getCount(CriteriaElement $criteria = null, $notNullFields = '')
1255
    {
1256
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('publisher_items');
1257
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
1258
            $whereClause = $criteria->renderWhere();
0 ignored issues
show
Bug introduced by
The method renderWhere() does not exist on CriteriaElement. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1259 View Code Duplication
            if ($whereClause !== 'WHERE ()') {
1260
                $sql .= ' ' . $criteria->renderWhere();
0 ignored issues
show
Bug introduced by
The method renderWhere() does not exist on CriteriaElement. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1261
                if (!empty($notNullFields)) {
1262
                    $sql .= $this->NotNullFieldClause($notNullFields, true);
1263
                }
1264
            } elseif (!empty($notNullFields)) {
1265
                $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
1266
            }
1267
        } elseif (!empty($notNullFields)) {
1268
            $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
1269
        }
1270
        $result = $this->db->query($sql);
1271
        if (!$result) {
1272
            return 0;
1273
        }
1274
        list($count) = $this->db->fetchRow($result);
1275
1276
        return $count;
1277
    }
1278
1279
    /**
1280
     * @param        $categoryid
1281
     * @param string $status
1282
     * @param string $notNullFields
1283
     *
1284
     * @return int
1285
     */
1286
    public function getItemsCount($categoryid = -1, $status = '', $notNullFields = '')
1287
    {
1288
        global $publisher_isAdmin;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1289 View Code Duplication
        if (!$publisher_isAdmin) {
1290
            $criteriaPermissions = new CriteriaCompo();
1291
            // Categories for which user has access
1292
            $categoriesGranted = $this->publisher->getHandler('permission')->getGrantedItems('category_read');
1293
            if (!empty($categoriesGranted)) {
1294
                $grantedCategories = new Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
1295
                $criteriaPermissions->add($grantedCategories, 'AND');
1296
            } else {
1297
                return 0;
1298
            }
1299
        }
1300
        if (isset($categoryid) && $categoryid != -1) {
1301
            $criteriaCategory = new criteria('categoryid', $categoryid);
1302
        }
1303
        $criteriaStatus = new CriteriaCompo();
1304
        if (!empty($status) && is_array($status)) {
1305
            foreach ($status as $v) {
1306
                $criteriaStatus->add(new Criteria('status', $v), 'OR');
1307
            }
1308 View Code Duplication
        } elseif (!empty($status) && $status != -1) {
1309
            $criteriaStatus->add(new Criteria('status', $status), 'OR');
1310
        }
1311
        $criteria = new CriteriaCompo();
1312
        if (!empty($criteriaCategory)) {
1313
            $criteria->add($criteriaCategory);
1314
        }
1315
        if (!empty($criteriaPermissions)) {
1316
            $criteria->add($criteriaPermissions);
1317
        }
1318
        if (!empty($criteriaStatus)) {
1319
            $criteria->add($criteriaStatus);
1320
        }
1321
1322
        return $this->getCount($criteria, $notNullFields);
1323
    }
1324
1325
    /**
1326
     * @param int    $limit
1327
     * @param int    $start
1328
     * @param int    $categoryid
1329
     * @param string $sort
1330
     * @param string $order
1331
     * @param string $notNullFields
1332
     * @param bool   $asobject
1333
     * @param string $id_key
1334
     *
1335
     * @return array
1336
     */
1337
    public function getAllPublished($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none')
1338
    {
1339
        $otherCriteria = new Criteria('datesub', time(), '<=');
1340
1341
        return $this->getItems($limit, $start, array(_PUBLISHER_STATUS_PUBLISHED), $categoryid, $sort, $order, $notNullFields, $asobject, $otherCriteria, $id_key);
1342
    }
1343
1344
    /**
1345
     * @param PublisherItem $obj
1346
     *
1347
     * @return bool
1348
     */
1349
    public function getPreviousPublished($obj)
1350
    {
1351
        $ret           = false;
1352
        $otherCriteria = new CriteriaCompo();
1353
        $otherCriteria->add(new Criteria('datesub', $obj->getVar('datesub'), '<'));
1354
        $objs = $this->getItems(1, 0, array(_PUBLISHER_STATUS_PUBLISHED), $obj->getVar('categoryid'), 'datesub', 'DESC', '', true, $otherCriteria, 'none');
1355
        if (count($objs) > 0) {
1356
            $ret = $objs[0];
1357
        }
1358
1359
        return $ret;
1360
    }
1361
1362
    /**
1363
     * @param PublisherItem $obj
1364
     *
1365
     * @return bool
1366
     */
1367
    public function getNextPublished($obj)
1368
    {
1369
        $ret           = false;
1370
        $otherCriteria = new CriteriaCompo();
1371
        $otherCriteria->add(new Criteria('datesub', $obj->getVar('datesub'), '>'));
1372
        $otherCriteria->add(new Criteria('datesub', time(), '<='));
1373
        $objs = $this->getItems(1, 0, array(_PUBLISHER_STATUS_PUBLISHED), $obj->getVar('categoryid'), 'datesub', 'ASC', '', true, $otherCriteria, 'none');
1374
        if (count($objs) > 0) {
1375
            $ret = $objs[0];
1376
        }
1377
1378
        return $ret;
1379
    }
1380
1381
    /**
1382
     * @param int    $limit
1383
     * @param int    $start
1384
     * @param int    $categoryid
1385
     * @param string $sort
1386
     * @param string $order
1387
     * @param string $notNullFields
1388
     * @param bool   $asobject
1389
     * @param string $id_key
1390
     *
1391
     * @return array
1392
     */
1393
    public function getAllSubmitted($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none')
1394
    {
1395
        return $this->getItems($limit, $start, array(_PUBLISHER_STATUS_SUBMITTED), $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
1396
    }
1397
1398
    /**
1399
     * @param int    $limit
1400
     * @param int    $start
1401
     * @param int    $categoryid
1402
     * @param string $sort
1403
     * @param string $order
1404
     * @param string $notNullFields
1405
     * @param bool   $asobject
1406
     * @param string $id_key
1407
     *
1408
     * @return array
1409
     */
1410
    public function getAllOffline($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none')
1411
    {
1412
        return $this->getItems($limit, $start, array(_PUBLISHER_STATUS_OFFLINE), $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
1413
    }
1414
1415
    /**
1416
     * @param int    $limit
1417
     * @param int    $start
1418
     * @param int    $categoryid
1419
     * @param string $sort
1420
     * @param string $order
1421
     * @param string $notNullFields
1422
     * @param bool   $asobject
1423
     * @param string $id_key
1424
     *
1425
     * @return array
1426
     */
1427
    public function getAllRejected($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none')
1428
    {
1429
        return $this->getItems($limit, $start, array(_PUBLISHER_STATUS_REJECTED), $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key);
1430
    }
1431
1432
    /**
1433
     * @param int    $limit
1434
     * @param int    $start
1435
     * @param string $status
1436
     * @param int    $categoryid
1437
     * @param string $sort
1438
     * @param string $order
1439
     * @param string $notNullFields
1440
     * @param bool   $asobject
1441
     * @param null   $otherCriteria
1442
     * @param string $id_key
1443
     *
1444
     * @return array
1445
     */
1446
    public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $otherCriteria = null, $id_key = 'none')
0 ignored issues
show
Unused Code introduced by
The parameter $asobject is not used and could be removed.

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

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

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1449 View Code Duplication
        if (!$publisher_isAdmin) {
1450
            $criteriaPermissions = new CriteriaCompo();
1451
            // Categories for which user has access
1452
            $categoriesGranted = $this->publisher->getHandler('permission')->getGrantedItems('category_read');
1453
            if (!empty($categoriesGranted)) {
1454
                $grantedCategories = new Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
1455
                $criteriaPermissions->add($grantedCategories, 'AND');
1456
            } else {
1457
                return array();
1458
            }
1459
        }
1460
        if (isset($categoryid) && ($categoryid != -1)) {
1461
            $criteriaCategory = new criteria('categoryid', $categoryid);
1462
        }
1463
        if (!empty($status) && is_array($status)) {
1464
            $criteriaStatus = new CriteriaCompo();
1465
            foreach ($status as $v) {
1466
                $criteriaStatus->add(new Criteria('status', $v), 'OR');
1467
            }
1468 View Code Duplication
        } elseif (!empty($status) && $status != -1) {
1469
            $criteriaStatus = new CriteriaCompo();
1470
            $criteriaStatus->add(new Criteria('status', $status), 'OR');
1471
        }
1472
        $criteria = new CriteriaCompo();
1473
        if (!empty($criteriaCategory)) {
1474
            $criteria->add($criteriaCategory);
1475
        }
1476
        if (!empty($criteriaPermissions)) {
1477
            $criteria->add($criteriaPermissions);
1478
        }
1479
        if (!empty($criteriaStatus)) {
1480
            $criteria->add($criteriaStatus);
1481
        }
1482
        if (!empty($otherCriteria)) {
1483
            $criteria->add($otherCriteria);
1484
        }
1485
        $criteria->setLimit($limit);
1486
        $criteria->setStart($start);
1487
        $criteria->setSort($sort);
1488
        $criteria->setOrder($order);
1489
        $ret =& $this->getObjects($criteria, $id_key, $notNullFields);
1490
1491
        return $ret;
1492
    }
1493
1494
    /**
1495
     * @param string $field
1496
     * @param string $status
1497
     * @param int    $categoryId
1498
     *
1499
     * @return bool
1500
     */
1501
    public function getRandomItem($field = '', $status = '', $categoryId = -1)
1502
    {
1503
        $ret           = false;
1504
        $notNullFields = $field;
1505
        // Getting the number of published Items
1506
        $totalItems = $this->getItemsCount($categoryId, $status, $notNullFields);
1507
        if ($totalItems > 0) {
1508
            --$totalItems;
1509
            mt_srand((double)microtime() * 1000000);
1510
            $entrynumber = mt_rand(0, $totalItems);
1511
            $item        = $this->getItems(1, $entrynumber, $status, $categoryId, $sort = 'datesub', $order = 'DESC', $notNullFields);
1512
            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...
1513
                $ret = $item[0];
1514
            }
1515
        }
1516
1517
        return $ret;
1518
    }
1519
1520
    /**
1521
     * delete Items matching a set of conditions
1522
     *
1523
     * @param CriteriaElement $criteria {@link CriteriaElement}
1524
     *
1525
     * @return bool FALSE if deletion failed
1526
     */
1527
    public function deleteAll(CriteriaElement $criteria = null)
1528
    {
1529
        //todo resource consuming, use get list instead?
1530
        $items =& $this->getObjects($criteria);
1531
        foreach ($items as $item) {
1532
            $this->delete($item);
1533
        }
1534
1535
        return true;
1536
    }
1537
1538
    /**
1539
     * @param $itemid
1540
     *
1541
     * @return bool
1542
     */
1543
    public function updateCounter($itemid)
1544
    {
1545
        $sql = 'UPDATE ' . $this->db->prefix('publisher_items') . ' SET counter=counter+1 WHERE itemid = ' . $itemid;
1546
        if ($this->db->queryF($sql)) {
1547
            return true;
1548
        } else {
1549
            return false;
1550
        }
1551
    }
1552
1553
    /**
1554
     * @param string|array $notNullFields
1555
     * @param bool         $withAnd
1556
     *
1557
     * @return string
1558
     */
1559
    public function NotNullFieldClause($notNullFields = '', $withAnd = false)
1560
    {
1561
        $ret = '';
1562
        if ($withAnd) {
1563
            $ret .= ' AND ';
1564
        }
1565
        if (!empty($notNullFields) && is_array($notNullFields)) {
1566
            foreach ($notNullFields as $v) {
1567
                $ret .= " ($v IS NOT NULL AND $v <> ' ' )";
1568
            }
1569
        } elseif (!empty($notNullFields)) {
1570
            $ret .= " ($notNullFields IS NOT NULL AND $notNullFields <> ' ' )";
1571
        }
1572
1573
        return $ret;
1574
    }
1575
1576
    /**
1577
     * @param array  $queryarray
1578
     * @param string $andor
1579
     * @param int    $limit
1580
     * @param int    $offset
1581
     * @param int    $userid
1582
     * @param array  $categories
1583
     * @param int    $sortby
1584
     * @param string $searchin
1585
     * @param string $extra
1586
     *
1587
     * @return array
1588
     */
1589
    public function getItemsFromSearch($queryarray = array(), $andor = 'AND', $limit = 0, $offset = 0, $userid = 0, $categories = array(), $sortby = 0, $searchin = '', $extra = '')
0 ignored issues
show
Unused Code introduced by
The parameter $extra is not used and could be removed.

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

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

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1592
        $ret           = array();
1593
        $gperm_handler = xoops_getHandler('groupperm');
1594
        $groups        = is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
1595
        $searchin      = empty($searchin) ? array('title', 'body', 'summary') : (is_array($searchin) ? $searchin : array($searchin));
1596
        if (in_array('all', $searchin) || count($searchin) == 0) {
1597
            $searchin = array('title', 'subtitle', 'body', 'summary', 'meta_keywords');
1598
        }
1599
        if (is_array($userid) && count($userid) > 0) {
1600
            $userid       = array_map('intval', $userid);
1601
            $criteriaUser = new CriteriaCompo();
1602
            $criteriaUser->add(new Criteria('uid', '(' . implode(',', $userid) . ')', 'IN'), 'OR');
1603
        } elseif (is_numeric($userid) && $userid > 0) {
1604
            $criteriaUser = new CriteriaCompo();
1605
            $criteriaUser->add(new Criteria('uid', $userid), 'OR');
1606
        }
1607
        $count = count($queryarray);
1608
        if (is_array($queryarray) && $count > 0) {
1609
            $criteriaKeywords = new CriteriaCompo();
1610
            $queryarrayCount  = count($queryarray);
1611
            for ($i = 0; $i < $queryarrayCount; ++$i) {
1612
                $criteriaKeyword = new CriteriaCompo();
1613 View Code Duplication
                if (in_array('title', $searchin)) {
1614
                    $criteriaKeyword->add(new Criteria('title', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1615
                }
1616 View Code Duplication
                if (in_array('subtitle', $searchin)) {
1617
                    $criteriaKeyword->add(new Criteria('subtitle', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1618
                }
1619 View Code Duplication
                if (in_array('body', $searchin)) {
1620
                    $criteriaKeyword->add(new Criteria('body', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1621
                }
1622 View Code Duplication
                if (in_array('summary', $searchin)) {
1623
                    $criteriaKeyword->add(new Criteria('summary', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1624
                }
1625 View Code Duplication
                if (in_array('meta_keywords', $searchin)) {
1626
                    $criteriaKeyword->add(new Criteria('meta_keywords', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1627
                }
1628
                $criteriaKeywords->add($criteriaKeyword, $andor);
1629
                unset($criteriaKeyword);
1630
            }
1631
        }
1632
        if (!$publisher_isAdmin && (count($categories) > 0)) {
1633
            $criteriaPermissions = new CriteriaCompo();
1634
            // Categories for which user has access
1635
            $categoriesGranted = $gperm_handler->getItemIds('category_read', $groups, $this->publisher->getModule()->getVar('mid'));
1636
            if (count($categories) > 0) {
1637
                $categoriesGranted = array_intersect($categoriesGranted, $categories);
1638
            }
1639
            if (count($categoriesGranted) == 0) {
1640
                return $ret;
1641
            }
1642
            $grantedCategories = new Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
1643
            $criteriaPermissions->add($grantedCategories, 'AND');
1644 View Code Duplication
        } elseif (count($categories) > 0) {
1645
            $criteriaPermissions = new CriteriaCompo();
1646
            $grantedCategories   = new Criteria('categoryid', '(' . implode(',', $categories) . ')', 'IN');
1647
            $criteriaPermissions->add($grantedCategories, 'AND');
1648
        }
1649
        $criteriaItemsStatus = new CriteriaCompo();
1650
        $criteriaItemsStatus->add(new Criteria('status', _PUBLISHER_STATUS_PUBLISHED));
1651
        $criteria = new CriteriaCompo();
1652
        if (!empty($criteriaUser)) {
1653
            $criteria->add($criteriaUser, 'AND');
1654
        }
1655
        if (!empty($criteriaKeywords)) {
1656
            $criteria->add($criteriaKeywords, 'AND');
1657
        }
1658
        if (!empty($criteriaPermissions)) {
1659
            $criteria->add($criteriaPermissions);
1660
        }
1661
        if (!empty($criteriaItemsStatus)) {
1662
            $criteria->add($criteriaItemsStatus, 'AND');
1663
        }
1664
        $criteria->setLimit($limit);
1665
        $criteria->setStart($offset);
1666
        if (empty($sortby)) {
1667
            $sortby = 'datesub';
1668
        }
1669
        $criteria->setSort($sortby);
1670
        $order = 'ASC';
1671
        if ($sortby === 'datesub') {
1672
            $order = 'DESC';
1673
        }
1674
        $criteria->setOrder($order);
1675
        $ret =& $this->getObjects($criteria);
1676
1677
        return $ret;
1678
    }
1679
1680
    /**
1681
     * @param array $categoriesObj
1682
     * @param array $status
1683
     *
1684
     * @return array
1685
     */
1686
    public function getLastPublishedByCat($categoriesObj, $status = array(_PUBLISHER_STATUS_PUBLISHED))
1687
    {
1688
        $ret    = array();
1689
        $catIds = array();
1690
        foreach ($categoriesObj as $parentid) {
1691
            foreach ($parentid as $category) {
1692
                $catId          = $category->getVar('categoryid');
1693
                $catIds[$catId] = $catId;
1694
            }
1695
        }
1696
        if (empty($catIds)) {
1697
            return $ret;
1698
        }
1699
        /*$cat = array();
1700
1701
        $sql = "SELECT categoryid, MAX(datesub) as date FROM " . $this->db->prefix('publisher_items') . " WHERE status IN (" . implode(',', $status) . ") GROUP BY categoryid";
1702
        $result = $this->db->query($sql);
1703
        while ($row = $this->db->fetchArray($result)) {
1704
            $cat[$row['categoryid']] = $row['date'];
1705
        }
1706
        if (count($cat) == 0) return $ret;
1707
        $sql = "SELECT categoryid, itemid, title, short_url, uid, datesub FROM " . $this->db->prefix('publisher_items');
1708
        $criteriaBig = new CriteriaCompo();
1709
        foreach ($cat as $id => $date) {
1710
            $criteria = new CriteriaCompo(new Criteria('categoryid', $id));
1711
            $criteria->add(new Criteria('datesub', $date));
1712
            $criteriaBig->add($criteria, 'OR');
1713
            unset($criteria);
1714
        }
1715
        $sql .= " " . $criteriaBig->renderWhere();
1716
        $result = $this->db->query($sql);
1717
        while ($row = $this->db->fetchArray($result)) {
1718
            $item = new PublisherItem();
1719
            $item->assignVars($row);
1720
            $ret[$row['categoryid']] = $item;
1721
            unset($item);
1722
        }
1723
        */
1724
        $sql = 'SELECT mi.categoryid, mi.itemid, mi.title, mi.short_url, mi.uid, mi.datesub';
1725
        $sql .= ' FROM (SELECT categoryid, MAX(datesub) AS date FROM ' . $this->db->prefix('publisher_items');
1726
        $sql .= ' WHERE status IN (' . implode(',', $status) . ')';
1727
        $sql .= ' AND categoryid IN (' . implode(',', $catIds) . ')';
1728
        $sql .= ' GROUP BY categoryid)mo';
1729
        $sql .= ' JOIN ' . $this->db->prefix('publisher_items') . ' mi ON mi.datesub = mo.date';
1730
        $result = $this->db->query($sql);
1731 View Code Duplication
        while ($row = $this->db->fetchArray($result)) {
1732
            $item = new PublisherItem();
1733
            $item->assignVars($row);
1734
            $ret[$row['categoryid']] = $item;
1735
            unset($item);
1736
        }
1737
1738
        return $ret;
1739
    }
1740
1741
    /**
1742
     * @param int    $parentid
1743
     * @param int    $catsCount
1744
     * @param string $spaces
1745
     *
1746
     * @return int
1747
     */
1748
    public function countArticlesByCat($parentid, &$catsCount, $spaces = '')
1749
    {
1750
        global $resultCatCounts;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1751
        $newspaces = $spaces . '--';
1752
        $thecount  = 0;
1753
        foreach ($catsCount[$parentid] as $subCatId => $count) {
1754
            $thecount += $count;
1755
            $resultCatCounts[$subCatId] = $count;
1756
            if (isset($catsCount[$subCatId])) {
1757
                $thecount += $this->countArticlesByCat($subCatId, $catsCount, $newspaces);
1758
                $resultCatCounts[$subCatId] = $thecount;
1759
            }
1760
        }
1761
1762
        return $thecount;
1763
    }
1764
1765
    /**
1766
     * @param int   $cat_id
1767
     * @param array $status
1768
     * @param bool  $inSubCat
1769
     *
1770
     * @return array
1771
     */
1772
    public function getCountsByCat($cat_id = 0, $status, $inSubCat = false)
1773
    {
1774
        global $resultCatCounts;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1775
        $ret       = array();
1776
        $catsCount = array();
1777
        $sql       = 'SELECT c.parentid, i.categoryid, COUNT(*) AS count FROM ' . $this->db->prefix('publisher_items') . ' AS i INNER JOIN ' . $this->db->prefix('publisher_categories') . ' AS c ON i.categoryid=c.categoryid';
1778
        if ((int)$cat_id > 0) {
1779
            $sql .= ' WHERE i.categoryid = ' . (int)$cat_id;
1780
            $sql .= ' AND i.status IN (' . implode(',', $status) . ')';
1781
        } else {
1782
            $sql .= ' WHERE i.status IN (' . implode(',', $status) . ')';
1783
        }
1784
        $sql .= ' GROUP BY i.categoryid ORDER BY c.parentid ASC, i.categoryid ASC';
1785
        $result = $this->db->query($sql);
1786
        if (!$result) {
1787
            return $ret;
1788
        }
1789
        if (!$inSubCat) {
1790 View Code Duplication
            while ($row = $this->db->fetchArray($result)) {
1791
                $catsCount[$row['categoryid']] = $row['count'];
1792
            }
1793
1794
            return $catsCount;
1795
        }
1796 View Code Duplication
        while ($row = $this->db->fetchArray($result)) {
1797
            $catsCount[$row['parentid']][$row['categoryid']] = $row['count'];
1798
        }
1799
        $resultCatCounts = array();
1800
        foreach ($catsCount[0] as $subCatId => $count) {
1801
            $resultCatCounts[$subCatId] = $count;
1802
            if (isset($catsCount[$subCatId])) {
1803
                $resultCatCounts[$subCatId] += $this->countArticlesByCat($subCatId, $catsCount);
0 ignored issues
show
Bug introduced by
It seems like $catsCount defined by array() on line 1776 can also be of type array; however, PublisherItemHandler::countArticlesByCat() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1804
            }
1805
        }
1806
1807
        return $resultCatCounts;
1808
    }
1809
}
1810