}
//load module
$module = CMS_modulesCatalog::getByCodename($codename);
if (!$module) {
    CMS_grandFather::raiseError('Unknown module or module for codename : ' . $codename);
    $view->show();
}
//CHECKS user has module clearance
if (!$cms_user->hasModuleClearance($codename, CLEARANCE_MODULE_EDIT)) {
    CMS_grandFather::raiseError('User has no rights on module : ' . $codename);
    $view->setActionMessage($cms_language->getmessage(MESSAGE_ERROR_MODULE_RIGHTS, array($module->getLabel($cms_language))));
    $view->show();
}
//get queried module categories
$attrs = array("module" => $codename, "language" => $cms_language, "level" => $rootId, "root" => $rootId ? false : 0, "attrs" => false, "cms_user" => $cms_user);
$categories = CMS_module::getModuleCategories($attrs);
$nodes = array();
foreach ($categories as $category) {
    $parentRight = sensitiveIO::isPositiveInteger($category->getAttribute('parentID')) ? $cms_user->hasModuleCategoryClearance($category->getAttribute('parentID'), CLEARANCE_MODULE_MANAGE) : $cms_user->hasModuleClearance($codename, CLEARANCE_MODULE_EDIT);
    $categoryRight = $cms_user->hasModuleCategoryClearance($category->getID(), CLEARANCE_MODULE_MANAGE);
    $hasSiblings = $category->hasSiblings();
    $qtip = $category->getIconPath(false, PATH_RELATIVETO_WEBROOT, true) ? '<img style="max-width:280px;" src="' . $category->getIconPath(true) . '" /><br />' : '';
    $qtip .= $category->getDescription() ? $category->getDescription() . '<br />' : '';
    if ($category->isProtected()) {
        $qtip .= '<strong>' . $cms_language->getMessage(MESSAGE_CATEGORY_PROTECTED) . ' : </strong>' . $cms_language->getMessage(MESSAGE_CATEGORY_PROTECTED_DESC) . '<br />';
    }
    $qtip .= 'ID : ' . $category->getID();
    $nodes[] = array('id' => 'cat' . $category->getID(), 'catId' => $category->getID(), 'text' => ($category->isProtected() ? '<span style="color:grey;"' . ($qtip ? ' ext:qtip="' . io::htmlspecialchars($qtip) . '"' : '') . '>' : '') . $category->getLabel() . ($category->isProtected() ? '</span>' : ''), 'leaf' => !$hasSiblings, 'qtip' => $qtip ? $qtip : false, 'draggable' => $parentRight && !$category->isProtected(), 'allowDrop' => $categoryRight, 'allowChildren' => true, 'disabled' => !$categoryRight, 'deletable' => $categoryRight && !$hasSiblings && !$category->isProtected() && !$module->isCategoryUsed($category), 'manageable' => $categoryRight, 'expanded' => sizeof($category->getLineageStack()) < $maxDepth, 'protected' => $category->isProtected() && !$cms_user->hasAdminClearance(CLEARANCE_ADMINISTRATION_EDITVALIDATEALL));
}
$view->setContent($nodes);
$view->show();
 /** 
  * Recursive function to build the categories tree.
  *
  * @param CMS_moduleCategory $category
  * @param integer $count, to determine category in-tree depth
  * @return string HTML formated
  */
 function build_category_tree_options($category, $count)
 {
     global $codename, $cms_language, $parentCategory, $cms_module, $cms_user, $catId;
     //if category is not itself (to avoid infinite loop in lineage)
     $a = array();
     if ($category->getID() != $catId) {
         $category->setAttribute('language', $cms_language);
         $label = htmlspecialchars($category->getLabel());
         if ($count >= 1) {
             $label = str_repeat(' ::', $count) . ' ' . $label;
         }
         $a[] = array($category->getID(), $label);
         $count++;
         $attrs = array("module" => $codename, "language" => $cms_language, "level" => $category->getID(), "root" => -1, "cms_user" => $cms_user, "clearanceLevel" => CLEARANCE_MODULE_MANAGE, "strict" => true);
         $siblings = CMS_module::getModuleCategories($attrs);
         if (sizeof($siblings)) {
             foreach ($siblings as $aSibling) {
                 $aSibling->setAttribute('language', $cms_language);
                 $a = array_merge($a, build_category_tree_options($aSibling, $count));
             }
         }
     }
     return $a;
 }
 /**
  * Returns each category ID and label in a module given user can see
  *
  * @access public
  * @param CMS_profile $cms_user, the profile concerned by these restrictions
  * @param string $cms_module, the module codename
  * @param CMS_language $cms_language, the language of the labels
  * @param mixed $clearanceLevel 
  * - false : CLEARANCE_MODULE_VIEW
  * - true : CLEARANCE_MODULE_EDIT
  * - constant value : clearanceLevel value
  * @param boolean $strict return only categories from this clearance (default : false, else, return complete categories tree until given clearance)
  * @return array(string) the statements or false if profile hasn't any access to any categories
  * @static
  */
 function getSiblingCategoriesAsArray(&$category, $count, &$cms_user, $cms_module, $cms_language, $clearanceLevel = false, $strict = false)
 {
     $count++;
     $attrs = array("module" => $cms_module, "language" => $cms_language, "level" => $category->getID(), "root" => false, "cms_user" => &$cms_user, "clearanceLevel" => $clearanceLevel, "strict" => $strict);
     $siblings = CMS_module::getModuleCategories($attrs);
     if (is_array($siblings) && $siblings) {
         $ctgs = array();
         foreach ($siblings as $obj) {
             $ctgs[$obj->getID()] = str_repeat('-&nbsp;', $count) . '' . io::htmlspecialchars($obj->getLabel());
             if (false !== ($a_sibling = CMS_moduleCategories_catalog::getSiblingCategoriesAsArray($obj, $count, $cms_user, $cms_module, $cms_language, $clearanceLevel, $strict))) {
                 while (list($id, $lbl) = each($a_sibling)) {
                     if ($id) {
                         $ctgs[$id] = $lbl;
                     }
                 }
             }
         }
         if (is_array($ctgs) && $ctgs) {
             return $ctgs;
         }
     }
     return false;
 }
    /** 
     * Recursive function to build items tree.
     *
     * @param mixed $items : current category or page
     * @param integer $count, to determine item in-tree depth
     * @param integer $parent_clearance, immediate parent item clearance
     * @return string HTML formated
     */
    function build_items_tree(&$item, $count, $parent_clearance)
    {
        global $moduleCodename, $cms_language, $cms_user, $profileId, $hash;
        //current user environment
        global $items_ids;
        //reference to all displayed items
        global $modules_clearances, $stack_clearances;
        //all clearances types available
        global $maxDepth, $clearance_colors;
        //displaying options
        global $disableFields;
        //disable status
        $s = '';
        $count++;
        // Current category clearance
        $i_default_clearance = $stack_clearances->getElementValueFromKey($item->getID());
        // Thig hidden but sets current category clearance identical
        // to its parent's one, used to hide some checkboxes
        $i_current_clearance = $i_default_clearance !== false ? (int) $i_default_clearance : $parent_clearance;
        if ($i_default_clearance !== false) {
            $bgColor = ' style="background-color:' . $clearance_colors[$i_default_clearance] . ';"';
        } elseif (!$i_default_clearance && $item->isRoot()) {
            $bgColor = ' style="background-color:' . $clearance_colors[CLEARANCE_MODULE_NONE] . ';"';
        } else {
            $bgColor = '';
        }
        $items_ids[] = $item->getID();
        if (is_a($item, 'CMS_moduleCategory')) {
            $hasSiblings = $item->hasSiblings();
        } else {
            $hasSiblings = CMS_tree::hasSiblings($item);
        }
        //Link to sub categories
        if ($hasSiblings) {
            if ($count < $maxDepth) {
                $thumbnail = '';
            } else {
                $thumbnail = '<a href="#" onclick="Automne.categories.open(' . $item->getID() . ', \'' . $hash . '\', this);return false;" title="ID : ' . $item->getID() . '">+</a>';
            }
        } else {
            $thumbnail = '';
        }
        //disabled checkboxes if needed
        if ($disableFields) {
            $disabled = ' disabled="disabled"';
        } else {
            //check if user has edition rights on item
            if (is_a($item, 'CMS_moduleCategory')) {
                $disabled = $cms_user->hasModuleCategoryClearance($item->getID(), CLEARANCE_MODULE_MANAGE) ? '' : ' disabled="disabled"';
            } else {
                $disabled = $cms_user->hasPageClearance($item->getId(), CLEARANCE_PAGE_EDIT) ? '' : ' disabled="disabled"';
            }
        }
        $label = is_a($item, 'CMS_moduleCategory') ? $item->getLabel() : $item->getTitle();
        $label = $disabled ? '<span style="color:grey;">' . $label . '</span>' : $label;
        // Get title and form actions
        $s .= '
			<li' . $bgColor . ' id="li-' . $hash . '-' . $item->getID() . '">
				<table border="0" cellpadding="0" cellspacing="0"' . $bgColor . ' onMouseOver="Automne.categories.onRow(this);" onMouseOut="Automne.categories.outRow(this);">
					<tr>
						<td width="100%">&nbsp;' . $thumbnail . '<span title="ID : ' . $item->getID() . '">' . $label . '</span></td>
						<td width="120">
							<table width="120" border="0" cellpadding="0" cellspacing="0" id="checkboxes-' . $hash . '-' . $item->getID() . '">
								<tr>';
        @reset($modules_clearances);
        while (list($msg, $value) = @each($modules_clearances)) {
            $sel = '';
            //check if user has edition rights on item
            if ($disableFields) {
                $disabled = ' disabled="disabled"';
            } else {
                if (is_a($item, 'CMS_moduleCategory')) {
                    $disabled = $cms_user->hasModuleCategoryClearance($item->getID(), CLEARANCE_MODULE_MANAGE) ? '' : ' disabled="disabled"';
                } else {
                    $disabled = $cms_user->hasPageClearance($item->getId(), CLEARANCE_PAGE_EDIT) ? '' : ' disabled="disabled"';
                }
            }
            if ($item->isRoot() || !$item->isRoot() && $parent_clearance !== $value) {
                // If none clearance defined yet, access is denied to any root category
                if (!$i_default_clearance && $value === CLEARANCE_MODULE_NONE && $item->isRoot() || $i_default_clearance !== false && (int) $i_default_clearance === $value) {
                    $sel = ' checked="checked"';
                }
                $s .= '<td width="30" align="center"><input type="checkbox"' . $disabled . ' onclick="Automne.categories.unselectOthers(\'' . $item->getID() . '\',\'' . $value . '\', \'' . $count . '\', \'' . $hash . '\');" id="check-' . $hash . '-' . $item->getID() . '_' . $value . '" name="cat' . $item->getID() . '" value="' . $value . '"' . $sel . $disabled . ' /></td>';
            } else {
                $s .= '<td width="30" align="center"><input type="checkbox"' . $disabled . ' onclick="Automne.categories.unselectOthers(\'' . $item->getID() . '\',\'' . $value . '\', \'' . $count . '\', \'' . $hash . '\');" id="check-' . $hash . '-' . $item->getID() . '_' . $value . '" name="cat' . $item->getID() . '" value="' . $value . '" style="display:none;"' . $disabled . ' /></td>';
            }
        }
        $s .= '					</tr>
							</table>
						</td>
					</tr>
				</table>';
        // Print siblings tree recursivly
        if ($hasSiblings) {
            if ($count < $maxDepth) {
                //get siblings
                if (is_a($item, 'CMS_moduleCategory')) {
                    $attrs = array("module" => $moduleCodename, "language" => $cms_language, "level" => $item->getID(), "root" => false, "attrs" => false, "cms_user" => &$cms_user);
                    $siblings = CMS_module::getModuleCategories($attrs);
                } else {
                    $siblings = CMS_tree::getSiblings($item);
                }
                // Prepare form actions here
                if (is_array($siblings) && $siblings) {
                    $s .= '<ul id="ul-' . $hash . '-' . $item->getID() . '">';
                    foreach ($siblings as $aSibling) {
                        if (is_a($item, 'CMS_moduleCategory')) {
                            $aSibling->setAttribute('language', $cms_language);
                        }
                        $s .= build_items_tree($aSibling, $count, $i_current_clearance);
                    }
                    $s .= '</ul>';
                }
            }
        }
        $s .= '</li>';
        return $s;
    }