Loading...
 

Category did not allow for proper edits.. (Fixed and submitted updates)

Status
Closed
Subject
Category did not allow for proper edits.. (Fixed and submitted updates)
Category
  • Usability
  • Patch
Feature
Category
Resolution status
Not enough information
Submitted by
cjutzi
Lastmod by
Pascal St-Jean
Rating
(0)
Description

guys.. I fixed the probem.. doesn't appear that I can upload anything..


dthacker: thanks for the fix, but our dev's can't see what you changed. Could you please do a diff between your code and current CVS, and comment on the changes? Thanks!

Solution

inline.. 3 files

-- FILE: tiki-admin_categories.tpl

Image
{* $Header: /cvsroot/tikiwiki/tiki/templates/tiki-admin_categories.tpl,v 1.33.2.23 2007/08/04 22:02:23 marclaporte Exp $ *}

<h1><a class="pagetitle" href="tiki-admin_categories.php">{tr}Admin categories{/tr}</a>
  
      {if $feature_help eq 'y'}
<a href="{$helpurl}Category" target="tikihelp" class="tikihelp" title="{tr}admin categories{/tr}">
<img src="img/icons/help.gif" border="0" height="16" width="16" alt='{tr}help{/tr}' /></a>{/if}

{if $feature_view_tpl eq 'y'}
<a href="tiki-edit_templates.php?template=tiki-admin_categories.tpl" target="tikihelp" class="tikihelp" title="{tr}View tpl{/tr}: {tr}admin categories tpl{/tr}">
<img src="img/icons/info.gif" border="0" width="16" height="16" alt='{tr}Edit template{/tr}' /></a>{/if}</h1>

<div class="navbar"><a class="linkbut" href="tiki-browse_categories.php?parentId={$parentId}" title="{tr}browse the category system{/tr}">{tr}browse category{/tr}</a></div>

{if !empty($errors)}
<div class="simplebox highlight">{section name=ix loop=$errors}{$errors[ix]}{/section}</div>
{/if}
<div class="tree" id="top">
<div class="treetitle">{tr}Current category{/tr}: 
<a href="tiki-admin_categories.php?parentId=0" class="categpath">{tr}ROOT{/tr}</a>
{section name=x loop=$path}
&nbsp;::&nbsp;
<a class="categpath" href="tiki-admin_categories.php?parentId={$path[x].categId}">{$path[x].name}</a>
{/section}
</div>
<div>
{section name=dx loop=$catree}
{assign var=after value=$smarty.section.dx.index_next}
{assign var=before value=$smarty.section.dx.index_prev}
{if ($smarty.section.dx.index > 0) and ($catree[dx].deep > $catree[$before].deep)} 
<!-- cjutzi - removed this because it didn't allow you to edit at all.. 3/8/2008 -->
<!-- <div id="id{$catree[$before].categId}" style="display:none;"> cjutzi -->
{else}
{/if}
<div class="treenode{if $catree[dx].categId eq $smarty.request.parentId}select{/if}" style="padding-left:{$catree[dx].deep*30+20}px;">
<!-- {$catree[dx].parentId} :: {$catree[dx].categId} :: -->
{if $catree[dx].children > 0}<i class="mini">{$catree[dx].children} {tr}Child categories{/tr}</i>{/if}
{if $catree[dx].objects > 0}<i class="mini">{$catree[dx].objects} {tr}Child categories{/tr}</i>{/if}
<a class="link" href="tiki-admin_categories.php?parentId={$catree[dx].parentId}&amp;removeCat={$catree[dx].categId}" title="{tr}delete{/tr}"><img  
style="margin-right:{$catree[dx].deep*10+10}px;" border="0" src="img/icons2/delete.gif" align="right" height="12" width="12" hspace="5" vspace="1"/></a>
<a class="link" href="tiki-admin_categories.php?parentId={$catree[dx].parentId}&amp;categId={$catree[dx].categId}" title="{tr}edit{/tr}"><img  
border="0" src="img/icons/edit.gif" height="12" width="12" hspace="5" vspace="1"/></a>
{if $catree[dx].has_perm eq 'y'}
<a title="{tr}permissions{/tr}" href="tiki-categpermissions.php?categId={$catree[dx].categId}"><img border="0" alt="{tr}permissions{/tr}" src="img/icons/key_active.gif" /></a>
{else}
<a title="{tr}permissions{/tr}" href="tiki-categpermissions.php?categId={$catree[dx].categId}"><img border="0" alt="{tr}permissions{/tr}" src="img/icons/key.gif" /></a>
{/if}
<a class="catname" href="tiki-admin_categories.php?parentId={$catree[dx].categId}">{$catree[dx].name}</a>
{if $catree[dx].deep < $catree[$after].deep}
<a href="inhibited_js:toggle('id{$catree[dx].categId}');" class="linkmenu">&gt;&gt;&gt;</a></div>
{elseif $catree[dx].deep eq $catree[$after].deep}
</div>
{else}
</div>
{repeat count=$catree[dx].deep-$catree[$after].deep}</div>{/repeat}
{/if}
{/section}
</div>
<B>TEST DIV <BR></B>
<br />
<a name="editcreate"></a>
<table class="normalnoborder" cellpadding="0" cellspacing="0">
<tr>
  <td valign="top">
    <div class="cbox">
      <div class="cbox-title">
      {if $categId > 0}
      {tr}Edit this category:{/tr} <b>{$name}</b> [<a href="tiki-admin_categories.php?parentId={$parentId}#editcreate" class="cboxtlink">{tr}create new{/tr}</a>]
      {else}
      {tr}Add new category{/tr}
      {/if}
      </div>
      <div class="cbox-data">
      <form action="tiki-admin_categories.php" method="post">
      <input type="hidden" name="categId" value="{$categId|escape}" />
      <table>
        <tr><td class="form">{tr}Parent{/tr}:</td><td class="form">
				<select name="parentId">
				<option value="0">{tr}ROOT{/tr}</option>
				{section name=ix loop=$catree}
				<option value="{$catree[ix].categId|escape}" {if $catree[ix].categId eq $parentId}selected="selected"{/if}>{$catree[ix].categpath}</option>
				{/section}
				</select>
				</td></tr>
        <tr><td class="form">{tr}Name{/tr}:</td><td class="form"><input type="text" name="name" value="{$name|escape}" /></td></tr>
        <tr><td class="form">{tr}Description{/tr}:</td><td class="form"><textarea rows="2" cols="40" name="description">{$description|escape}</textarea></td></tr>
        {if $categId <= 0}<tr><td class="form"><label for="assign_perms" title="{tr}Perms inherited from closest parent if possible or from global perms{/tr}">{tr}Assign permissions automatically{/tr}:<br /><i>({tr}recommended for best performance{/tr})</i></label></td>
        <td class="form"><input type="checkbox" name="assign_perms" id="assign_perms" checked="{$assign_perms}" /></td></tr>
        {else}<tr><td class="form" colspan="2"><a href="tiki-categpermissions.php?categId={$categId}">{tr}Edit permissions for this category{/tr}</a></td></tr>
        {/if}
        <tr><td class="form" align="center" colspan="2"><input type="submit" name="save" value="{tr}Save{/tr}" /></td></tr>
      </table>
      </form>
      </div>
    </div>
  </td>
</tr>
</table>
<br />
<a name="objects"></a>
<table class="normalnoborder" cellpadding="0" cellspacing="0">
<tr>
  <td valign="top">
    <div class="cbox">
      <div class="cbox-title">
      {tr}Objects in category{/tr} <b>{$categ_name}</b>  
      </div>
      <div class="cbox-data">
      
      <table class="findtable">
      <tr><td class="findtable">{tr}Find{/tr}</td>
      <td class="findtable">
        <form method="get" action="tiki-admin_categories.php">
        <input type="text" name="find" />
        <input type="hidden" name="parentId" value="{$parentId|escape}" />
        <input type="submit" value="{tr}find{/tr}" name="search" />
        <input type="hidden" name="sort_mode" value="{$sort_mode|escape}" />
        <input type="hidden" name="find_objects" value="{$find_objects|escape}" />
        </form>
      </td>
      </tr>
      </table>
      
      <table class="normal">
      <tr>
        <td class="heading"><a class="tableheading" href="tiki-admin_categories.php?parentId={$parentId}&amp;offset={$offset}&amp;sort_mode={if $sort_mode eq 'name_desc'}name_asc{else}name_desc{/if}#objects">{tr}name{/tr}</a></td>
        <td class="heading"><a class="tableheading" href="tiki-admin_categories.php?parentId={$parentId}&amp;offset={$offset}&amp;sort_mode={if $sort_mode eq 'type_desc'}type_asc{else}type_desc{/if}#objects">{tr}type{/tr}</a></td>
        <td class="heading">{tr}delete{/tr}</td>
      </tr>
      {section name=ix loop=$objects}
      <tr>
        <td class="even"><a class="link" href="{$objects[ix].href}" title="{$objects[ix].name}">{$objects[ix].name|truncate:25:"(...)":true}</a></td>
        <td class="even">{tr}{$objects[ix].type}{/tr}</td>
        <td class="even"><a class="link" href="tiki-admin_categories.php?parentId={$parentId}&amp;removeObject={$objects[ix].catObjectId}&amp;fromCateg={$parentId}" title="{tr}delete{/tr}"><img alt="{tr}delete{/tr}" src="img/icons2/delete2.gif" border="0" /></a></td>
      </tr>
      {/section}
      </table>
      
      <div align="center">
        <div class="mini">
        {if $prev_offset >= 0}
          [<a class="prevnext" href="tiki-admin_categories.php?find={$find}&amp;parentId={$parentId}&amp;offset={$prev_offset}&amp;sort_mode={$sort_mode}#objects">{tr}prev{/tr}</a>]&nbsp;
        {/if}
        {tr}Page{/tr}: {$actual_page}/{if $cant_pages eq 0}1{else}{$cant_pages}{/if}
        {if $next_offset >= 0}
          &nbsp;[<a class="prevnext" href="tiki-admin_categories.php?find={$find}&amp;parentId={$parentId}&amp;offset={$next_offset}&amp;sort_mode={$sort_mode}#objects">{tr}next{/tr}</a>]
        {/if}
        </div>
      </div>

      
      </div>
    </div>
  </td>
  </tr>
  </table>
{if $parentId != 0}
  <br />
