1<?php
2/**
3 * XOOPS Kernel Class
4 *
5 * You may not change or alter any portion of this comment or credits
6 * of supporting developers from this source code or any supporting source code
7 * which is considered copyrighted (c) material of the original comment or credit authors.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13 * @license             GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
14 * @package             kernel
15 * @since               2.0.0
16 * @author              Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
17 */
18defined('XOOPS_ROOT_PATH') || exit('Restricted access');
19
20/**
21 * A block
22 *
23 * @author  Kazumi Ono <onokazu@xoops.org>
24 *
25 * @package kernel
26 *
27 * @todo reconcile the two XoopsBlock classes.
28 * @internal This handler appears to only be loaded by system/class/group.php
29 * @internal The other, in class/xoopsblock.php is loaded all over
30 */
31class XoopsBlock extends XoopsObject
32{
33    /**
34     * constructor
35     *
36     * @param mixed $id
37     **/
38    public function __construct($id = null)
39    {
40        $this->initVar('bid', XOBJ_DTYPE_INT, null, false);
41        $this->initVar('mid', XOBJ_DTYPE_INT, 0, false);
42        $this->initVar('func_num', XOBJ_DTYPE_INT, 0, false);
43        $this->initVar('options', XOBJ_DTYPE_TXTBOX, null, false, 255);
44        $this->initVar('name', XOBJ_DTYPE_TXTBOX, null, true, 150);
45        //$this->initVar('position', XOBJ_DTYPE_INT, 0, false);
46        $this->initVar('title', XOBJ_DTYPE_TXTBOX, null, false, 150);
47        $this->initVar('content', XOBJ_DTYPE_TXTAREA, null, false);
48        $this->initVar('side', XOBJ_DTYPE_INT, 0, false);
49        $this->initVar('weight', XOBJ_DTYPE_INT, 0, false);
50        $this->initVar('visible', XOBJ_DTYPE_INT, 0, false);
51        $this->initVar('block_type', XOBJ_DTYPE_OTHER, null, false);
52        $this->initVar('c_type', XOBJ_DTYPE_OTHER, null, false);
53        $this->initVar('isactive', XOBJ_DTYPE_INT, null, false);
54        $this->initVar('dirname', XOBJ_DTYPE_TXTBOX, null, false, 50);
55        $this->initVar('func_file', XOBJ_DTYPE_TXTBOX, null, false, 50);
56        $this->initVar('show_func', XOBJ_DTYPE_TXTBOX, null, false, 50);
57        $this->initVar('edit_func', XOBJ_DTYPE_TXTBOX, null, false, 50);
58        $this->initVar('template', XOBJ_DTYPE_OTHER, null, false);
59        $this->initVar('bcachetime', XOBJ_DTYPE_INT, 0, false);
60        $this->initVar('last_modified', XOBJ_DTYPE_INT, 0, false);
61
62        // for backward compatibility
63        if (isset($id)) {
64            if (is_array($id)) {
65                $this->assignVars($id);
66            } else {
67                $blkhandler = xoops_getHandler('block');
68                $obj        = $blkhandler->get($id);
69                foreach (array_keys($obj->getVars()) as $i) {
70                    $this->assignVar($i, $obj->getVar($i, 'n'));
71                }
72            }
73        }
74    }
75
76    /**
77     * Returns Class Base Variable bid
78     * @param string $format
79     * @return mixed
80     */
81    public function id($format = 'n')
82    {
83        return $this->getVar('bid', $format);
84    }
85
86    /**
87     * Returns Class Base Variable bid
88     * @param string $format
89     * @return mixed
90     */
91    public function bid($format = '')
92    {
93        return $this->getVar('bid', $format);
94    }
95
96    /**
97     * Returns Class Base Variable mid
98     * @param string $format
99     * @return mixed
100     */
101    public function mid($format = '')
102    {
103        return $this->getVar('mid', $format);
104    }
105
106    /**
107     * Returns Class Base Variable func_num
108     * @param string $format
109     * @return mixed
110     */
111    public function func_num($format = '')
112    {
113        return $this->getVar('func_num', $format);
114    }
115
116    /**
117     * Returns Class Base Variable avatar_id
118     * @param string $format
119     * @return mixed
120     */
121    public function options($format = '')
122    {
123        return $this->getVar('options', $format);
124    }
125
126    /**
127     * Returns Class Base Variable name
128     * @param string $format
129     * @return mixed
130     */
131    public function name($format = '')
132    {
133        return $this->getVar('name', $format);
134    }
135
136    /**
137     * Returns Class Base Variable title
138     * @param string $format
139     * @return mixed
140     */
141    public function title($format = '')
142    {
143        return $this->getVar('title', $format);
144    }
145
146    /**
147     * Returns Class Base Variable content
148     * @param string $format
149     * @return mixed
150     */
151    public function content($format = '')
152    {
153        return $this->getVar('content', $format);
154    }
155
156    /**
157     * Returns Class Base Variable side
158     * @param string $format
159     * @return mixed
160     */
161    public function side($format = '')
162    {
163        return $this->getVar('side', $format);
164    }
165
166    /**
167     * Returns Class Base Variable weight
168     * @param string $format
169     * @return mixed
170     */
171    public function weight($format = '')
172    {
173        return $this->getVar('weight', $format);
174    }
175
176    /**
177     * Returns Class Base Variable visible
178     * @param string $format
179     * @return mixed
180     */
181    public function visible($format = '')
182    {
183        return $this->getVar('visible', $format);
184    }
185
186    /**
187     * Returns Class Base Variable block_type
188     * @param string $format
189     * @return mixed
190     */
191    public function block_type($format = '')
192    {
193        return $this->getVar('block_type', $format);
194    }
195
196    /**
197     * Returns Class Base Variable c_type
198     * @param string $format
199     * @return mixed
200     */
201    public function c_type($format = '')
202    {
203        return $this->getVar('c_type', $format);
204    }
205
206    /**
207     * Returns Class Base Variable isactive
208     * @param string $format
209     * @return mixed
210     */
211    public function isactive($format = '')
212    {
213        return $this->getVar('isactive', $format);
214    }
215
216    /**
217     * Returns Class Base Variable dirname
218     * @param string $format
219     * @return mixed
220     */
221    public function dirname($format = '')
222    {
223        return $this->getVar('dirname', $format);
224    }
225
226    /**
227     * Returns Class Base Variable func_file
228     * @param string $format
229     * @return mixed
230     */
231    public function func_file($format = '')
232    {
233        return $this->getVar('func_file', $format);
234    }
235
236    /**
237     * Returns Class Base Variable show_func
238     * @param string $format
239     * @return mixed
240     */
241    public function show_func($format = '')
242    {
243        return $this->getVar('show_func', $format);
244    }
245
246    /**
247     * Returns Class Base Variable edit_func
248     * @param string $format
249     * @return mixed
250     */
251    public function edit_func($format = '')
252    {
253        return $this->getVar('edit_func', $format);
254    }
255
256    /**
257     * Returns Class Base Variable template
258     * @param string $format
259     * @return mixed
260     */
261    public function template($format = '')
262    {
263        return $this->getVar('template', $format);
264    }
265
266    /**
267     * Returns Class Base Variable avatar_id
268     * @param string $format
269     * @return mixed
270     */
271    public function bcachetime($format = '')
272    {
273        return $this->getVar('bcachetime', $format);
274    }
275
276    /**
277     * Returns Class Base Variable last_modified
278     * @param string $format
279     * @return mixed
280     */
281    public function last_modified($format = '')
282    {
283        return $this->getVar('last_modified', $format);
284    }
285
286    /**
287     * return the content of the block for output
288     *
289     * @param  string $format
290     * @param  string $c_type type of content<br>
291     *                        Legal value for the type of content<br>
292     *                        <ul><li>H : custom HTML block
293     *                        <li>P : custom PHP block
294     *                        <li>S : use text sanitizater (smilies enabled)
295     *                        <li>T : use text sanitizater (smilies disabled)</ul>
296     * @return string content for output
297     */
298    public function getContent($format = 's', $c_type = 'T')
299    {
300        $format = strtolower($format);
301        $c_type = strtoupper($c_type);
302        switch ($format) {
303            case 's':
304                if ($c_type === 'H') {
305                    return str_replace('{X_SITEURL}', XOOPS_URL . '/', $this->getVar('content', 'n'));
306                } elseif ($c_type === 'P') {
307                    ob_start();
308                    echo eval($this->getVar('content', 'n'));
309                    $content = ob_get_contents();
310                    ob_end_clean();
311
312                    return str_replace('{X_SITEURL}', XOOPS_URL . '/', $content);
313                } elseif ($c_type === 'S') {
314                    $myts    = MyTextSanitizer::getInstance();
315                    $content = str_replace('{X_SITEURL}', XOOPS_URL . '/', $this->getVar('content', 'n'));
316
317                    return $myts->displayTarea($content, 0, 1);
318                } else {
319                    $myts    = MyTextSanitizer::getInstance();
320                    $content = str_replace('{X_SITEURL}', XOOPS_URL . '/', $this->getVar('content', 'n'));
321
322                    return $myts->displayTarea($content, 0, 0);
323                }
324                break;
325            case 'e':
326                return $this->getVar('content', 'e');
327                break;
328            default:
329                return $this->getVar('content', 'n');
330                break;
331        }
332    }
333
334    /**
335     * (HTML-) form for setting the options of the block
336     *
337     * @return string HTML for the form, FALSE if not defined for this block
338     */
339    public function getOptions()
340    {
341        if (!$this->isCustom()) {
342            $edit_func = $this->getVar('edit_func');
343            if (!$edit_func) {
344                return false;
345            }
346            if (file_exists(XOOPS_ROOT_PATH . '/modules/' . $this->getVar('dirname') . '/blocks/' . $this->getVar('func_file'))) {
347                if (file_exists(XOOPS_ROOT_PATH . '/modules/' . $this->getVar('dirname') . '/language/' . $GLOBALS['xoopsConfig']['language'] . '/blocks.php')) {
348                    include_once XOOPS_ROOT_PATH . '/modules/' . $this->getVar('dirname') . '/language/' . $GLOBALS['xoopsConfig']['language'] . '/blocks.php';
349                } elseif (file_exists(XOOPS_ROOT_PATH . '/modules/' . $this->getVar('dirname') . '/language/english/blocks.php')) {
350                    include_once XOOPS_ROOT_PATH . '/modules/' . $this->getVar('dirname') . '/language/english/blocks.php';
351                }
352                include_once XOOPS_ROOT_PATH . '/modules/' . $this->getVar('dirname') . '/blocks/' . $this->getVar('func_file');
353                $options   = explode('|', $this->getVar('options'));
354                $edit_form = $edit_func($options);
355                if (!$edit_form) {
356                    return false;
357                }
358
359                return $edit_form;
360            } else {
361                return false;
362            }
363        } else {
364            return false;
365        }
366    }
367
368    /**
369     * @return bool
370     */
371    public function isCustom()
372    {
373        return in_array($this->getVar('block_type'), array(
374            'C',
375            'E'));
376    }
377}
378
379/**
380 * XOOPS block handler class. (Singelton)
381 *
382 * This class is responsible for providing data access mechanisms to the data source
383 * of XOOPS block class objects.
384 *
385 * @author              Kazumi Ono <onokazu@xoops.org>
386 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
387 * @package             kernel
388 * @subpackage          block
389 *
390 * @todo Why is this not a XoopsPersistableObjectHandler?
391 */
392class XoopsBlockHandler extends XoopsObjectHandler
393{
394    /**
395     * create a new block
396     *
397     * @see XoopsBlock
398     * @param  bool $isNew is the new block new??
399     * @return XoopsBlock XoopsBlock reference to the new block
400     **/
401    public function create($isNew = true)
402    {
403        $block = new XoopsBlock();
404        if ($isNew) {
405            $block->setNew();
406        }
407
408        return $block;
409    }
410
411    /**
412     * retrieve a specific {@link XoopsBlock}
413     *
414     * @see XoopsBlock
415     * @param  int $id bid of the block to retrieve
416     * @return XoopsBlock reference to the block
417     **/
418    public function get($id)
419    {
420        $block = false;
421        $id    = (int)$id;
422        if ($id > 0) {
423            $sql = 'SELECT * FROM ' . $this->db->prefix('newblocks') . ' WHERE bid=' . $id;
424            if ($result = $this->db->query($sql)) {
425                $numrows = $this->db->getRowsNum($result);
426                if ($numrows == 1) {
427                    $block = new XoopsBlock();
428                    $block->assignVars($this->db->fetchArray($result));
429                }
430            }
431        }
432
433        return $block;
434    }
435
436    /**
437     * write a new block into the database
438     *
439     * @param XoopsObject|XoopsBlock $block a XoopsBlock object
440     *
441     * @return bool true on success, otherwise false
442     */
443    public function insert(XoopsObject $block)
444    {
445        $className = 'XoopsBlock';
446        if (!($block instanceof $className)) {
447            return false;
448        }
449        if (!$block->isDirty()) {
450            return true;
451        }
452        if (!$block->cleanVars()) {
453            return false;
454        }
455
456        $bid = $block->getVar('bid', 'n');
457        $mid = $block->getVar('mid', 'n');
458        $func_num = $block->getVar('func_num', 'n');
459        $options = $block->getVar('options', 'n');
460        $name = $block->getVar('name', 'n');
461        $title = $block->getVar('title', 'n');
462        $content = $block->getVar('content', 'n');
463        $side = $block->getVar('side', 'n');
464        $weight = $block->getVar('weight', 'n');
465        $visible = $block->getVar('visible', 'n');
466        $c_type = $block->getVar('c_type', 'n');
467        $isactive = $block->getVar('isactive', 'n');
468        $func_file = $block->getVar('func_file', 'n');
469        $show_func = $block->getVar('show_func', 'n');
470        $edit_func = $block->getVar('edit_func', 'n');
471        $template = $block->getVar('template', 'n');
472        $bcachetime = $block->getVar('bcachetime', 'n');
473        $block_type = $block->getVar('block_type', 'n');
474        $dirname = $block->getVar('dirname', 'n');
475
476        if ($block->isNew()) {
477            $bid = $this->db->genId('newblocks_bid_seq');
478            $sql = sprintf(
479                'INSERT INTO %s (bid, mid, func_num, options, name, title, content, side, weight, visible, block_type,'
480                . ' c_type, isactive, dirname, func_file, show_func, edit_func, template, bcachetime, last_modified)'
481                . " VALUES (%u, %u, %u, '%s', '%s', '%s', '%s', %u, %u, %u, '%s', '%s', %u, '%s', '%s', '%s', '%s',"
482                . " '%s', %u, %u)",
483                $this->db->prefix('newblocks'),
484                $bid,
485                $mid,
486                $func_num,
487                $options,
488                $name,
489                $title,
490                $content,
491                $side,
492                $weight,
493                $visible,
494                $block_type,
495                $c_type,
496                1,
497                $dirname,
498                $func_file,
499                $show_func,
500                $edit_func,
501                $template,
502                $bcachetime,
503                time()
504            );
505        } else {
506            $sql = sprintf(
507                "UPDATE %s SET func_num = %u, options = '%s', name = '%s', title = '%s', content = '%s', side = %u,"
508                . " weight = %u, visible = %u, c_type = '%s', isactive = %u, func_file = '%s', show_func = '%s',"
509                . " edit_func = '%s', template = '%s', bcachetime = %u, last_modified = %u WHERE bid = %u",
510                $this->db->prefix('newblocks'),
511                $func_num,
512                $options,
513                $name,
514                $title,
515                $content,
516                $side,
517                $weight,
518                $visible,
519                $c_type,
520                $isactive,
521                $func_file,
522                $show_func,
523                $edit_func,
524                $template,
525                $bcachetime,
526                time(),
527                $bid
528            );
529        }
530        if (!$result = $this->db->query($sql)) {
531            return false;
532        }
533        if (empty($bid)) {
534            $bid = $this->db->getInsertId();
535        }
536        $block->assignVar('bid', $bid);
537
538        return true;
539    }
540
541    /**
542     * delete a block from the database
543     *
544     * @param XoopsObject|XoopsBlock $block a XoopsBlock object
545     *
546     * @return bool true on success, otherwise false
547     */
548    public function delete(XoopsObject $block)
549    {
550        $className = 'XoopsBlock';
551        if (!($block instanceof $className)) {
552            return false;
553        }
554        $id  = $block->getVar('bid');
555        $sql = sprintf('DELETE FROM %s WHERE bid = %u', $this->db->prefix('newblocks'), $id);
556        if (!$result = $this->db->query($sql)) {
557            return false;
558        }
559        $sql = sprintf('DELETE FROM %s WHERE block_id = %u', $this->db->prefix('block_module_link'), $id);
560        $this->db->query($sql);
561
562        return true;
563    }
564
565    /**
566     * retrieve array of {@link XoopsBlock}s meeting certain conditions
567     * @param  CriteriaElement|CriteriaCompo $criteria  {@link CriteriaElement} with conditions for the blocks
568     * @param  bool   $id_as_key should the blocks' bid be the key for the returned array?
569     * @return array  {@link XoopsBlock}s matching the conditions
570     **/
571    public function getObjects(CriteriaElement $criteria = null, $id_as_key = false)
572    {
573        $ret   = array();
574        $limit = $start = 0;
575        $sql   = 'SELECT DISTINCT(b.bid), b.* FROM ' . $this->db->prefix('newblocks') . ' b LEFT JOIN '
576            . $this->db->prefix('block_module_link') . ' l ON b.bid=l.block_id';
577        if (isset($criteria) && is_subclass_of($criteria, 'CriteriaElement')) {
578            $sql .= ' ' . $criteria->renderWhere();
579            $limit = $criteria->getLimit();
580            $start = $criteria->getStart();
581        }
582        $result = $this->db->query($sql, $limit, $start);
583        if (!$result) {
584            return $ret;
585        }
586        while (false !== ($myrow = $this->db->fetchArray($result))) {
587            $block = new XoopsBlock();
588            $block->assignVars($myrow);
589            if (!$id_as_key) {
590                $ret[] =& $block;
591            } else {
592                $ret[$myrow['bid']] = &$block;
593            }
594            unset($block);
595        }
596
597        return $ret;
598    }
599
600    /**
601     * get a list of blocks matchich certain conditions
602     *
603     * @param  CriteriaElement $criteria conditions to match
604     * @return array  array of blocks matching the conditions
605     **/
606    public function getList(CriteriaElement $criteria = null)
607    {
608        $blocks = $this->getObjects($criteria, true);
609        $ret    = array();
610        foreach (array_keys($blocks) as $i) {
611            $name    = (!$blocks[$i]->isCustom()) ? $blocks[$i]->getVar('name') : $blocks[$i]->getVar('title');
612            $ret[$i] = $name;
613        }
614
615        return $ret;
616    }
617
618    ##################### Deprecated Methods ######################
619
620    /**#@+
621     * @deprecated
622     * @param      $moduleid
623     * @param bool $asobject
624     * @param bool $id_as_key
625     * @return bool
626     */
627    public function getByModule($moduleid, $asobject = true, $id_as_key = false)
628    {
629        trigger_error(__CLASS__ . '::' . __FUNCTION__ . ' is deprecated', E_USER_WARNING);
630
631        return false;
632    }
633
634    /**
635     * @param        $groupid
636     * @param int    $module_id
637     * @param bool   $toponlyblock
638     * @param null   $visible
639     * @param string $orderby
640     * @param int    $isactive
641     *
642     * @return bool
643     */
644    public function getAllByGroupModule($groupid, $module_id = 0, $toponlyblock = false, $visible = null, $orderby = 'i.weight,i.instanceid', $isactive = 1)
645    {
646        trigger_error(__CLASS__ . '::' . __FUNCTION__ . ' is deprecated', E_USER_WARNING);
647
648        return false;
649    }
650
651    /**
652     * @param        $groupid
653     * @param string $orderby
654     *
655     * @return bool
656     */
657    public function getAdminBlocks($groupid, $orderby = 'i.weight,i.instanceid')
658    {
659        trigger_error(__CLASS__ . '::' . __FUNCTION__ . ' is deprecated', E_USER_WARNING);
660
661        return false;
662    }
663
664    /**
665     * @return bool
666     */
667    public function assignBlocks()
668    {
669        trigger_error(__CLASS__ . '::' . __FUNCTION__ . ' is deprecated', E_USER_WARNING);
670
671        return false;
672    }
673    /**#@-*/
674}
675