<?php
/**
 * @version $Id: Category.class.php 679 2012-08-20 12:41:35Z hodaka $
 * @package myuploader
 */

if (!defined('XOOPS_ROOT_PATH')) exit();

class Myuploader_CategoryObject extends XoopsSimpleObject
{
    var $mCatViewGroups = null;
    var $mCatUploadGroups = null;
    var $mCatHtmlAllowedGroups = null;
    var $mParentIds = null;
    var $mDeleteRelatedImagesFlag = true;

    /**
     * @public
     */
    function Myuploader_CategoryObject()
    {
        $this->initVar('category_id', XOBJ_DTYPE_INT, '0', false);
        $this->initVar('cat_name', XOBJ_DTYPE_STRING, '', false, 100);
        $this->initVar('cat_description', XOBJ_DTYPE_TEXT, '', false);
        $this->initVar('cat_maxsize', XOBJ_DTYPE_INT, '100', false);
        $this->initVar('cat_maxlength', XOBJ_DTYPE_INT, '1024', false);
        $this->initVar('cat_resizelength', XOBJ_DTYPE_INT, '600', false);
        $this->initVar('cat_thumblength', XOBJ_DTYPE_INT, '140', false);
        $this->initVar('cat_active', XOBJ_DTYPE_BOOL, '1', false);
        $this->initVar('cat_weight', XOBJ_DTYPE_INT, '0', false);
        $this->initVar('cat_pid', XOBJ_DTYPE_INT, '0', false);
    }

}

class Myuploader_CategoryHandler extends XoopsObjectGenericHandler
{
    var $mTable = '{dirname}_category';
    var $mPrimary = 'category_id';
    var $mClass = 'Myuploader_CategoryObject';
    var $mDirname = null;
    var $mModuleGlobal = null;
    var $mAssetManager = null;

    /**
     * Myuploader_CategoryHandler
     *
     * @param   XoopsDatabase  &$db
     * @param   string  $dirname
     *
     * @return  void
     *
     * @public
    **/
    function Myuploader_CategoryHandler(&$db, $dirname)
    {
        $this->mTable = str_replace('{dirname}', $dirname, $this->mTable);
        parent::XoopsObjectGenericHandler($db);

        $this->mDirname = $dirname;
        $this->mAssetManager =& Myuploader_AssetManager::getInstance($dirname);
        XCube_DelegateUtils::call('Module.myuploader.Event.GetModuleGlobal', new XCube_Ref($this->mModuleGlobal), $dirname);
    }

    function getChildTreeArray($id=0, $name='', $as_object=false, $array=array(), $prefix='') {
        $allCategories =& $this->mModuleGlobal->getAllCategories();
        if(!count($allCategories))
            return $array;

        switch($name) {
            case 'view':
                $categories =& $this->mModuleGlobal->getViewable();
                break;
            case 'upload':
                $categories =& $this->mModuleGlobal->getUploadable();
                break;
            default:
                $categories = array_keys($allCategories);
                break;
        }

        foreach($categories as $cid) {
            $category =& $allCategories[$cid];
            if($category->get('cat_pid') == $id) {
                if($as_object) {
                    $category->set('cat_name', $prefix.$category->get('cat_name'));
                    $array[$cid] = $category;
                    $array[$cid] = $prefix.$category->get('cat_name');
                } else {
                    $array[$cid] = $prefix.$category->get('cat_name');
                }
                $array = $this->getChildTreeArray($cid, $name, $as_object, $array, $prefix.'--');

            }
        }
        return $array;
    }

    function getChildIds($cat_id=0, $all_children=true, $perm_check=true, $array=array()) {
        $allCategories =& $this->mModuleGlobal->getAllCategories();
        if(!count($allCategories))
            return $array;

        foreach($allCategories as $id=>$category) {
            if($category->get('cat_pid') == $cat_id) {
                if(!$perm_check || in_array($id, $this->mModuleGlobal->getViewable())) {
                    $array[] = $id;

                    if($all_children) {
                        $array = $this->getChildIds($id, $all_children, $perm_check, $array);
                    }
                }
            }
        }

        return $array;
    }

    function getAllParentIds($pid=0, $array=array()) {
        $allCategories =& $this->mModuleGlobal->getAllCategories();
        if(!count($allCategories))
            return $array;
        if(empty($pid))
            return $array;

        if(in_array($pid, array_keys($allCategories))) {
            $array[] = $pid;
            $array = $this->getAllParentIds($allCategories[$pid]->get('cat_pid'), $array);
        }

        return $array;
    }

    function renderCategoryTree($include_children=true, $sel_id=0, $tree='', $depth=0) {
        $allCategories =& $this->mModuleGlobal->getAllCategories();
        $depth++;

        $classselecter = ($depth == 1)? 'myuploaderBlockCategory' : 'myuploaderBlockCatChild';
        $tree .= "\n".str_pad('', ($depth - 1) * 2, "\t").'<ul class="'.$classselecter.'">'."\n";
        foreach($allCategories as $id => $category) {
            if(in_array($id, $this->mModuleGlobal->getViewable()) && $category->get('cat_pid') == $sel_id) {
                $count =& $this->_getCountByCategory($id, $include_children);
                $tree .= str_pad('', ($depth - 1) * 2 + 1, "\t").'<li><a href="'.sprintf("%s/modules/%s/index.php?op=ImageList&amp;category_id=%d", XOOPS_URL, $this->mDirname, intval($id)).'">'.$category->getShow('cat_name').'</a>('.$count.')';
                if($this->_hasChild($id)) {
                    $tree = $this->renderCategoryTree($include_children, $id, $tree, $depth);
                    $tree .= str_pad('', ($depth - 1) * 2 + 1, "\t");
                }
                $tree .= '</li>'."\n";
            }
        }
        $tree .= str_pad('', ($depth - 1) * 2, "\t").'</ul>'."\n";
        return $tree;
    }

