e107inc/e107

View on GitHub
e107_plugins/featurebox/e_shortcode.php

Summary

Maintainability
A
30 mins
Test Coverage
C
75%
<?php
/*
* Copyright (c) e107 Inc e107.org, Licensed under GNU GPL (http://www.gnu.org/licenses/gpl.txt)
*
* Featurebox shortcode batch class - shortcodes available site-wide. ie. equivalent to multiple .sc files.
*/

if (!defined('e107_INIT')) { exit; }

e107::includeLan(e_PLUGIN.'featurebox/languages/'.e_LANGUAGE.'_front_featurebox.php');


class featurebox_shortcodes// must match the plugin's folder name. ie. [PLUGIN_FOLDER]_shortcodes
{    
    protected $_categories = array();
    
    /**
     * Available parameters (GET string format)
     * - cols (integer): number of items per column, default 1
     * - no_fill_empty (boolean): don't fill last column with empty items (if required), default 0
     * - tablestyle (string): mode to be used with <code>tablerender()</code>, default 'featurebox'
     * - notablestyle (null): if isset - disable <code>tablerender()</code>
     * - force (boolean): force category model load , default false
     * - ids (string): comma separated id list - load specific featurebox items, default empty 
     * 
     * @param string $parm parameters
     * @param string $mod category template
     * @example {FEATUREBOX=cols=2|tabs}
     */
    function sc_featurebox($parm=null, $mod = '')
    {

        if($parm == null && $mod == '') // ie {FEATUREBOX}
        {
            $menCat = e107::getPlugPref('featurebox','menu_category');
            $type     = vartrue($menCat,'bootstrap_carousel');
            $text = e107::getParser()->parseTemplate("{FEATUREBOX|".$type."}");
            
            return $text;
        }
        
        // TODO cache
        if(!e107::isInstalled('featurebox')) //just in case
        {
            return '';
        }
        
        if(!$mod)
        {
            $ctemplate = 'default';
    
        }
        else
        {
            $ctemplate = $mod;
        }

        if(is_string($parm))
        {
            parse_str($parm, $parm);
        }
        
        $category = $this->getCategoryModel($ctemplate, (vartrue($parm['force']) ? true : false));
        $defopt = array(
            'force' => 0,
            'no_fill_empty' => 0,
            'tablestyle' => 'featurebox',
            'cols' => 1,    
            'ids' => '',
            'notablestyle' => null
        );
        // reset to default, update current
        $category->setParams($defopt)
            ->updateParams($parm);

        if(!$category->hasData())
        {
            
            return '';
        }
        
        $tmpl = $this->getFboxTemplate($ctemplate);
        
        
        $type = vartrue($tmpl['js_type'],''); // Legacy support (prototype.js)
        
        if(vartrue($tmpl['js']))
        {        
            $tmp = explode(',', $tmpl['js']);
            
            foreach($tmp as $file)
            {
                e107::js('footer',$file,$type);    
            }
        }
        
        $tp = e107::getParser();
                
        if(vartrue($tmpl['js_inline']))
        {
            $data = $tp->toText($category->getData('fb_category_parms'));
            $jsInline = str_replace("{FEATUREBOX_PARMS}","{".trim($data)."}",$tmpl['js_inline']);
            e107::js('footer-inline', $jsInline, $type, 3);
        }
                
    
        
        // Fix - don't use tablerender if no result (category could contain hidden items)
        $ret = $this->render($category, $ctemplate, $parm);
        if(empty($ret))
        {
            e107::getMessage()->addDebug('Featurebox returned nothing.')->addDebug('Category: '.print_a($category,true))->addDebug('Template: '.$ctemplate)->addDebug('Param: '.print_a($parm,true));
            return '';
        }
        
        $ret = $tp->parseTemplate($tmpl['list_start'], true, $category).$ret.$tp->parseTemplate($tmpl['list_end'], true, $category);
        if(isset($parm['notablestyle']))
        {
            return $ret;
        }
        
        return e107::getRender()->tablerender(LAN_PLUGIN_FEATUREBOX_NAME, $ret, vartrue($parm['tablestyle'], 'featurebox'), true);
    }
    