<table class="normalnoborder" cellpadding="0" cellspacing="0">  
  <tr>
  <td valign="top">
    <div class="cbox">
      <div class="cbox-title">
      {tr}Add objects to category{/tr} <b>{$categ_name}</b>
      </div>
      <div class="cbox-data">
      <table class="findtable">
      <tr><td class="findtable">{tr}Find{/tr}</td>
      <td>
        <form method="get" action="tiki-admin_categories.php">
        <input type="text" name="find_objects" />
        <input type="hidden" name="parentId" value="{$parentId|escape}" />
        <input type="submit" value="{tr}filter{/tr}" name="search_objects" />
        <input type="hidden" name="sort_mode" value="{$sort_mode|escape}" />
        <input type="hidden" name="offset" value="{$offset|escape}" />
        <input type="hidden" name="find" value="{$find|escape}" />
        </form>
      </td>
      </tr>
      </table>
      <form action="tiki-admin_categories.php" method="post">
      <input type="hidden" name="parentId" value="{$parentId|escape}" />
      <table>
        <tr>
          <td class="form">{tr}page{/tr}:</td>
          <td class="form"><select name="pageName[]" multiple="multiple" size="5">{section name=ix loop=$pages}<option value="{$pages[ix].pageName|escape}">{$pages[ix].pageName|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addpage" value="{tr}add{/tr}" /></td>
        </tr>
        <tr>
          <td class="form">{tr}article{/tr}:</td>
          <td class="form"><select name="articleId">{section name=ix loop=$articles}<option value="{$articles[ix].articleId|escape}">{$articles[ix].title|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addarticle" value="{tr}add{/tr}" /></td>
        </tr>
        <tr>
          <td class="form">{tr}blog{/tr}:</td>
          <td class="form"><select name="blogId">{section name=ix loop=$blogs}<option value="{$blogs[ix].blogId|escape}">{$blogs[ix].title|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addblog" value="{tr}add{/tr}" /></td>
        </tr>
        <tr>
          <td class="form">{tr}directory{/tr}:</td>
          <td class="form"><select name="directoryId">{section name=ix loop=$directories}<option value="{$directories[ix].categId|escape}">{$directories[ix].name|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="adddirectory" value="{tr}add{/tr}" /></td>
        </tr>
        <tr>
          <td class="form">{tr}image gal{/tr}:</td>
          <td class="form"><select name="galleryId">{section name=ix loop=$galleries}<option value="{$galleries[ix].galleryId|escape}">{$galleries[ix].name|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addgallery" value="{tr}add{/tr}" /></td>
        </tr>
        <tr>
          <td class="form">{tr}file gal{/tr}:</td>
          <td class="form"><select name="file_galleryId">{section name=ix loop=$file_galleries}<option value="{$file_galleries[ix].galleryId|escape}">{$file_galleries[ix].name|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addfilegallery" value="{tr}add{/tr}" /></td>
        </tr>
        <tr>
          <td class="form">{tr}forum{/tr}:</td>
          <td class="form"><select name="forumId">{section name=ix loop=$forums}<option value="{$forums[ix].forumId|escape}">{$forums[ix].name|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addforum" value="{tr}add{/tr}" /></td>
        </tr>
        <tr>
          <td class="form">{tr}poll{/tr}:</td>
          <td class="form"><select name="pollId">{section name=ix loop=$polls}<option value="{$polls[ix].pollId|escape}">{$polls[ix].title|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addpoll" value="{tr}add{/tr}" /></td>
        </tr>        
        <tr>
          <td class="form">{tr}faq{/tr}:</td>
          <td class="form"><select name="faqId">{section name=ix loop=$faqs}<option value="{$faqs[ix].faqId|escape}">{$faqs[ix].title|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addfaq" value="{tr}add{/tr}" /></td>
        </tr> 
	   <tr>
          <td class="form">{tr}tracker{/tr}:</td>
          <td class="form"><select name="trackerId">{section name=ix loop=$trackers}<option value="{$trackers[ix].trackerId|escape}">{$trackers[ix].name|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addtracker" value="{tr}add{/tr}" /></td>
        </tr>          
        <tr>
          <td class="form">{tr}quiz{/tr}:</td>
          <td class="form"><select name="quizId">{section name=ix loop=$quizzes}<option value="{$quizzes[ix].quizId|escape}">{$quizzes[ix].name|truncate:40:"(...)":true}</option>{/section}</select></td>
          <td class="form"><input type="submit" name="addquiz" value="{tr}add{/tr}" /></td>
        </tr>        


      </table>
      </form>
      </div>
    </div>
  </td>
</tr>
</table>
{/if}


-- FILE: categlib.php

Image
<?php
/** \file
 * $Header: /cvsroot/tikiwiki/tiki/lib/categories/categlib.php,v 1.48.2.55 2007/06/12 17:43:16 nkoth Exp $
 *
 * \brief Categories support class
 *
 */

//this script may only be included - so its better to die if called directly.
if (strpos($_SERVER["SCRIPT_NAME"],basename(__FILE__)) !== false) {
  header("location: index.php");
  exit;
}

class CategLib extends TikiLib {

	function CategLib($db) {
		# this is probably unneeded now
		if (!$db) {
			die ("Invalid db object passed to CategLib constructor");
		}

		$this->db = $db;
	}

	function list_categs($categId=0) {
		global $cachelib;
		if (!$cachelib->isCached("allcategs")) {
			$back = $this->build_cache();
		} else {
			$back = unserialize($cachelib->getCached('allcategs'));
		}
		if ($categId > 0) {
			$path = '';
			$back2 = array();
			foreach ($back as $cat) {
				if ($cat['categId'] == $categId)
					$path = $cat['categpath'].'::';
				else if ($path != '' && strpos($cat['categpath'], $path) === 0) {
					$cat['categpath'] = substr($cat['categpath'] , strlen($path));
					$back2[] = $cat;
				}
			}
			return $back2;
		} else {
			return $back;
		}
	}
	
	function list_all_categories($offset, $maxRecords, $sort_mode = 'name_asc', $find, $type, $objid) {

		$cats = $this->get_object_categories($type, $objid);
		if ($find) {
			$findesc = '%' . $find . '%';
			$bindvals=array($findesc,$findesc);
			$mid = " where (`name` like ? or `description` like ?)";
		} else {
	      $bindvals=array();
		  $mid = "";
		}

		$query = "select * from `tiki_categories` $mid order by ".$this->convert_sortmode($sort_mode);
		$query_cant = "select count(*) from `tiki_categories` $mid";
		$result = $this->query($query,$bindvals,$maxRecords,$offset);
		$cant = $this->getOne($query_cant,$bindvals);

		$ret = array();

		while ($res = $result->fetchRow()) {
			if (!empty($cats) && in_array($res["categId"], $cats)) {
				$res["incat"] = 'y';
			} else {
				$res["incat"] = 'n';
			}
      
			$catpath = $this->get_category_path($res["categId"]);
			$tepath = array();	
			foreach ($catpath as $cat) {
				$tepath[] = $cat['name'];
			}
			$categpath = implode("::",$tepath);
			$categpathforsort = implode("!!",$tepath); // needed to prevent cat::subcat to be sorted after cat2::subcat 
			$res["categpath"] = $categpath;
			$res["tepath"] = $tepath;
			$res["deep"] = count($tepath);
			global $userlib;
			if ($userlib->object_has_one_permission($res['categId'], 'category')) {
				$res['has_perm'] = 'y';
			} else {
				$res['has_perm'] = 'n';
			}
			
			/* cjutzi - added so you could edit the damn thing.. 	*/
			/* only show / edit those who's parent == the requested */
//			if (($res["parentId"] == $objid))
				$ret["$categpathforsort"] = $res;
		}

		ksort($ret);
		
		$retval = array();
		$retval["data"] = array_values($ret);
		$retval["cant"] = $cant;
		return $retval;
	}

	function get_category_path_string($categId) {
		global $cachelib;
		if (!$cachelib->isCached('allcategs')) {
			$categs = $this->build_cache();
		} else {
			$categs = unserialize($cachelib->getCached('allcategs'));
		}
		foreach ($categs as $cat) {
			if ($cat['categId'] == $categId) {
				return $cat['categpath'];
			}
		}
		return '';
	}

	function get_category_path($categId) {
		$info = $this->get_category($categId);
		$i=999999;
		$path[$i--] = array('categId'=>$info["categId"],'name'=>$info["name"]);
		while ($info["parentId"] != 0) {
			$info = $this->get_category($info["parentId"]);
			$path[$i--] = array('categId'=>$info["categId"],'name'=>$info["name"]);
		}
		ksort($path);
		return array_values($path);
	}

	function get_category($categId) {
	   if(!isset($this->category_cache) || !isset($this->category_cache[$categId])) {
		$query = "select * from `tiki_categories` where `categId`=?";
		$result = $this->query($query,array((int) $categId));
		if (!$result->numRows()) {
		   $this->category_cache[$categId] = false;
		}
		$this->category_cache[$categId] = $result->fetchRow();
	   }
	   return $this->category_cache[$categId];
	}
	
	function get_category_name($categId) {
		$query = "select `name` from `tiki_categories` where `categId`=?";
		return $this->getOne($query,array((int) $categId));
	}
	
	function remove_category($categId) {
		global $cachelib;

		$query = "delete from `tiki_categories` where `categId`=?";
		$result = $this->query($query,array((int) $categId));
		$query = "select `catObjectId` from `tiki_category_objects` where `categId`=?";
		$result = $this->query($query,array((int) $categId));

		while ($res = $result->fetchRow()) {
			$object = $res["catObjectId"];

			$query_cant = "select count(*) from `tiki_category_objects` where `catObjectId`=?";
			$cant = $this->getOne($query_cant,array($object));
			if ($cant <= 1) {
			$query2 = "delete from `tiki_categorized_objects` where `catObjectId`=?";
			$result2 = $this->query($query2,array($object));
			}
		}
		
		// remove any permissions assigned to this category
		$type = 'category';
		$object = $type . $categId;
		$query = "delete from `users_objectpermissions` where `objectId`=? and `objectType`=?";
		$result = $this->query($query,array(md5($object),$type));

		$query = "delete from `tiki_category_objects` where `categId`=?";
		$result = $this->query($query,array((int) $categId));
		$query = "select `categId` from `tiki_categories` where `parentId`=?";
		$result = $this->query($query,array((int) $categId));

		while ($res = $result->fetchRow()) {
			// Recursively remove the subcategory
			$this->remove_category($res["categId"]);
		}
		$cachelib->invalidate('allcategs');
		return true;
	}

	function update_category($categId, $name, $description, $parentId) {
		global $cachelib;
		$query = "update `tiki_categories` set `name`=?, `parentId`=?, `description`=? where `categId`=?";
		$result = $this->query($query,array($name,(int) $parentId,$description,(int) $categId));
		$cachelib->invalidate('allcategs');
		$cachelib->invalidate('childcategs'.$parentId);
	}

	function add_category($parentId, $name, $description) {
		global $cachelib;
		$query = "insert into `tiki_categories`(`name`,`description`,`parentId`,`hits`) values(?,?,?,?)";
		$result = $this->query($query,array($name,$description,(int) $parentId,0));
		$query = "select `categId` from `tiki_categories` where `name`=? and `parentId`=?";
		$id = $this->getOne($query,array($name,(int) $parentId));
		$cachelib->invalidate('allcategs');
		$cachelib->invalidate('childcategs'.$parentId);
		return $id;
	}

	function is_categorized($type, $objId) {
		$query = "select `catObjectId` from `tiki_categorized_objects` where `type`=? and `objId`=?";
		$bindvars=array($type,$objId);
		settype($bindvars["1"],"string");
		$result = $this->query($query,$bindvars);
		if ($result->numRows()) {
			$res = $result->fetchRow();
			return $res["catObjectId"];
		} else {
			return 0;
		}
	}

	function add_categorized_object($type, $objId, $description, $name, $href) {
		global $cachelib;

		$description = strip_tags($description);
		$name = strip_tags($name);
		$now = date("U");
		$query = "insert into `tiki_categorized_objects`(`type`,`objId`,`description`,`name`,`href`,`created`,`hits`)
    values(?,?,?,?,?,?,?)";
		$result = $this->query($query,array($type,(string) $objId,$description,$name,$href,(int) $now,0));
		$query = "select `catObjectId` from `tiki_categorized_objects` where `created`=? and `type`=? and `objId`=?";
		$id = $this->getOne($query,array((int) $now,$type,(string) $objId));
		$cachelib->invalidate('allcategs');
		return $id;
	}

	function categorize($catObjectId, $categId) {
		$query = "delete from `tiki_category_objects` where `catObjectId`=? and `categId`=?";
		$result = $this->query($query,array((int) $catObjectId,(int) $categId),-1,-1,false);
	        
		$query = "insert into `tiki_category_objects`(`catObjectId`,`categId`) values(?,?)";
		$result = $this->query($query,array((int) $catObjectId,(int) $categId));
	}

	function get_category_descendants($categId) {
		$query = "select `categId` from `tiki_categories` where `parentId`=?";

		$result = $this->query($query,array((int) $categId));
		$ret = array($categId);

		while ($res = $result->fetchRow()) {
			$ret[] = $res["categId"];

			$aux = $this->get_category_descendants($res["categId"]);
			$ret = array_merge($ret, $aux);
		}

		$ret = array_unique($ret);
		return $ret;
	}

	// Returns a hash indicating which permission is needed for viewing an object of desired type.
	function map_object_type_to_permission() {
	    return array('wiki page' => 'tiki_p_view',
			 'forum' => 'tiki_p_forum_read',
			 'image gallery' => 'tiki_p_view_image_gallery',
			 'file gallery' => 'tiki_p_view_file_gallery',
			 'tracker' => 'tiki_p_view_trackers',
			 'blog' => 'tiki_p_read_blog',
			 'quiz' => 'tiki_p_take_quiz',

			 // overhead - we are checking individual permission on types below, but they
			 // can't have individual permissions, although they can be categorized.
			 // should they have permissions too?
			 'poll' => 'tiki_p_vote_poll',
			 'survey' => 'tiki_p_take_survey',
			 'directory' => 'tiki_p_view_directory',
			 'faq' => 'tiki_p_view_faqs',
			 'sheet' => 'tiki_p_view_sheet',

			 // these ones are tricky, because permission type is for container, not object itself.
			 // I think we need to refactor permission schemes for them to be wysiwyca - lfagundes
			 //
			 // by now they're not showing, list_category_objects needs support for ignoring permissions
			 // for a type.
			 'article' => 'tiki_p_read_article',
			 'image' => 'tiki_p_view_image_gallery',
			 'calendar' => 'tiki_p_view_calendar',
			 
			 // newsletters can't be categorized, although there's some code in tiki-admin_newsletters.php
			 // 'newsletter' => ?,
			 // 'events' => ?,
			 );
	}

	function list_category_objects($categId, $offset, $maxRecords, $sort_mode='pageName_asc', $type='', $find='', $deep=false, $and=false) {
		global $userlib;
	    
	    // Build the condition to restrict which categories objects must be in to be returned.
	    $join = '';
	    if (is_array($categId) && $and) {
			$i = count($categId);
			$bindWhere = $categId;
			foreach ($categId as $c) {
				if (--$i)
					$join .= " INNER JOIN tiki_category_objects tco$i on (tco$i.`catObjectId`=o.`catObjectId` and tco$i.`categId`=?) ";
			}
			$where = ' AND c.`categId`=? ';
	   } elseif (is_array($categId)) {
			$bindWhere = $categId;
			if ($deep) {
				foreach ($categId as $c) {
					$bindWhere = array_merge($bindWhere, $this->get_category_descendants($c));
				}				
			}
			$where = " AND c.`categId` IN (".str_repeat("?,",count($bindWhere)-1)."?)";
	    } else {
		if ($deep) {
			$bindWhere = $this->get_category_descendants($categId);
			$bindWhere[] = $categId;
			$where = " AND c.`categId` IN (".str_repeat("?,",count($bindWhere)-1)."?)";
		} else {
			$bindWhere = array($categId);
			$where = ' AND c.`categId`=? ';
		}
	    }

	        // Restrict results by keyword
		if ($find) {
			$findesc = '%' . $find . '%';
			$bindWhere[]=$findesc;
			$bindWhere[]=$findesc;
			$where .= " AND (`name` LIKE ? OR `description` LIKE ?)";
		} 

		global $user;
		$permMap = $this->map_object_type_to_permission();
		$groupList = $this->get_user_groups($user);

		$where .= " AND (( u.`objectId` IS NULL AND (o.`type` IN (''";

		$allowField = '';
		$bindAllow = array();
		$addTrackerItem = false;
		foreach ($permMap as $objType => $permName) {
		  if (empty($type) || $type == $objType || ($type == "trackerItem" && $objType == "tracker")) {
		    if ($type == "trackerItem") {
			$allowField .= "(o.`type`like ? AND u.`permName`=?) OR ";
			$bindAllow[] = "tracker %";
		    } else {
			$allowField .= "(o.`type`=? AND u.`permName`=?) OR ";
			$bindAllow[] = $objType;
		    }
		    $bindAllow[] = $permName;
		    
		    global $permName;
		    if ($permName == 'y' && (empty($type) || $type != "trackerItem")) {
			$where .= ",?";
			$bindWhere[] = $objType;
		    }
		    if ($objType == "tracker" && $permName == 'y') {
			$addTrackerItem = true;
		    }
		  }
		}
		$where .= ")";
		if ($addTrackerItem) {
			$where .= " OR o.`type` like ?";
			$bindWhere[] .= "tracker %";
		}

		$allowField = preg_replace("/OR $/",") ",$allowField);
		if (!$userlib->user_has_permission($user, 'tiki_p_admin')) { // do not filter on group if admin
		$allowField .= " AND u.`groupName` IN (''";
		
		foreach ($groupList as $grp) {
		    $bindAllow[] = $grp;
		    $allowField .= ",?";
		}
			$where .= ')';
		}
		$where .= ") OR (($allowField )))";

		$bindVars = array_merge($bindWhere, $bindAllow);

		$orderBy = '';
		if ($sort_mode) {
			if ($sort_mode != 'shuffle') {
				$orderBy = " ORDER BY ".$this->convert_sortmode($sort_mode);
			}
		}

		$query_cant = "SELECT DISTINCT c.*, o.* FROM `tiki_category_objects` c,`tiki_categorized_objects` o LEFT JOIN `users_objectpermissions` u ON u.`objectId`=MD5(".$this->db->concat("o.`type`","LOWER(o.`objId`)").") AND u.`objectType`=o.`type` $join WHERE c.`catObjectId`=o.`catObjectId` $where";
		$query = $query_cant . $orderBy;
		$result = $this->query($query,$bindVars,$maxRecords,$offset);
		$resultCant = $this->query($query_cant,$bindVars);
		$cant = $resultCant->numRows();

		$ret = array();
		$objs = array();

		while ($res = $result->fetchRow()) {
			if (!in_array($res["catObjectId"], $objs)) {
				$ret[] = $res;

				$objs[] = $res["catObjectId"];
			}
		}

		$retval = array();
		if ($sort_mode == 'shuffle') {
			shuffle($ret);
		}
		$retval["data"] = $ret;
		$retval["cant"] = $cant;

		return $retval;
	}

	// get the parent categories of an object
	function get_object_categories($type, $objId) {
		if (!$objId)
			return null;
		$query = "select `categId` from 
									`tiki_category_objects` tco, 
									`tiki_categorized_objects` tto
    					  where 
						  		tco.`catObjectId`=tto.`catObjectId` 
							and 
								`type`=? 
							and 
								`objId`=?";
		//settype($objId,"string"); //objId is defined as varchar

		$bindvars=array($type,$objId);
		settype($bindvars["1"],"string");
		$result = $this->query($query,$bindvars);
		$ret = array();

		while ($res = $result->fetchRow()) {
			$ret[] = $res["categId"];
		}
		return $ret;
	}
	
	// get the permissions assigned to the parent categories of an object
	function get_object_categories_perms($user, $type, $objId) {		
		$is_categorized = $this->is_categorized("$type",$objId);
		if ($is_categorized) {
			global $cachelib;
			global $userlib;
			global $tiki_p_admin;
			
			$parents = $this->get_object_categories("$type", $objId);
			$return_perms = array(); // initialize array for storing perms to be returned

			if (!$cachelib->isCached("categories_permission_names")) {
				$perms = $userlib->get_permissions(0, -1, 'permName_desc', 'categories');
				$cachelib->cacheItem("categories_permission_names",serialize($perms));
			} else {
				$perms = unserialize($cachelib->getCached("categories_permission_names"));
			}

			foreach ($perms["data"] as $perm) {
				$perm = $perm["permName"];
				if ($tiki_p_admin == 'y') {
					$return_perms["$perm"] = 'y';
				} else {
					foreach ($parents as $categId) {
						if ($userlib->object_has_one_permission($categId, 'category')) {
							if ($userlib->object_has_permission($user, $categId, 'category', $perm)) {
								$return_perms["$perm"] = 'y';
							} else {
								$return_perms["$perm"] = 'n';
								// better-sorry-than-safe approach:
								// if a user lacks a given permission regarding a particular category,
								// that category takes precedence when considering if user has that permission
								break 1;
								// break out of one FOREACH loop
							}
						} else {
							$categpath = $this->get_category_path($categId);
							foreach ($categpath as $cat) {
								if ($userlib->object_has_one_permission($cat['categId'], 'category')) {
									if ($userlib->object_has_permission($user, $cat['categId'], 'category', $perm)) {
										$return_perms["$perm"] = 'y';
								   		break 1;
									} else {
										$return_perms["$perm"] = 'n';
										// better-sorry-than-safe approach:
										// if a user lacks a given permission regarding a particular category,
										// that category takes precedence when considering if user has that permission
										break 2;
										// break out of one FOR loop and one FOREACH loop
									}
								} else { /* no special perm on cat  so general perm: (to see the categ panel as anonymous */ 
									$return_perms[$perm] = $GLOBALS[$perm];
								}

							}
						}
					}
				}
			}
			return $return_perms;
		} else {
			return FALSE;
		}
		
	}

	function get_category_objects($categId) {
		// Get all the objects in a category
		$query = "select * from `tiki_category_objects` tbl1,`tiki_categorized_objects` tbl2 where tbl1.`catObjectId`=tbl2.`catObjectId` and `categId`=?";

		$result = $this->query($query,array((int) $categId));
		$ret = array();
		while ($res = $result->fetchRow()) {
			$ret[] = $res;
		}

		return $ret;
	}

	function remove_object_from_category($catObjectId, $categId) {
		global $cachelib;

		$query = "delete from `tiki_category_objects` where `catObjectId`=? and `categId`=?";
		$result = $this->query($query,array($catObjectId,$categId));
		$query = "select count(*) from `tiki_category_objects` where `catObjectId`=?";
		$cant = $this->getOne($query,array((int) $catObjectId));
		if (!$cant) {
			$query = "delete from `tiki_categorized_objects` where `catObjectId`=?";
			$result = $this->query($query,array((int) $catObjectId));
		}
		$cachelib->invalidate('allcategs');
	}

	// FUNCTIONS TO CATEGORIZE SPECIFIC OBJECTS ////
	function categorize_page($pageName, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page

		$catObjectId = $this->is_categorized('wiki page', $pageName);

		if (!$catObjectId) {
			// The page is not cateorized
			$info = $this->get_page_info($pageName);

			$href = 'tiki-index.php?page=' . urlencode($pageName);
			$catObjectId = $this->add_categorized_object('wiki page', $pageName, substr($info["description"], 0, 200), $pageName, $href);
		}

		$this->categorize($catObjectId, $categId);
	}
	
	function categorize_tracker($trackerId, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page

		$catObjectId = $this->is_categorized('tracker', $trackerId);

		if (!$catObjectId) {
			// The page is not cateorized
			$info = $this->get_tracker($trackerId);

			$href = 'tiki-view_tracker.php?trackerId=' . $trackerId;
			$catObjectId = $this->add_categorized_object('tracker', $trackerId, substr($info["description"], 0, 200),$info["name"] , $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	function categorize_quiz($quizId, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('quiz', $quizId);

		if (!$catObjectId) {
			// The page is not cateorized
			$info = $this->get_quiz($quizId);

			$href = 'tiki-take_quiz.php?quizId=' . $quizId;
			$catObjectId
				= $this->add_categorized_object('quiz', $quizId, substr($info["description"], 0, 200), $info["name"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	function categorize_article($articleId, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('article', $articleId);

		if (!$catObjectId) {
			// The page is not cateorized
			$info = $this->get_article($articleId);

			$href = 'tiki-read_article.php?articleId=' . $articleId;
			$catObjectId = $this->add_categorized_object('article', $articleId, $info["heading"], $info["title"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	function categorize_faq($faqId, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('faq', $faqId);

		if (!$catObjectId) {
			// The page is not cateorized
			$info = $this->get_faq($faqId);

			$href = 'tiki-view_faq.php?faqId=' . $faqId;
			$catObjectId = $this->add_categorized_object('faq', $faqId, $info["description"], $info["title"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	function categorize_blog($blogId, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('blog', $blogId);

		if (!$catObjectId) {
			// The page is not cateorized
			$info = $this->get_blog($blogId);

			$href = 'tiki-view_blog.php?blogId=' . $blogId;
			$catObjectId = $this->add_categorized_object('blog', $blogId, $info["description"], $info["title"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	function categorize_directory($directoryId, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('directory', $directoryId);

		if (!$catObjectId) {
			// The page is not cateorized
			$info = $this->get_directory($directoryId);

			$href = 'tiki-directory_browse.php?parent=' . $directoryId;
			$catObjectId = $this->add_categorized_object('directory', $directoryId, $info["description"], $info["name"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	function categorize_gallery($galleryId, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('image gallery', $galleryId);

		if (!$catObjectId) {
			// The page is not cateorized
			$info = $this->get_gallery($galleryId);

			$href = 'tiki-browse_gallery.php?galleryId=' . $galleryId;
			$catObjectId = $this->add_categorized_object('image gallery', $galleryId, $info["description"], $info["name"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	function categorize_file_gallery($galleryId, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('file gallery', $galleryId);

		if (!$catObjectId) {
			// The page is not cateorized
			$info = $this->get_file_gallery($galleryId);

			$href = 'tiki-list_file_gallery.php?galleryId=' . $galleryId;
			$catObjectId = $this->add_categorized_object('file gallery', $galleryId, $info["description"], $info["name"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	function categorize_forum($forumId, $categId) {
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('forum', $forumId);

		if (!$catObjectId) {
			global $commentslib;
			if (!is_object($commentslib)) {
				require_once('lib/commentslib.php');
			}
			// The page is not cateorized
			$info = $commentslib->get_forum($forumId);

			$href = 'tiki-view_forum.php?forumId=' . $forumId;
			$catObjectId = $this->add_categorized_object('forum', $forumId, $info["description"], $info["name"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	function categorize_poll($pollId, $categId) {
		global $polllib;
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('poll', $pollId);
		if (!$catObjectId) {
			if (!is_object($polllib)) {
				require_once('lib/polls/polllib_shared.php');
			}
			// The page is not cateorized
			$info = $pollib->get_poll($pollId);

			$href = 'tiki-poll_form.php?pollId=' . $pollId;
			$catObjectId = $this->add_categorized_object('poll', $pollId, $info["title"], $info["title"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}
	
	function categorize_calendar($calendarId, $categId) {
		global $calendarlib;
		// Check if we already have this object in the tiki_categorized_objects page
		$catObjectId = $this->is_categorized('calendar', $calendarId);
		if (!$catObjectId) {
			if (!is_object($calendarlib)) {
				require_once('lib/calendar/calendarlib.php');
			}
			// The page is not cateorized
			$info = $calendarlib->get_calendar($calendarId);

			$href = 'tiki-calendar.php?calId=' . $calendarId;
			$catObjectId = $this->add_categorized_object('calendar', $calendarId, $info["description"], $info["calname"], $href);
		}

		$this->categorize($catObjectId, $categId);
	}

	// FUNCTIONS TO CATEGORIZE SPECIFIC OBJECTS END ////
	function get_child_categories($categId) {
	  global $cachelib, $language, $feature_multilingual;
		if (!$categId) $categId = "0"; // avoid wrong cache
		if (!$cachelib->isCached("childcategs$categId")) {
			$ret = array();
			$query = "select * from `tiki_categories` where `parentId`=? order by name";
			$result = $this->query($query,array($categId));
			while ($res = $result->fetchRow()) {
				$id = $res["categId"];
				$query = "select count(*) from `tiki_categories` where `parentId`=?";
				$res["children"] = $this->getOne($query,array($id));
				$query = "select count(*) from `tiki_category_objects` where `categId`=?";
				$res["objects"] = $this->getOne($query,array($id));
				$ret[] = $res;
			}
			$cachelib->cacheItem("childcategs$categId",serialize($ret));
		} else {
			$ret = unserialize($cachelib->getCached("childcategs$categId"));
		}
		if ($feature_multilingual == 'y' && $language != 'en') {
			foreach ($ret as $key=>$res) {
				$ret[$key]['name'] = tra($res['name']);
			}
		}
		return $ret;
	}

	function get_all_categories() {
		global $cachelib;
	/*
		// inhibited because allcateg_ext is cached now
		$query = " select `name`,`categId`,`parentId` from `tiki_categories` order by `name`";
		$result = $this->query($query,array());
		$ret = array();

		while ($res = $result->fetchRow()) {
			$ret[] = $res;
		}
	*/
		return $this->get_all_categories_ext();
	}

	/* build the cache with the categpath and the count */
	function build_cache() {
		global $cachelib;
		$ret = array();
		$query = "select * from `tiki_categories` order by `name`";
		$result = $this->query($query,array());
		while ($res = $result->fetchRow()) {
			$id = $res["categId"];
			$catpath = $this->get_category_path($id);
			$tepath = array();
			foreach ($catpath as $cat) {
				$tepath[] = $cat['name'];
			}
			$categpath = implode("::",$tepath);
			$categpathforsort = implode("!!",$tepath); // needed to prevent cat::subcat to be sorted after cat2::subcat
			$res["categpath"] = $categpath;
			$res["tepath"] = $tepath;
			$query = "select count(*) from `tiki_categories` where `parentId`=?";
			$res["children"] = $this->getOne($query,array($id));
			$query = "select count(*) from `tiki_category_objects` where `categId`=?";
			$res["objects"] = $this->getOne($query,array($id));
			$ret[$categpathforsort] = $res;
		}
		ksort($ret);
		$ret = array_values($ret);
		$cachelib->cacheItem("allcategs",serialize($ret));
		return $ret;
	}

	// Same as get_all_categories + it also get info about count of objects
	function get_all_categories_ext() {
		global $cachelib;
		if (!$cachelib->isCached("allcategs")) {
			$ret = $this->build_cache();
		} else {
			$ret = unserialize($cachelib->getCached("allcategs"));

		}
		return $ret;
	}

	function get_all_categories_respect_perms($user, $perm) {
		global $cachelib;
		global $userlib;
		global $tiki_p_admin;
		
//		if (!$cachelib->isCached("allcategs")) {
			$ret = array();
			$query = "select * from `tiki_categories` order by `name`";
			$result = $this->query($query,array());
			while ($res = $result->fetchRow()) {

				$add = TRUE;
				if ($tiki_p_admin != 'y' && $userlib->object_has_one_permission($res['categId'], 'category')) {
					if (!$userlib->object_has_permission($user, $res['categId'], 'category', $perm)) {
						$add = FALSE;
					}
				} elseif ($tiki_p_admin != 'y') {
					$categpath = $this->get_category_path($res['categId']);
					$arraysize = count($categpath);
					for ($i=$arraysize-2; $i>=0; $i--) {
						if ($userlib->object_has_one_permission($categpath[$i]['categId'], 'category')) {
							if ($userlib->object_has_permission($user, $categpath[$i]['categId'], 'category', $perm)) {
								$add = TRUE;
								break 1;
								// break out of one FOR loop
							} else {
								$add = FALSE;
								break 1;
								// break out of one FOR loop
							}
						}
					}
				}
				
				if ($add) {
					$id = $res["categId"];
					$query = "select count(*) from `tiki_categories` where `parentId`=?";
					$res["children"] = $this->getOne($query,array($id));
					$query = "select count(*) from `tiki_category_objects` where `categId`=?";
					$res["objects"] = $this->getOne($query,array($id));
					$ret[] = $res;
				}
			}
//			$cachelib->cacheItem("allcategs.$user.$perm",serialize($ret));
//		} else {
//			$ret = unserialize($cachelib->getCached("allcategs.$user.$perm"));
//		}
		return $ret;
	}

	
	// get categories related to a link. For Whats related module.
	function get_link_categories($link) {
		$ret=array();
		$parsed=parse_url($link);
		$urlPath = split("/",$parsed["path"]);
		$parsed["path"]=end($urlPath);
		if(!isset($parsed["query"])) return($ret);
		/* not yet used. will be used to get the "base href" of a page
		$params=array();
		$a = explode('&', $parsed["query"]);
		for ($i=0; $i < count($a);$i++) {
			$b = split('=', $a[$i]);
			$params[htmlspecialchars(urldecode($b[0]))]=htmlspecialchars(urldecode($b[1]));
		}
		*/
		$query="select distinct co.`categId` from `tiki_categorized_objects` cdo, `tiki_category_objects` co  where cdo.`href`=? and cdo.`catObjectId`=co.`catObjectId`";
		$result=$this->query($query,array($parsed["path"]."?".$parsed["query"]));
		while ($res = $result->fetchRow()) {
		  $ret[]=$res["categId"];
		}
		return($ret);
	}

	// input is a array of category id's and return is a array of 
	// maxRows related links with description
	function get_related($categories,$maxRows=10) {
		if(count($categories)==0) return (array());
		$quarr=implode(",",array_fill(0,count($categories),'?'));
		$query="select distinct cdo.`type`, cdo.`description`, cdo.`objId`,cdo.`href` from `tiki_categorized_objects` cdo, `tiki_category_objects` co  where co.`categId` in (".$quarr.") and co.`catObjectId`=cdo.`catObjectId`";
		$result=$this->query($query,$categories);
		$ret=array();
		while ($res = $result->fetchRow()) {
			if (empty($res["description"])) {
				$ret[$res["href"]]=$res["type"].": ".$res["objId"];
			} else {
				$ret[$res["href"]]=$res["type"].": ".$res["description"];
			}
		}
		if (count($ret)>$maxRows) {
			$ret2=array();
			$rand_keys = array_rand ($ret,$maxRows);
			foreach($rand_keys as $value) {
				$ret2[$value]=$ret[$value];
			}
			return($ret2);
		}
		return($ret);
	}
	
	// combines the two functions above
	function get_link_related($link,$maxRows=10) {
		return ($this->get_related($this->get_link_categories($link),$maxRows));
	}
	
	// Moved from tikilib.php
	function uncategorize_object($type, $id) {
		// Fixed query. -rlpowell
		$query = "select `catObjectId`  from `tiki_categorized_objects` where `type`=? and `objId`=?";
		$catObjectId = $this->getOne($query, array((string) $type,(string) $id));

		if ($catObjectId) {
		    $query = "delete from `tiki_category_objects` where `catObjectId`=?";
		    $result = $this->query($query,array((int) $catObjectId));
			// must keep tiki_categorized object because poll or ... can use it
		}
    }

    // Moved from tikilib.php
    function get_categorypath($cats) {
			global $smarty;
			global $feature_categories;

			$catpath = '';
			foreach ($cats as $categId) {
			        $catp = array();
				$info = $this->get_category($categId);
				$catp["{$info['categId']}"] = $info["name"];
				while ($info["parentId"] != 0) {
					$info = $this->get_category($info["parentId"]);
					$catp["{$info['categId']}"] = $info["name"];
				}
				$smarty->assign('catp',array_reverse($catp,true));
				$catpath.= $smarty->fetch('categpath.tpl');
			}
			return $catpath;
    }
    
    //Moved from tikilib.php
    function get_categoryobjects($catids,$types="*",$sort='created_desc',$split=true,$sub=false,$and=false) {
			global $smarty;
			global $feature_categories;

		$typetokens = array(
			"article" => "article",
			"blog" => "blog",
			"directory" => "directory",
			"faq" => "faq",
			"fgal" => "file gallery",
			"forum" => "forum",
			"igal" => "image gallery",
			"newsletter" => "newsletter",
			"poll" => "poll",
			"quiz" => "quiz",
			"survey" => "survey",
			"tracker" => "tracker",
			"wiki" => "wiki page",
			"calendar" => "calendar",
			"img" => "image"
		);	//get_strings tra("article");tra("blog");tra("directory");tra("faq");tra("file gallery");tra("forum");tra("image gallery");tra("newsletter");
			//get_strings tra("poll");tra("quiz");tra("survey");tra("tracker");tra("wiki page");tra("image");tra("calendar");
			
		$typetitles = array(
			"article" => "Articles",
			"blog" => "Blogs",
			"directory" => "Directories",
			"faq" => "FAQs",
			"file gallery" => "File Galleries",
			"forum" => "Forums",
			"image gallery" => "Image Galleries",
			"newsletter" => "Newsletters",
			"poll" => "Polls",
			"quiz" => "Quizzes",
			"survey" => "Surveys",
			"tracker" => "Trackers",
			"wiki page" => "Wiki",
			"calendar" => "Calendar",
			"image" => "Image"
		);

		$out = "";
		$listcat = $allcats = array();
		$title = '';
		$find = "";
		$offset = 0;
		$firstpassed = false;
		$maxRecords = 500;
		$typesallowed = array();
		if ($and) {
			$split = false;
		}
		if ($types == '*') {
			$typesallowed = array_keys($typetitles);
		} elseif (strpos($types,'+')) {
			$alltypes = split('\+',$types);
			foreach ($alltypes as $t) {
				if (isset($typetokens["$t"])) {
					$typesallowed[] = $typetokens["$t"];
				} elseif (isset($typetitles["$t"])) {
					$typesallowed[] = $t;
				}
			}
		} elseif (isset($typetokens["$types"])) {
			$typesallowed = array($typetokens["$types"]);
		} elseif (isset($typetitles["$types"])) {
			$typesallowed = array($types);
		}
		
		foreach ($catids as $id) {
			$titles["$id"] = $this->get_category_name($id);
			$objectcat = array();
			$objectcat = $this->list_category_objects($id, $offset, $maxRecords, $sort, '', $find, $sub);

			$acats = $andcat = array();
			foreach ($objectcat["data"] as $obj) {
				$type = $obj["type"];
				if (substr($type,0,7) == 'tracker') $type = 'tracker';
				if (($types == '*') || in_array($type,$typesallowed)) {
					if ($split or !$firstpassed) {
						$listcat["$type"][] = $obj;
						$cats[] = $type.'.'.$obj['name'];
					} elseif ($and) {
						if (in_array($type.'.'.$obj['name'], $cats)) {
							$andcat["$type"][] = $obj;
							$acats[] = $type.'.'.$obj['name'];
						}
					} else {
						if (!in_array($type.'.'.$obj['name'], $cats)) {
							$listcat["$type"][] = $obj;
							$cats[] = $type.'.'.$obj['name'];
						}
					}
				}
			}
			if ($split) {
				$smarty->assign("id", $id);
				$smarty->assign("titles", $titles);
				$smarty->assign("listcat", $listcat);
				$out .= $smarty->fetch("categobjects.tpl");
				$listcat = array();
				$titles = array();
				$cats = array();
			} elseif ($and and $firstpassed) {
				$listcat = $andcat;
				$cats = $acats;
			}
			$firstpassed = true;
		}
		if (!$split) {
			$smarty->assign("id", $id);
			$smarty->assign("titles", $titles);
			$smarty->assign("listcat", $listcat);
			$out = $smarty->fetch("categobjects.tpl");
		}
		return $out;
	}
	
	//Moved from tikilib.php
    function last_category_objects($categId, $maxRecords, $type="") {
		$mid = "and tbl1.`categId`=?";
		$bindvars = array((int)$categId);
		if ($type) {
		    $mid.= " and tbl2.`type`=?";
		    $bindvars[] = $type;
		}
		$sort_mode = "created_desc";
		$query = "select tbl1.`catObjectId`,`categId`,`type`,`name`,`href` from `tiki_category_objects` tbl1,`tiki_categorized_objects` tbl2 ";
		$query.= " where tbl1.`catObjectId`=tbl2.`catObjectId` $mid order by tbl2.".$this->convert_sortmode($sort_mode);
		$result = $this->query($query,$bindvars,$maxRecords,0);

		$ret = array('data'=>array());
		while ($res = $result->fetchRow()) {
		    $ret['data'][] = $res;
		}
		return $ret;
    }

    // Gets a list of categories that will block objects to be seen by user, recursive
    function list_forbidden_categories($parentId=0, $parentAllowed='') {
	global $user, $userlib;
	if (empty($parentAllowed)) {
	    global $tiki_p_view_categories;
	    $parentAllowed = $tiki_p_view_categories;
	}

	$query = "select `categId` from `tiki_categories` where `parentId`=?";
	$result = $this->query($query, array($parentId));

	$forbidden = array();

	while ($row = $result->fetchRow()) {
	    $child = $row['categId'];
	    if ($userlib->object_has_one_permission($child, 'category')) {
		if ($userlib->object_has_permission($user, $child, 'category', 'tiki_p_view_categories')) {
		    $forbidden = array_merge($forbidden, $this->list_forbidden_categories($child, 'y'));
		} else {
		    $forbidden[] = $child;
		    $forbidden = array_merge($forbidden, $this->list_forbidden_categories($child, 'n'));
		}
	    } else {
		if ($parentAllowed != 'y') {
		    $forbidden[] = $child;
		}
		$forbidden = array_merge($forbidden, $this->list_forbidden_categories($child, $parentAllowed));
	    }
	}
	return $forbidden;
    }
	function approve_submission($subId, $articleId) {
		$query = "update `tiki_categorized_objects` set `type`= ?, `objId`= ?, `href`=? where `objId` = ? and `type`= ?";
		$this->query($query, array('article', (int)$articleId, "tiki-read_article.php?articleId=$articleId", (int)$subId, 'submission') );
	}
	/* build the portion of list join if filter by category
	 */
	function getSqlJoin($categId, $objType, $sqlObj, &$fromSql, &$whereSql, &$bindVars) {
		$fromSql .= ",`tiki_categorized_objects` co, `tiki_category_objects` cat ";
		$whereSql .= " AND co.`type`=? AND co.`objId`= $sqlObj ";
		$whereSql .= " AND co.`catObjectId`=cat.`catObjectId` ";
		$whereSql .= " AND cat.`categId`= ? ";
		$bind = array( $objType, $categId);
		if (is_array($bindVars))
			$bindVars = array_merge($bindVars, $bind);
		else
			$bindVars = $bind;
	} 		
	function exist_child_category($parentId, $name) {
		$query = 'select `categId` from `tiki_categories` where `parentId`=? and `name`=?';
		return ($this->getOne($query, array((int)$parentId, $name)));
	}
}

global $dbTiki;
$categlib = new CategLib($dbTiki);

?>



-- FILE: tiki-admin_categories.php

Image
{CODE()}
<?php

// $Header: /cvsroot/tikiwiki/tiki/tiki-admin_categories.php,v 1.27.2.16 2007/06/12 17:43:15 nkoth Exp $

// Copyright (c) 2002-2007, Luis Argerich, Garland Foster, Eduardo Polidor, et. al.
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.

// Initialization
require_once('tiki-setup.php');

include_once('lib/categories/categlib.php');
include_once('lib/filegals/filegallib.php');
include_once('lib/polls/polllib.php');
include_once('lib/tree/categ_admin_tree.php');
include_once('lib/directory/dirlib.php');
include_once('lib/trackers/trackerlib.php');
include_once('lib/commentslib.php');


if (!isset($polllib)) {
$polllib = new PollLib($dbTiki);
}

if (!isset($commentslib)) {
$commentslib = new Comments($dbTiki);
}

if ($feature_categories != 'y') {
$smarty->assign('msg', tra("This feature is disabled").": feature_categories");

$smarty->display("error.tpl");
die;
}

if ($tiki_p_admin_categories != 'y') {
$smarty->assign('msg', tra("You do not have permission to use this feature"));

$smarty->display("error.tpl");
die;
}

// Check for parent category or set to 0 if not present
if (!isset($_REQUEST%22parentId%22)) {
$_REQUEST%22parentId%22 = 0;
}

$smarty->assign('parentId', $_REQUEST%22parentId%22);

if (isset($_REQUEST%22addpage%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize a page
// $categlib->categorize_page($_REQUEST%22pageName%22,$_REQUEST%22parentId%22);
// add multiple pages at once
foreach ($_REQUEST'pageName' as $value) {
$categlib->categorize_page($value, $_REQUEST%22parentId%22);
}
}

if (isset($_REQUEST%22addpoll%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize a poll
$categlib->categorize_poll($_REQUEST%22pollId%22, $_REQUEST%22parentId%22);
}

if (isset($_REQUEST%22addfaq%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize a faq
$categlib->categorize_faq($_REQUEST%22faqId%22, $_REQUEST%22parentId%22);
}

if (isset($_REQUEST%22addtracker%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize a tracker
$categlib->categorize_tracker($_REQUEST%22trackerId%22, $_REQUEST%22parentId%22);
}

if (isset($_REQUEST%22addquiz%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize a quiz
$categlib->categorize_quiz($_REQUEST%22quizId%22, $_REQUEST%22parentId%22);
}

if (isset($_REQUEST%22addforum%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize a forum
$categlib->categorize_forum($_REQUEST%22forumId%22, $_REQUEST%22parentId%22);
}

if (isset($_REQUEST%22addgallery%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize an image gallery
$categlib->categorize_gallery($_REQUEST%22galleryId%22, $_REQUEST%22parentId%22);
}

if (isset($_REQUEST%22addfilegallery%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize a file gallery
$categlib->categorize_file_gallery($_REQUEST%22file_galleryId%22, $_REQUEST%22parentId%22);
}

if (isset($_REQUEST%22addarticle%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize an article
$categlib->categorize_article($_REQUEST%22articleId%22, $_REQUEST%22parentId%22);
}

if (isset($_REQUEST%22addblog%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize a blog
$categlib->categorize_blog($_REQUEST%22blogId%22, $_REQUEST%22parentId%22);
}

if (isset($_REQUEST%22adddirectory%22) && $_REQUEST%22parentId%22 != 0) {
check_ticket('admin-categories');
// Here we categorize a directory category
$categlib->categorize_directory($_REQUEST%22directoryId%22, $_REQUEST%22parentId%22);
}

if $_REQUEST%22categId%22 {
$info = $categlib->get_category($_REQUEST%22categId%22);
} else {
$_REQUEST%22categId%22 = 0;

$info%22name%22 = '';
$info%22description%22 = '';
}

if $_REQUEST%22removeObject%22 {
$area = 'delcategobject';
if ($feature_ticketlib2 != 'y' or 'daconfirm') and isset($_SESSION[%22ticket_$area%22]" class="wiki wikinew text-danger tips isset">$_POST'daconfirm') and isset($_SESSION%22ticket_$area%22) {
key_check($area);
$categlib->remove_object_from_category($_REQUEST%22removeObject%22, $_REQUEST%22parentId%22);
} else {
key_get($area);
}
}

if $_REQUEST%22removeCat%22 {
$area = "delcateg";
if ($feature_ticketlib2 != 'y' or 'daconfirm') and isset($_SESSION[%22ticket_$area%22]" class="wiki wikinew text-danger tips isset">$_POST'daconfirm') and isset($_SESSION%22ticket_$area%22) {
key_check($area);
$categlib->remove_category($_REQUEST%22removeCat%22);
} else {
$confirmation = tra('Click here to delete this category');
key_get($area, $confirmation);
}
}

if (isset($_REQUEST%22save%22) && isset($_REQUEST%22name%22) && strlen($_REQUEST%22name%22) > 0) {
check_ticket('admin-categories');
// Save

if 'parentId', $_REQUEST'name'" class="wiki wikinew text-danger tips">$this_categId = $categlib->exist_child_category($_REQUEST'parentId', $_REQUEST'name'
&& ($this_categId != $_REQUEST'categId')) // - cjutzi added 3/8/2008 - to allow updates to cat (this was an edit)
{
$errors[]= tra('You can not create a category with a name already existing at this level');
}
else
if ($_REQUEST%22categId%22) {
if ($_REQUEST'parentId' == $_REQUEST'categId')
{
$smarty->assign('msg', tra("Category can`t be parent of itself"));
$smarty->display("error.tpl");
die;
}
else
$categlib->update_category($_REQUEST%22categId%22, $_REQUEST%22name%22, $_REQUEST%22description%22, $_REQUEST%22parentId%22);
} else {
$newcategId = $categlib->add_category($_REQUEST%22parentId%22, $_REQUEST%22name%22, $_REQUEST%22description%22);
if 'assign_perms'" class="wiki wikinew text-danger tips isset">$_REQUEST'assign_perms' {
if ($_REQUEST'parentId' == 0) {
$userlib->inherit_global_permissions($newcategId, 'category');
} else {
$newcategpath = $categlib->get_category_path($newcategId);
$numcats = count($newcategpath);
$inherit_from_parent = FALSE;
for ($i=$numcats-2; $i>=0; $i--) {
if ($userlib->object_has_one_permission($newcategpath$i'categId', 'category')) {
$userlib->copy_object_permissions($newcategpath$i'categId', $newcategId, 'category');
$inherit_from_parent = TRUE;
break 1;
}
}
if (!$inherit_from_parent) {
$userlib->inherit_global_permissions($newcategId, 'category');
}
}
}
}

$info%22name%22 = '';
$info%22description%22 = '';
$_REQUEST%22categId%22 = 0;
}

$smarty->assign('categId', $_REQUEST%22categId%22);
$smarty->assign('name', $info%22name%22);
$smarty->assign('description', $info%22description%22);

// If the parent category is not zero get the category path

if ($_REQUEST%22parentId%22) {
$path = $categlib->get_category_path($_REQUEST%22parentId%22);
$p_info = $categlib->get_category($_REQUEST%22parentId%22);
$father = $p_info%22parentId%22;
$categ_name = $p_info'name';
} else {
$path = "";
$father = 0;
$categ_name = tra('Top');
}

$smarty->assign('path', $path);
$smarty->assign('father', $father);
$smarty->assign('categ_name', $categ_name);

// -------------------
// Convert $childrens
//$debugger->var_dump('$children');
$ctall = $categlib->get_all_categories_ext();
$tree_nodes = array();
// was the beginning of coments


foreach ($ctall as $c) {
$tree_nodes[] = array(
"id" => $c%22categId%22,
"parent" => $c%22parentId%22,
"data" => '<a class="catname" href="tiki-admin_categories.php?parentId=' . $c%22categId%22 . '" title="' . tra(
'Child categories'). ':' . $c%22children%22 . ' ' . tra(
'Objects in category'). ':' . $c%22objects%22 . '">' . $c%22name%22 . '</a>',
"edit" =>
'<a class="link" href="tiki-admin_categories.php?parentId=' . $c%22parentId%22 . '&amp;categId=' . $c%22categId%22 . '#editcreate" title="' . tra(
'edit'). '"><img border="0" src="img/icons/edit.gif" /></a>',
"remove" =>
'<a class="link" href="tiki-admin_categories.php?parentId=' . $c%22parentId%22 . '&amp;removeCat=' . $c%22categId%22 . '" title="' . tra(
'remove'). '"><img border="0" src="img/icons2/delete.gif" /></a>',
"children" => $c%22children%22,
"objects" => $c%22objects%22
);
}

//$debugger->var_dump('$tree_nodes');
$tm = new CatAdminTreeMaker("admcat");
$res = $tm->make_tree($_REQUEST%22parentId%22, $tree_nodes);
$smarty->assign('tree', $res);
// was end of comment
// -------------------
function array_csort($marray, $column) {
if (is_array($marray)) {
$sortarr = array();
foreach ($marray as $key=>$row) {
$sortarr$key = $row$column;
}
array_multisort($sortarr, $marray); return $marray;
} else {
return array();
}
}

$catree = $categlib->list_all_categories(0,-1,'name_asc',,,0);

// if this was an edit.. kill the catagepath in all the list.. otherwise the user can put an infinite loop in here */

// cjutzi - added 3/8/2008 to target coorectly the root tap in menu
$smarty->assign('parentId', $_REQUEST%22parentId%22);
// cjutzi - added 3/8/2008 to — NO SELECT — itself
if ($_REQUEST%22categId%22)
{
$newArray = array();
$i = 0;
foreach ($catree%22data%22 as $bar)
{
if ($bar%22categId%22 == $_REQUEST%22categId%22)
$bar%22categpath%22 = 'NO SELECT';
{
$newArray$i=$bar;
$i++;
}
}
$catree%22data%22 = $newArray;
}
$smarty->assign('catree', $catree'data');
$smarty->assign('deep', 'off');

// var_dump($catree);

// -------------------

$smarty->assign('assign_perms', 'checked');

if (!isset($_REQUEST%22sort_mode%22)) {
$sort_mode = 'name_asc';
} else {
$sort_mode = $_REQUEST%22sort_mode%22;
}

if (!isset($_REQUEST%22offset%22)) {
$offset = 0;
} else {
$offset = $_REQUEST%22offset%22;
}

$smarty->assign_by_ref('offset', $offset);

if $_REQUEST%22find%22 {
$find = $_REQUEST%22find%22;
} else {
$find = '';
}

$smarty->assign('find', $find);

if $_REQUEST%22find_objects%22 {
$find_objects = $_REQUEST%22find_objects%22;
} else {
$find_objects = '';
}

$smarty->assign('find_objects', $find_objects);

$smarty->assign_by_ref('sort_mode', $sort_mode);
$smarty->assign_by_ref('find', $find);
$objects = $categlib->list_category_objects($_REQUEST%22parentId%22, $offset, $maxRecords, $sort_mode, '', $find, false);
$smarty->assign_by_ref('objects', $objects%22data%22);

$cant_pages = ceil($objects%22cant%22 / $maxRecords);
$smarty->assign_by_ref('cant_pages', $cant_pages);
$smarty->assign('actual_page', 1 + ($offset / $maxRecords));

if ($objects%22cant%22 > ($offset + $maxRecords)) {
$smarty->assign('next_offset', $offset + $maxRecords);
} else {
$smarty->assign('next_offset', -1);
}

// If offset is > 0 then prev_offset
if ($offset > 0) {
$smarty->assign('prev_offset', $offset - $maxRecords);
} else {
$smarty->assign('prev_offset', -1);
}
/*
$categories = $categlib->get_all_categories();
$smarty->assign_by_ref('categories', $categories);

  • /

$galleries = $tikilib->list_galleries(0, -1, 'name_desc', 'admin', $find_objects);
$smarty->assign_by_ref('galleries', $galleries%22data%22);

$file_galleries = $filegallib->list_file_galleries(0, -1, 'name_desc', 'admin', $find_objects);
$smarty->assign_by_ref('file_galleries', $file_galleries%22data%22);

$forums = $commentslib->list_forums(0, -1, 'name_asc', $find_objects);
$smarty->assign_by_ref('forums', $forums%22data%22);

$polls = $polllib->list_polls(0, -1, 'title_asc', $find_objects);
$smarty->assign_by_ref('polls', $polls%22data%22);

$blogs = $tikilib->list_blogs(0, -1, 'title_asc', $find_objects);
$smarty->assign_by_ref('blogs', $blogs%22data%22);

$pages = $tikilib->list_pageNames(0, -1, 'pageName_asc', $find_objects);
$smarty->assign_by_ref('pages', $pages%22data%22);

$faqs = $tikilib->list_faqs(0, -1, 'title_asc', $find_objects);
$smarty->assign_by_ref('faqs', $faqs%22data%22);

$quizzes = $tikilib->list_quizzes(0, -1, 'name_asc', $find_

Importance
8
Priority
40
Demonstrate Bug
Please demonstrate your bug on show2.tikiwiki.org
 About show2.tikiwiki.org

To help developers solve the bug, we kindly request that you demonstrate your bug on a show2.tikiwiki.org instance. To start, simply select a version and click on "Create show2.tikiwiki.org instance". Once the instance is ready (in a minute or two), as indicated in the status window below, you can then access that instance, login (the initial admin username/password is "admin") and configure the Tiki to demonstrate your bug. Priority will be given to bugs that have been demonstrated on show2.tikiwiki.org.

Version: Create show2.tikiwiki.org instance
Ticket ID
1605
Created
Thursday 06 March, 2008 22:44:28 GMT-0000
LastModif
Thursday 21 November, 2013 17:37:08 GMT-0000

Attachments

 filenamecreatedhitscommentversionfiletype 
No attachments for this item


Keywords

The following is a list of keywords that should serve as hubs for navigation within the Tiki development and should correspond to documentation keywords.

Each feature in Tiki has a wiki page which regroups all the bugs, requests for enhancements, etc. It is somewhat a form of wiki-based project management. You can also express your interest in a feature by adding it to your profile. You can also try out the Dynamic filter.

Accessibility (WAI & 508)
Accounting
Administration
Ajax
Articles & Submissions
Backlinks
Banner
Batch
BigBlueButton audio/video/chat/screensharing
Blog
Bookmark
Browser Compatibility
Calendar
Category
Chat
Comment
Communication Center
Consistency
Contacts Address book
Contact us
Content template
Contribution
Cookie
Copyright
Credits
Custom Home (and Group Home Page)
Database MySQL - MyISAM
Database MySQL - InnoDB
Date and Time
Debugger Console
Diagram
Directory (of hyperlinks)
Documentation link from Tiki to doc.tiki.org (Help System)
Docs
DogFood
Draw -superseded by Diagram
Dynamic Content
Preferences
Dynamic Variable
External Authentication
FAQ
Featured links
Feeds (RSS)
File Gallery
Forum
Friendship Network (Community)
Gantt
Group
Groupmail
Help
History
Hotword
HTML Page
i18n (Multilingual, l10n, Babelfish)
Image Gallery
Import-Export
Install
Integrator
Interoperability
Inter-User Messages
InterTiki
jQuery
Kaltura video management
Karma
Live Support
Logs (system & action)
Lost edit protection
Mail-in
Map
Menu
Meta Tag
Missing features
Visual Mapping
Mobile
Mods
Modules
MultiTiki
MyTiki
Newsletter
Notepad
OS independence (Non-Linux, Windows/IIS, Mac, BSD)
Organic Groups (Self-managed Teams)
Packages
Payment
PDF
Performance Speed / Load / Compression / Cache
Permission
Poll
Profiles
Quiz
Rating
Realname
Report
Revision Approval
Scheduler
Score
Search engine optimization (SEO)
Search
Security
Semantic links
Share
Shopping Cart
Shoutbox
Site Identity
Slideshow
Smarty Template
Social Networking
Spam protection (Anti-bot CATPCHA)
Spellcheck
Spreadsheet
Staging and Approval
Stats
Survey
Syntax Highlighter (Codemirror)
Tablesorter
Tags
Task
Tell a Friend
Terms and Conditions
Theme
TikiTests
Timesheet
Token Access
Toolbar (Quicktags)
Tours
Trackers
TRIM
User Administration
User Files
User Menu
Watch
Webmail and Groupmail
WebServices
Wiki History, page rename, etc
Wiki plugins extends basic syntax
Wiki syntax text area, parser, etc
Wiki structure (book and table of content)
Workspace and perspectives
WYSIWTSN
WYSIWYCA
WYSIWYG
XMLRPC
XMPP




Useful Tools