    function _getCountByCategory($sel_id, $include_children=true) {
        static $countByCid;

        if(!isset($countByCid)) {
            $handler =& $this->mAssetManager->getObject('handler', 'image');
            $criteria = new criteriaCompo();
            $sql = sprintf('SELECT category_id, count(image_id) as count FROM %s ', $handler->mTable);

            $where = '';

            // filter
            $uid = isset($_GET['uid'])? intval($_GET['uid']) : 0;
            if(!empty($uid)) {
                $where .= " image_uid = $uid";
            }

            if(!empty($where)) {
                $sql .= ' WHERE '.$where;
            }

            $sql .= ' GROUP BY category_id ORDER BY category_id';
            $root = XCube_Root::getSingleton();
            $result = $root->mController->mDB->query($sql);

            $countByCid = array();
            $counts = array();
            if($result) {
                while(list($cid, $count) = $root->mController->mDB->fetchRow($result)) {
                    $counts[$cid] = intval($count);
                }
            }

            $allCategories =& $this->mModuleGlobal->getAllCategories();
            foreach($allCategories as $key=>$obj) {
                if(!in_array($key, array_keys($counts))) {
                    $countByCid[$key] = 0;
                } else {
                    $countByCid[$key] = $counts[$key];
                }
            }
        }

        // return summary of this children
        if(!$include_children) {
            if(isset($countByCid[$sel_id]))
                return $countByCid[$sel_id];
            else
                return 0;
        } else {
            $ids = $this->getChildIds(intval($sel_id));
            $ids[] = intval($sel_id);
            $return = 0;
            foreach($ids as $id) {
                if(in_array($id, $this->mModuleGlobal->getViewable())) {
                    $return += $countByCid[$id];
                }
            }
            return $return;
        }
    }

    function _hasChild($catid) {
        $allCategories =& $this->mModuleGlobal->getAllCategories();
        foreach($allCategories as $id=>$category) {
            if(in_array($id, $this->mModuleGlobal->getViewable()) && $category->get('cat_pid') == $catid) {
                return true;
            }
        }

        return false;
    }

    function delete(&$obj, $force=false) {
        // first children
        $children = $this->getChildIds($obj->get('category_id'), false, false);

        // delete children
        foreach($children as $child) {
            if(!$this->delete($child, $force)) {
                return false;
            }
        }

        // delete images
        if($obj->mDeleteRelatedImagesFlag) {
            $image_handler =& $this->mAssetManager->getObject('handler', 'image');
            if(!$image_handler->deleteByCategory($obj->get('category_id'), $force)) {
               return false;
            }
        }

        // delete group permission
        $gperm_handler =& xoops_gethandler('groupperm');
        $criteria = new criteriaCompo(new criteria('gperm_modid', $this->mModuleGlobal->mXoopsModule->get('mid')));
        $criteria->add(new criteria('gperm_itemid', $obj->get('category_id')));
        $criteria->add(new criteria('gperm_name', '("cat_view", "cat_upload", "html_allowed")', 'IN'));

        if(!$gperm_handler->deleteAll($criteria)) {
            return false;
        }
        unset($criteria);

        // and finally delete self
        if(!parent::delete($obj, $force)) {
            return false;
        }
        return true;
    }

    function deletes($criteria=null, $force=false) {
        if(empty($criteria)) {
            $criteria = new criteriaCompo();
        }
        $sql = "DELETE FROM `" . $this->mTable . "` WHERE " . $criteria->render();

        return $force ? $this->db->queryF($sql) : $this->db->query($sql);
    }

    function &getObjects($criteria=null, $id_as_key=false)
    {
        $ret = array();

        $sql = "SELECT * FROM `" . $this->mTable . '`';

        if($criteria !== null && is_a($criteria, 'CriteriaElement')) {
            $where = $this->_makeCriteria4sql($criteria);

            if (trim($where)) {
                $sql .= " WHERE " . $where;
            }

            $sorts = array();
            foreach ($criteria->getSorts() as $sort) {
                $sorts[] = '`' . $sort['sort'] . '` ' . $sort['order'];
            }
            if ($criteria->getSort() != '') {
                $sql .= " ORDER BY " . implode(',', $sorts);
            }

            $limit = $criteria->getLimit();
            $start = $criteria->getStart();
        }
        else {
            $limit = 0;
            $start = 0;
        }

        $result = $this->db->query($sql, $limit, $start);

        if (!$result) {
            return $ret;
        }

        while($row = $this->db->fetchArray($result)) {
            $obj = new $this->mClass();
            $obj->assignVars($row);
            $obj->unsetNew();

            if ($id_as_key) {
                $ret[$obj->get($this->mPrimary)] =& $obj;
            }
            else {
                $ret[]=&$obj;
            }

            unset($obj);
        }

        return $ret;
    }

}

?>