Source for file category.php
Documentation is available at category.php
/* Reminder: always indent with 4 spaces (no tabs). */
// +---------------------------------------------------------------------------+
// +---------------------------------------------------------------------------+
// | Geeklog links category administration page. |
// +---------------------------------------------------------------------------+
// | Copyright (C) 2000-2009 by the following authors: |
// | Authors: Tony Bibbs - tony AT tonybibbs DOT com |
// | Mark Limburg - mlimburg AT users.sourceforge DOT net |
// | Jason Whittenburg - jwhitten AT securitygeeks DOT com |
// | Dirk Haun - dirk AT haun-online DOT de |
// | Euan McKay - info AT heatherengineering DOT com |
// +---------------------------------------------------------------------------+
// | This program is free software; you can redistribute it and/or |
// | modify it under the terms of the GNU General Public License |
// | as published by the Free Software Foundation; either version 2 |
// | of the License, or (at your option) any later version. |
// | This program is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | You should have received a copy of the GNU General Public License |
// | along with this program; if not, write to the Free Software Foundation, |
// | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
// +---------------------------------------------------------------------------+
* Geeklog links categories administration page.
* @copyright Copyright © 2000-2009
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
* @author Tony Bibbs, tony AT tonybibbs DOT com
* @author Mark Limburg, mlimburg AT users.sourceforge DOT net
* @author Jason Whittenburg, jwhitten AT securitygeeks DOT com
* @author Dirk Haun, dirk AT haun-online DOT de
* @author Euan McKay, info AT heatherengineering DOT com
* Geeklog common function library and Admin authentication
require_once '../../../lib-common.php';
require_once '../../auth.inc.php';
// Uncomment the line below if you need to debug the HTTP variables being passed
// to the script. This will sometimes cause errors but it will allow you to see
// the data being passed in a POST operation
// echo COM_debug($_POST);
COM_accessLog("User {$_USER['username']} tried to illegally access the link category administration screen.");
// +--------------------------------------------------------------------------+
// | Category administration functions |
// | Located here so that in the future, users can also have their own link |
// | collections with categories over which they have edit access. |
// +--------------------------------------------------------------------------+
// Returns a category tree of categories in the database to which
// the user has edit access
global $_CONF, $_TABLES, $_USER, $_IMAGE_TYPE, $LANG_ADMIN, $LANG_ACCESS,
$LANG_LINKS_ADMIN, $LANG_LINKS, $_LI_CONF;
require_once $_CONF['path_system'] . 'lib-admin.php';
$header_arr = array( # display 'text' and use table field 'field'
array('text' => $LANG_ADMIN['edit'], 'field' => 'edit', 'sort' => false),
array('text' => $LANG_LINKS_ADMIN[44], 'field' => 'addchild', 'sort' => false),
array('text' => $LANG_LINKS_ADMIN[30], 'field' => 'category', 'sort' => true),
array('text' => $LANG_ACCESS['access'], 'field' => 'access', 'sort' => false),
array('text' => $LANG_LINKS_ADMIN[33], 'field' => 'tid', 'sort' => true));
$defsort_arr = array('field' => 'category', 'direction' => 'asc');
$links_url = $_CONF['site_admin_url'] . '/plugins/links';
array('url' => $links_url . '/index.php',
'text' => $LANG_LINKS_ADMIN[53]),
array('url' => $links_url . '/index.php?mode=edit',
'text' => $LANG_LINKS_ADMIN[51]),
array('url' => $links_url . '/index.php?validate=enabled',
'text' => $LANG_LINKS_ADMIN[26]),
array('url' => $links_url . '/category.php',
'text' => $LANG_LINKS_ADMIN[50]),
array('url' => $links_url . '/category.php?mode=edit',
'text' => $LANG_LINKS_ADMIN[52]),
array('url' => $_CONF['site_admin_url'],
'text' => $LANG_ADMIN['admin_home'])
'form_url' => $_CONF['site_admin_url'] . '/plugins/links/category.php'
global $_CONF, $_TABLES, $_LI_CONF, $LANG_LINKS_ADMIN;
// get all children of present category
$sql = "SELECT cid,category,tid,owner_id,group_id,perm_owner,perm_group,perm_members,perm_anon "
. "FROM {$_TABLES['linkcategories']} "
. "ORDER BY pid,category";
for ($i = 0; $i < $nrows; $i++ ) {
$topic = DB_getItem($_TABLES['topics'], 'topic', "tid='{$A['tid']}'");
$A['topic_text'] = $topic;
// Returns form to create a new category or edit an existing one
global $_CONF, $_TABLES, $_USER, $MESSAGE,
$LANG_LINKS_ADMIN, $LANG_ADMIN, $LANG_ACCESS, $_LI_CONF;
// have parent id, so making a new subcategory
// get parent access rights
$result = DB_query("SELECT group_id,perm_owner,perm_group,perm_members,perm_anon FROM {$_TABLES['linkcategories']} WHERE cid='" . addslashes($pid) . "'");
$A['owner_id'] = $_USER['uid'];
} elseif (!empty($cid)) {
// have category id, so editing a category
$sql = "SELECT * FROM {$_TABLES['linkcategories']} WHERE cid='{$cid}'"
// nothing, so making a new top-level category
// get default access rights
$A['group_id'] = DB_getItem($_TABLES['groups'], 'grp_id', "grp_name='Links Admin'");
$A['owner_id'] = $_USER['uid'];
$A['pid'] = $_LI_CONF['root'];
$access = SEC_hasAccess($A['owner_id'], $A['group_id'], $A['perm_owner'],
$A['perm_group'], $A['perm_members'], $A['perm_anon']);
$T->set_file(array('page' => 'categoryeditor.thtml'));
$T->set_var('lang_pagetitle', $LANG_LINKS_ADMIN[28]);
$T->set_var('lang_link_list', $LANG_LINKS_ADMIN[53]);
$T->set_var('lang_new_link', $LANG_LINKS_ADMIN[51]);
$T->set_var('lang_validate_links', $LANG_LINKS_ADMIN[26]);
$T->set_var('lang_list_categories', $LANG_LINKS_ADMIN[50]);
$T->set_var('lang_new_category', $LANG_LINKS_ADMIN[52]);
$T->set_var('lang_admin_home', $LANG_ADMIN['admin_home']);
$T->set_var('instructions', $LANG_LINKS_ADMIN[29]);
$T->set_var('lang_category', $LANG_LINKS_ADMIN[30]);
$T->set_var('lang_cid', $LANG_LINKS_ADMIN[32]);
$T->set_var('lang_description', $LANG_LINKS_ADMIN[31]);
$T->set_var('lang_topic', $LANG_LINKS_ADMIN[33]);
$T->set_var('lang_parent', $LANG_LINKS_ADMIN[34]);
$T->set_var('lang_save', $LANG_ADMIN['save']);
$delbutton = '<input type="submit" value="' . $LANG_ADMIN['delete']
. '" name="mode"%s' . XHTML . '>';
$jsconfirm = ' onclick="return confirm(\'' . $MESSAGE[76] . '\');"';
$T->set_var('delete_option', sprintf($delbutton, $jsconfirm));
$T->set_var('delete_option_no_confirmation', sprintf($delbutton, ''));
$T->set_var('delete_option', '');
$T->set_var('lang_cancel', $LANG_ADMIN['cancel']);
$T->set_var('cid_value', $A['cid']);
$T->set_var('old_cid_value', $A['cid']);
$T->set_var('category_value', $A['category']);
$T->set_var('description_value', $A['description']);
$A['cid'] = COM_makeSid();
$T->set_var('cid_value', $A['cid']);
$T->set_var('old_cid_value', '');
$T->set_var('category_value', '');
$T->set_var('description_value', '');
$T->set_var('topic_list', $topics);
$alltopics = '<option value="all"';
if ($A['tid'] == 'all') {
$alltopics .= ' selected="selected"';
$alltopics .= '>' . $LANG_LINKS_ADMIN[35] . '</option>' . LB;
$T->set_var('topic_selection', '<select name="tid">' . $alltopics
. $topics . '</select>');
$num_links = $LANG_ADMIN['na'];
$nresult = DB_query("SELECT COUNT(*) AS count FROM {$_TABLES['links']} WHERE cid='{$cid}'" . COM_getPermSQL('AND'));
$T->set_var('lang_num_links', $LANG_LINKS_ADMIN[61]);
$T->set_var('num_links', $num_links);
$T->set_var('lang_accessrights', $LANG_ACCESS['accessrights']);
$T->set_var('lang_owner', $LANG_ACCESS['owner']);
$T->set_var('cat_ownerid', $A['owner_id']);
$T->set_var('lang_group', $LANG_ACCESS['group']);
$T->set_var('lang_permissions', $LANG_ACCESS['permissions']);
$T->set_var('lang_permissionskey', $LANG_ACCESS['permissionskey']);
$T->set_var('lang_perm_key', $LANG_ACCESS['permissionskey']);
$A['perm_group'], $A['perm_members'], $A['perm_anon']));
$T->set_var('lang_permissions_msg', $LANG_ACCESS['permmsg']);
$T->set_var('lang_lockmsg', $LANG_ACCESS['permmsg']);
$T->set_var('gltoken', $token);
$T->parse('output', 'page');
$retval .= $T->finish($T->get_var('output'));
* Save changes to category information
* input array values from form (unvalidated, unsafe)
* output string message giving outcome status of requested operation
function links_save_category($cid, $old_cid, $pid, $category, $description, $tid, $owner_id, $group_id, $perm_owner, $perm_group, $perm_members, $perm_anon)
global $_CONF, $_TABLES, $_USER, $LANG_LINKS, $LANG_LINKS_ADMIN, $_LI_CONF,
// Convert array values to numeric permission values
list ($perm_owner,$perm_group,$perm_members,$perm_anon) = SEC_getPermissionValues($perm_owner,$perm_group,$perm_members,$perm_anon);
// Remove any autotags the user doesn't have permission to use
if (empty($category) || empty($description)) {
// Check cid to make sure not illegal
if (($cid == addslashes($_LI_CONF['root'])) || ($cid == 'user')) {
if (!empty($cid) && ($cid != $old_cid)) {
// this is either a new category or an attempt to change the cid
// - check that cid doesn't exist yet
$ctrl = DB_getItem($_TABLES['linkcategories'], 'cid', "cid = '$cid'");
if (isset ($PLG_links_MESSAGE17)) {
// Check that they didn't delete the cid. If so, get the hidden one
if (empty($cid) && !empty($old_cid)) {
// Make sure they aren't making a parent category child of one of it's own
// children. This would create orphans
if ($cid == DB_getItem($_TABLES['linkcategories'], 'pid',"cid='{$pid}'")) {
if (DB_count ($_TABLES['linkcategories'], 'cid', $old_cid) > 0) {
// update existing item, but new cid so get access from database with old cid
$result = DB_query("SELECT owner_id,group_id,perm_owner,perm_group,perm_members,perm_anon FROM {$_TABLES['linkcategories']} WHERE cid='{$old_cid}'");
$access = SEC_hasAccess($A['owner_id'],$A['group_id'],$A['perm_owner'],
$A['perm_group'],$A['perm_members'],$A['perm_anon']);
} else if (DB_count ($_TABLES['linkcategories'], 'cid', $cid) > 0) {
// update existing item, same cid, so get access from database with existing cid
$result = DB_query("SELECT owner_id,group_id,perm_owner,perm_group, perm_members,perm_anon FROM {$_TABLES['linkcategories']} WHERE cid='{$cid}'");
$access = SEC_hasAccess($A['owner_id'],$A['group_id'],$A['perm_owner'],
$A['perm_group'],$A['perm_members'],$A['perm_anon']);
// new item, so use passed values
$access = SEC_hasAccess($owner_id, $group_id, $perm_owner, $perm_group,
$perm_members, $perm_anon);
// no access rights: user should not be here
if ($update == 'existing') {
// update an existing item but new cid
$sql = "UPDATE {$_TABLES['linkcategories']}
tid='{$tid}',category='{$category}',
description='{$description}',
owner_id='{$owner_id}',group_id='{$group_id}',
perm_owner='{$perm_owner}',perm_group='{$perm_group}',
perm_members='{$perm_members}',perm_anon='{$perm_anon}'
WHERE cid = '{$old_cid}'";
// Also need to update links for this category
$sql = "UPDATE {$_TABLES['links']} SET cid='{$cid}' WHERE cid='{$old_cid}'";
} else if ($update == 'same') {
// update an existing item
$sql = "UPDATE {$_TABLES['linkcategories']}
tid='{$tid}',category='{$category}',
description='{$description}',
owner_id='{$owner_id}',group_id='{$group_id}',
perm_owner='{$perm_owner}',perm_group='{$perm_group}',
perm_members='{$perm_members}',perm_anon='{$perm_anon}'
$sql = "INSERT INTO {$_TABLES['linkcategories']}
(cid, pid, category, description, tid,
owner_id, group_id, perm_owner, perm_group,
('{$cid}','{$pid}','{$category}',
'{$description}','{$tid}',
'{$owner_id}','{$group_id}','{$perm_owner}',
'{$perm_group}','{$perm_members}','{$perm_anon}')";
if (($update == 'existing') && ($cid != $old_cid)) {
return 10; // success message
* input $cid string category id number
* output string message about success of requested operation
global $_TABLES, $LANG_LINKS_ADMIN;
if (DB_count ($_TABLES['linkcategories'], 'cid', $cid) > 0) {
// item exists so check access rights
$result = DB_query("SELECT owner_id,group_id,perm_owner,perm_group,
perm_members,perm_anon FROM {$_TABLES['linkcategories']}
$access = SEC_hasAccess($A['owner_id'],$A['group_id'],$A['perm_owner'],
$A['perm_group'],$A['perm_members'],$A['perm_anon']);
// Check for subfolders and sublinks
$sf = DB_count($_TABLES['linkcategories'], 'pid', $cid);
$sl = DB_count($_TABLES['links'], 'cid', $cid);
if (($sf == 0) && ($sl == 0)) {
// No subfolder/links so OK to delete
DB_delete($_TABLES['linkcategories'], 'cid', $cid);
// Subfolders and/or sublinks exist so return a message
if (isset ($_REQUEST['mode'])) {
$mode = $_REQUEST['mode'];
$root = $_LI_CONF['root'];
if ((($mode == $LANG_ADMIN['delete']) && !empty ($LANG_ADMIN['delete'])) || ($mode== "delete")) {
if (isset ($_REQUEST['cid'])) {
. '/plugins/links/category.php');
COM_accessLog("User {$_USER['username']} tried to illegally delete link category $cid and failed CSRF checks.");
echo COM_refresh($_CONF['site_admin_url'] . '/index.php');
} elseif (($mode == $LANG_ADMIN['save']) && !empty($LANG_ADMIN['save']) && SEC_checkToken()) {
$_POST['pid'], $_POST['category'],
$_POST['perm_owner'], $_POST['perm_group'],
$_POST['perm_members'], $_POST['perm_anon']);
} else if ($mode == 'edit') {
if (isset ($_GET['pid'])) {
if (isset ($_GET['cid'])) {
// nothing, so list categories
if (isset ($_REQUEST['msg'])) {
|