    /**
     * Render featurebox navigation
     * Available parameters (GET string format)
     * - loop (boolean): loop using 'nav_loop' template, default 0
     * - base (string): template key prefix, default is 'nav'. Example: 'mynav' base key will search templates 'mynav_start', 'mynav_loop', 'mynav_end'.
     * - nolimit (boolean): ignore 'limit' field , use 'total' items number for navigation looping
     * - uselimit (boolean): ignore 'limit' field , use 'total' items number for navigation looping
     * 
     * @param string $parm parameters
     * @param string $mod category template
     */
    function sc_featurebox_navigation($parm=null, $mod = '')
    {
        // TODO cache    
        //TODO default $parm values. eg. assume 'tabs' when included in the 'tabs' template.     
        
        if(!e107::isInstalled('featurebox')) //just in case
        {
            return '';
        }
        
        if(!$mod)
        {
            $ctemplate = 'default';
        }
        else
        {
            $ctemplate = $mod;
        }
        parse_str((string) $parm, $parm);
        
        $category = $this->getCategoryModel($ctemplate); 
        
        if(!$category->hasData())
        {
            return '';
        }
        $tree = $category->getItemTree();
        if($tree->isEmpty())
        {
            return '';
        }
        $tmpl = $this->getFboxTemplate($ctemplate);
        
        if($category->get('fb_category_random'))
        {
            unset($parm['loop']);
        }
        
        $base = vartrue($parm['base'], 'nav').'_';
        $tree_ids = array_keys($tree->getTree()); //all available item ids
        
        
        
        $ret = $category->toHTML(varset($tmpl[$base.'start']), true); 
        $cols = $category->getParam('cols', 1);
        
        if(isset($parm['loop']) && $tree->getTotal() > 0 && vartrue($tmpl[$base.'item']))
        {
            // loop for all
            if(isset($parm['nolimit'])) 
            {
                $total = $tree->getTotal();
            }
        
            // loop for limit number
            elseif(isset($parm['uselimit'])) 
            {
                $total = $category->sc_featurebox_category_limit() ? intval($category->sc_featurebox_category_limit()) : $tree->getTotal();
                if($total > $tree->getTotal())
                {
                    $total = $tree->getTotal();
                }
            }
            // default - number based on all / limit (usefull for ajax navigation)
            else 
            { 
                $total = ceil($tree->getTotal() / ($category->sc_featurebox_category_limit() ? intval($category->sc_featurebox_category_limit()) : $tree->getTotal()) );
            }
            if($cols > 1)
            {
                $total = ceil($total / $cols);
            }
                

            $model = clone $category;
            $item = new plugin_featurebox_item();
            $tmp = array();
            
            for ($index = 1; $index <= $total; $index++)
            {
                
                $nodeid = varset($tree_ids[($index - 1) * $cols], 0); 
                if($nodeid && $tree->hasNode($nodeid))
                {
                    
                    $model->setParam('counter', $index)
                        ->setParam('total', $total)
                        ->setParam('active', $index == varset($parm['from'], 1));
                        
                    $node = $tree->getNode($nodeid);
                    
                    e107::getScParser()->resetScClass('plugin_featurebox_category', $model);
                    $node->setCategory($model)
                        ->setParam('counter', $index)
                        ->setParam('total', $total)
                        ->setParam('limit', $category->get('fb_category_limit'))
                        ;
    
                    $tmp[] = $node->toHTML($tmpl[$base.'item'], true); 
                    continue;
                }
                
                e107::getScParser()->resetScClass('plugin_featurebox_item', $item);
                $tmp[] = $model->setParam('counter', $index)
                    ->setParam('active', $index == varset($parm['from'], 1))
                    ->toHTML($tmpl[$base.'item'], true);
            } 
            $ret .= implode(varset($tmpl[$base.'separator']), $tmp);
            unset($model, $tmp);
        }
        $ret .= $category->toHTML(varset($tmpl[$base.'end']), true);
        
        // Moved to 'sc_featurebox' - as it wouldn't load js if navigation was not used. 
        /*
        $type = vartrue($tmpl['js_type'],''); // Legacy support (prototype.js)
        
        if(vartrue($tmpl['js']))
        {        
            $tmp = explode(',', $tmpl['js']);
            
            foreach($tmp as $file)
            {
                e107::js('footer',$file,$type);    
            }
        }
                
        if(vartrue($tmpl['js_inline']))
        {
            e107::js('inline',$tmpl['js_inline'],$type,3);
            // e107::getJs()->footerInline($tmpl['js_inline'], 3);
        }
        
        if(vartrue($tmpl['css']))
        {        
            $tmp = explode(',', $tmpl['css']);
            foreach($tmp as $file)
            {
                e107::css('url',$file,$type);    
            }
        }
        */
        return $ret;
    }
    
    /**
     * Get & Render featurebox items (custom)
     * Available parameters (GET string format)
     * - cols (integer): number of items per column, default 1
     * - no_fill_empty (boolean): don't fill last column with empty items (if required), default 0
     * - from (integer): start load at
     * - limit (integer): load to
     * 
     * @param string $parm parameters
     * @param string $mod category template
     */
    function sc_featurebox_items($parm=null, $mod = '')
    {
        // TODO cache
        if(!e107::isInstalled('featurebox')) //just in case
        {
            return '';
        }
        
        if(!$mod)
        {
            $ctemplate = 'default';
        }
        else
        {
            $ctemplate = $mod;
        }

        if(!empty($parm))
        {
            parse_str($parm, $parm);
        }
        
        $category = clone $this->getCategoryModel($ctemplate);
        if(!$category->hasData())
        {
            return '';
        }
        return $this->render($category, $ctemplate, $parm);
    }
    
