<?php
 if (!defined('VB_ENTRY')) die('Access denied.');
/*======================================================================*\
   || #################################################################### ||
   || # vBulletin 4.0.0 Alpha 5
   || # ---------------------------------------------------------------- # ||
   || # Copyright ©2000-2009 Jelsoft Enterprises Ltd. All Rights Reserved. ||
   || # This file may not be redistributed in whole or significant part. # ||
   || # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
   || # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
   || #################################################################### ||
   \*======================================================================*/


/**
 * CMS Content Controller
 * Base content controller for CMS specific content types.
 *
 * @package vBulletin
 * @author Ed Brown, vBulletin Development Team
 * @version $Revision: 32150 $
 * @since $Date: 2009-09-21 17:39:41 -0500 (Mon, 21 Sep 2009) $
 * @copyright Jelsoft Enterprises Ltd.
 */

 /**
  * Class to return permissions
  *
  */

 class vBCMS_Permissions
{
	/**** Caching time in minutes for permissions info ********/
 	protected $cache_ttl = 5;

 	private static $permissionsfrom = array();

	public static function getUserPerms()
	{
		require_once DIR . '/includes/class_bootstrap_framework.php' ;
		vB_Bootstrap_Framework::init();
		$cache_ttl = 5;

		//See if we have a cached version
		if (!isset($_REQUEST['nocache']) AND vB::$vbulletin->userinfo['permissions']['cms'] = vB_Cache::instance()->read(self::getHash(), true))
		{
			return true;
		}

		$rst = vB::$vbulletin->db->query_read($sql = "SELECT nodeid,
		MAX(permissions & 1) AS canview, MAX(permissions & 2) AS cancreate , MAX(permissions & 4) AS canedit,
			MAX(permissions & 8) AS canpublish
			FROM " . TABLE_PREFIX . "cms_permissions p
			WHERE usergroupid IN (" . vB::$vbulletin->userinfo['usergroupid']
			. (strlen(vB::$vbulletin->userinfo['membergroupids']) ? ',' . vB::$vbulletin->userinfo['membergroupids'] : '')
			. ")
			GROUP BY nodeid; ");

		//We need to create four arrays
		vB::$vbulletin->userinfo['permissions']['cms']['canview'] = array();
		vB::$vbulletin->userinfo['permissions']['cms']['cancreate'] = array();
		vB::$vbulletin->userinfo['permissions']['cms']['canedit'] = array();
		vB::$vbulletin->userinfo['permissions']['cms']['canpublish'] = array();
		while($result = vB::$vbulletin->db->fetch_array($rst))
		{

			if ($result['canview'] OR $result['canedit'] OR $result['canpublish'])
			{
				vB::$vbulletin->userinfo['permissions']['cms']['canview'][] = $result['nodeid'];
			}

			if ($result['cancreate'])
			{
				vB::$vbulletin->userinfo['permissions']['cms']['cancreate'][] = $result['nodeid'];
			}

			if ($result['canedit'])
			{
				vB::$vbulletin->userinfo['permissions']['cms']['canedit'][] = $result['nodeid'];
			}

			if ($result['canpublish'])
			{
				vB::$vbulletin->userinfo['permissions']['cms']['canpublish'][] = $result['nodeid'];
			}
		}
		//when we use these in "where" clauses we'd better have at least one value.

		if (!count(vB::$vbulletin->userinfo['permissions']['cms']['canview']))
		{
			vB::$vbulletin->userinfo['permissions']['cms']['canview'][] = -1;
		}

		if (!count(vB::$vbulletin->userinfo['permissions']['cms']['cancreate']))
		{
			vB::$vbulletin->userinfo['permissions']['cms']['cancreate'][] = -1;
		}

		if (!count(vB::$vbulletin->userinfo['permissions']['cms']['canedit']))
		{
			vB::$vbulletin->userinfo['permissions']['cms']['canedit'][] = -1;
		}

		if (!count(vB::$vbulletin->userinfo['permissions']['cms']['canpublish']))
		{
			vB::$vbulletin->userinfo['permissions']['cms']['canpublish'][] = -1;
		}

		vB::$vbulletin->userinfo['permissions']['cms']['alledit'] =
				array_unique(array_merge(vB::$vbulletin->userinfo['permissions']['cms']['canedit'],
				vB::$vbulletin->userinfo['permissions']['cms']['cancreate'],
				vB::$vbulletin->userinfo['permissions']['cms']['canpublish']));


		vB::$vbulletin->userinfo['permissions']['cms']['viewonly'] =
			array_diff(vB::$vbulletin->userinfo['permissions']['cms']['canview'],
			vB::$vbulletin->userinfo['permissions']['cms']['alledit']);

		vB::$vbulletin->userinfo['permissions']['cms']['allview'] =
		array_unique(array_merge(vB::$vbulletin->userinfo['permissions']['cms']['alledit'],
		vB::$vbulletin->userinfo['permissions']['cms']['viewonly']));

		vB_Cache::instance()->write(self::getHash(),
			   vB::$vbulletin->userinfo['permissions']['cms'], $cache_ttl);
	}


	/****
	 * This resets permissions for a node, and it's surrounding nodes, should they be unassigned.
	 *
	 ****/
	private static function repairPermissions($nodeid)
	{
		//we start by generating a list of this node's parents. We go up the tree until
		// either we find a node with assigned permissions, or we hit the top.
		//If we hit the top, we use that node.
		require_once DIR . '/includes/class_bootstrap_framework.php' ;
		vB_Bootstrap_Framework::init();

		$parents = array();
		$rst = vB::$vbulletin->db->query_read("SELECT parent.nodeid,
		parent.permissionsfrom FROM " . TABLE_PREFIX . "cms_node AS parent INNER JOIN
		" . TABLE_PREFIX . "cms_node AS node ON node.nodeleft BETWEEN parent.nodeleft AND parent.noderight
			AND parent.nodeid <> node.nodeid
		WHERE node.nodeid = $nodeid ORDER BY node.nodeleft DESC");
		$permissionsfrom = 1;

		while($record = vB::$vbulletin->db->fetch_array($rst))
		{
			$parents[] = $record;

			if (intval($record['permissionsfrom']))
			{
				$permissionsfrom = $record['permissionsfrom'];
				break;
			}
		}
		//Now we go back down the list. Assign the node to the children at each level;
		foreach ($parents as $parent)
		{
			vB::$vbulletin->db->query_write("UPDATE ". TABLE_PREFIX . "cms_node SET permissionsfrom = $permissionsfrom
				WHERE permissionsfrom IS NULL AND parentnode = " . $parent['nodeid']);
		}

	}

 	/****
 	* This determines if the user can view a node
 	*
 	****/
 	public static function canView($nodeid)
	{

 		require_once DIR . '/includes/class_bootstrap_framework.php' ;
 		vB_Bootstrap_Framework::init();

 		if (! isset(vB::$vbulletin->userinfo['permissions']['cms']) )
 		{
 			self::getUserPerms();
 		}

 		if (array_key_exists ($nodeid, self::$permissionsfrom))
 		{
 			return (in_array(self::$permissionsfrom[$nodeid], vB::$vbulletin->userinfo['permissions']['cms']['allview']));
 		}

 		if (! $record = vB::$vbulletin->db->query_first("SELECT permissionsfrom FROM " .
 			TABLE_PREFIX . "cms_node WHERE nodeid = $nodeid"))
 		{
 			return false;
 		}
 		if (intval($record['permissionsfrom']))
 		{
 			self::$permissionsfrom[$nodeid] = intval($record['permissionsfrom']);
 			return (in_array($record['permissionsfrom'], vB::$vbulletin->userinfo['permissions']['cms']['allview']));
 		}
 		//if we got here, there's a problem. Repair and do it again.
		self::repairPermissions($nodeid);
		if (! $record = vB::$vbulletin->db->query_first("SELECT permissionsfrom FROM " .
			TABLE_PREFIX . "cms_node WHERE nodeid = $nodeid"))
		{
			return false;
		}
		if (intval($record['permissionsfrom']))
		{
			self::$permissionsfrom[$nodeid] = intval($record['permissionsfrom']);
			return (in_array($record['permissionsfrom'], vB::$vbulletin->userinfo['permissions']['cms']['canview']));
		}
 		return false;
	}

	public static function canEdit($nodeid)
	{
		require_once DIR . '/includes/class_bootstrap_framework.php' ;
		vB_Bootstrap_Framework::init();

		if (! isset(vB::$vbulletin->userinfo['permissions']['cms']) )
		{
			self::getUserPerms();
		}

		if (array_key_exists ($nodeid, self::$permissionsfrom))
		{
			return (in_array(self::$permissionsfrom[$nodeid], vB::$vbulletin->userinfo['permissions']['cms']['alledit']));
		}


		if (! $record = vB::$vbulletin->db->query_first("SELECT permissionsfrom FROM " .
			TABLE_PREFIX . "cms_node WHERE nodeid = $nodeid"))
		{
			return false;
		}

		//If we got here, we need to pull a record from the database.
		if (intval($record['permissionsfrom']))
		{
			self::$permissionsfrom[$nodeid] = intval($record['permissionsfrom']);
			return (in_array($record['permissionsfrom'], vB::$vbulletin->userinfo['permissions']['cms']['alledit']));
		}
		//if we got here, there's a problem. Repair and do it again.
		self::repairPermissions($nodeid);

		if (! $record = vB::$vbulletin->db->query_first("SELECT permissionsfrom FROM " .
			TABLE_PREFIX . "cms_node WHERE nodeid = $nodeid"))
		{
			return false;
		}

		if (intval($record['permissionsfrom']))
		{
			self::$permissionsfrom[$nodeid] = intval($record['permissionsfrom']);
			return (in_array($record['permissionsfrom'], vB::$vbulletin->userinfo['permissions']['cms']['alledit']));
		}
		return false;
	}

 	/** This function tells whether we can create a content node.
 	* The rules are: if we have publish rights we can create any type of content
 	* If we have create or edit we can create non-section types.
 	***/
 	public static function canCreate($nodeid, $contenttype)
 	{
		$sectiontype = vB_Types::instance()->getContentTypeID('vBCms_Section');

 		if (array_key_exists ($nodeid, self::$permissionsfrom))
 		{
 			if ($contenttype == $sectiontype)
 			{
 				return (in_array(self::$permissionsfrom[$nodeid], vB::$vbulletin->userinfo['permissions']['cms']['canpublish']));
 			}
 			return (in_array(self::$permissionsfrom[$nodeid], vB::$vbulletin->userinfo['permissions']['cms']['alledit']));
 		}

 		require_once DIR . '/includes/class_bootstrap_framework.php' ;
 		vB_Bootstrap_Framework::init();

 		if (! isset(vB::$vbulletin->userinfo['permissions']['cms']) )
 		{
 			self::getUserPerms();
 		}

 		if (! $record = vB::$vbulletin->db->query_first("SELECT permissionsfrom FROM " .
 			TABLE_PREFIX . "cms_node WHERE nodeid = $nodeid"))
 		{
 			return false;
 		}

 		if (intval($record['permissionsfrom']))
 		{
 			self::$permissionsfrom[$nodeid] = intval($record['permissionsfrom']);
 			if ($contenttype == $sectiontype)
 			{
 				return (in_array($record['permissionsfrom'], vB::$vbulletin->userinfo['permissions']['cms']['canpublish']));
 			}
 			return (in_array($record['permissionsfrom'], vB::$vbulletin->userinfo['permissions']['cms']['alledit']));
 		}

 		//if we got here, there's a problem. Repair and do it again.
 		self::repairPermissions($nodeid);

 		if (! $record = vB::$vbulletin->db->query_first("SELECT permissionsfrom FROM " .
 			TABLE_PREFIX . "cms_node WHERE nodeid = $nodeid"))
 		{
 			return false;
 		}

 		if (intval($record['permissionsfrom']))
 		{
 			self::$permissionsfrom[$nodeid] = intval($record['permissionsfrom']);
 			if ($contenttype == $sectiontype)
 			{
 				return (in_array($record['permissionsfrom'], vB::$vbulletin->userinfo['permissions']['cms']['canpublish']));
 			}
 			return (in_array($record['permissionsfrom'], vB::$vbulletin->userinfo['permissions']['cms']['alledit']));
 		}
 		return false;
 	}


	/********* Get a hash so we can cache the data
	 *
	 ********/
	protected static function getHash()
	{
		$context = new vB_Context('cms_priv' , array('userid' => vB::$vbulletin->userinfo['userid']));
		return strval($context);

	}


 }