    /**
     * Render featurebox list
     * @param plugin_featurebox_category $category
     * @param string $ctemplate category template
     * @param array $parm
     */
    public function render($category, $ctemplate, $parm)
    {
        $tmpl = $this->getFboxTemplate($ctemplate);
        $cols = intval(vartrue($parm['cols'], 1));
        $limit = intval(varset($parm['limit'], $category->sc_featurebox_category_limit()));
        $from = (intval(vartrue($parm['from'], 1)) - 1) * $limit;
        $category->setParam('cols', $cols)
            ->setParam('no_fill_empty', isset($parm['no_fill_empty']) ? 1 : 0)
            ->setParam('limit', $limit)
            ->setParam('from', $from);
            
        $tree = $category->getItemTree(true); 
        if($tree->isEmpty())
        {
            return '';
        }
        
        $total = $tree->getTotal();
        $category->setParam('total', $total);
        $counter = 1;
        $col_counter = 1;
        $cols_counter = 1; // column counter
        $ret = '';
        
        foreach ($tree->getTree() as $id => $node) 
        {
            $tmpl_item = e107::getTemplate('featurebox', 'featurebox', $node->get('fb_template'));
            if(!$tmpl_item) 
            {
                $tmpl_item = e107::getTemplate('featurebox', 'featurebox', 'default', true, true);
            }
            
            // reset column counter
            if($col_counter > $cols)
            {
                $col_counter = 1;
            }
            
            // item container (category template)
            $tmpl_item = $tmpl['item_start'].$tmpl_item.$tmpl['item_end'];

            // add column start
            if(1 == $col_counter && vartrue($tmpl['col_start']))
            {
                $tmpl_item = $tmpl['col_start'].$tmpl_item;
            }
            
            // there is more
            if(($total - $counter) > 0)
            {
                // add column end if column end reached
                if($cols == $col_counter && vartrue($tmpl['col_end']))
                {
                    $tmpl_item .= $tmpl['col_end'];
                }
                // else add item separator
                elseif($cols != $col_counter && 1 != $col_counter)
                {
                    $tmpl_item .= $tmpl['item_separator'];
                }
            }
            // no more items - clean & close
            else
            {
                $empty_cnt = $cols - $col_counter;
                if($empty_cnt > 0 && !$category->getParam('no_fill_empty'))
                {
                    // empty items fill
                    $tmp = new plugin_featurebox_item();
                    $tmp->setCategory($category);
                    $tmp_tmpl_item = $tmpl['item_separator'].$tmpl['item_start'].varset($tmpl['item_empty'], '<div><!-- --></div>').$tmpl['item_end'];
                    for ($index = 1; $index <= $empty_cnt; $index++) 
                    {
                        $tmpl_item .= $tmp->setParam('counter', $counter + $index)
                            ->setParam('cols', $cols)
                            ->setParam('col_counter', $col_counter + $index)
                            ->setParam('cols_counter', $cols_counter)
                            ->setParam('limit', $category->get('fb_category_limit'))
                            ->setParam('total', $total)
                            ->toHTML($tmp_tmpl_item);
                    }
                    unset($tmp, $tmp_tmpl_item);
                }
                // add column end
                $tmpl_item .= varset($tmpl['col_end']);
            }
            
            $ret .= $node->setParam('counter', $counter)
                ->setParam('cols', $cols)
                ->setParam('col_counter', $col_counter)
                ->setParam('cols_counter', $cols_counter)
                ->setParam('limit', $category->get('fb_category_limit'))
                ->setParam('total', $total)
                ->setCategory($category)
                ->toHTML($tmpl_item);
            
            if($cols == $col_counter)
            {
                $cols_counter++;
            }
            
            $counter++;
            $col_counter++;
        }
        return $ret;
    }
    
    /**
     * Retrieve template array by category
     * 
     * @param string $ctemplate
     * @return array
     */
    public function getFboxTemplate($ctemplate)
    {
        $tmpl = e107::getTemplate('featurebox', 'featurebox_category', $ctemplate, 'front');  
        if(!$tmpl && e107::getTemplate('featurebox', 'featurebox_category', $ctemplate, false))
        {
            $tmpl = e107::getTemplate('featurebox', 'featurebox_category', $ctemplate, false); // plugin template
        }
        elseif(!$tmpl && e107::getTemplate('featurebox', 'featurebox_category', 'default'))
        {
            $tmpl = e107::getTemplate('featurebox', 'featurebox_category', 'default'); // theme/plugin default template
        }
        elseif(!$tmpl)
        {
            $tmpl = e107::getTemplate('featurebox', 'featurebox_category', 'default', false); //plugin default
        }
        return $tmpl;
    }
    
    /**
     * Get category model by template
     * @param string $template
     * @return plugin_featurebox_category
     */
    public function getCategoryModel($template, $force = false)
    {
        
        if(!isset($this->_categories[$template]))
        {        
            $this->_categories[$template] = new plugin_featurebox_category();
            $this->_categories[$template]->loadByTemplate($template, $force);
        }
        return $this->_categories[$template];
    }
}