<commit_before><?php
// (c) Copyright 2002-2014 by authors of the Tiki Wiki CMS Groupware Project
// 
// 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.
// $Id$


/**
 * Facade class of the permission subsystem. Once configured, the ::get()
 * static method can be used to obtain accessors for specific objects.
 * The accessor will contain all the rules applicable to the object.
 *
 * Sample usage:
 *   $perms = Perms::get( array(
 *       'type' => 'wiki page',
 *       'object' => 'HomePage',
 *   ) );
 *
 *   if ( $perms->view_calendar ) {
 *      // ...
 *   }
 *
 * Global permissions may be obtained using Perms::get() without a context.
 *
 * The facade also provides a convenient way to filter lists based on
 * permissions. Using the method will also used the underlying::bulk()
 * method to charge permissions for multiple objects at once and reduce
 * the amount of queries required.
 *
 * Sample usage:
 *   $pages = $tikilib->listpages();
 *
 *   $filtered = Perms::filter(
 *       array( 'type' => 'wiki page' ), 
 *       'object',
 *       $pages,
 *       array( 'object' => 'pageName' ),
 *       'view' );
 *
 * The sample above would return the data without elements not visible,
 * assuming tiki_p_view is required, in the same format as provided.
 * In a standard configuration, this filter would use a maximum of
 * 4 queries to the database, less if some elements were previously
 * loaded.
 *
 * The permission facade handles local caching of the decision rules,
 * meaning that calling the facade for the same object twice will not
 * cause multiple queries to the database. Rather, the same object will
 * be provided. Moreover, if two objects use the same rules, like two
 * objects with the same set of categories, the rules will be shared
 * between the two accessors.
 *
 * Configuration of the facade is required only once. Configuration
 * includes indicating which rules apply, which are the active groups
 * for the current user and a prefix for backwards compatibility. The 
 * rules are provided as a list of ResolverFactory objects. Each of
 * these objects will fetch the permissions applicable for the given
 * context. The first factory providing a Resolver for the context
 * will be the applicable set of rules. For example, when configured
 * with ObjectFactory, CategoryFactory and GlobalFactory, the facade
 * would first search for object permissions, if none are found, it
 * would fall back to categories and finally to globals. Global
 * guarentees a basic set of rules.
 *
 * The context is provided as an array for extensibility. Currently,
 * type and object are the only two known keys.
 *
 * Resolvers are group agnostic, meaning the same resolver will be
 * provided no matter which groups have been configured. This allows
 * for more caching possible. As a general rule, the permission sub-
 * system fetches all the information it may require and counts on
 * caching to have the extra cost diminished over multiple requests.
 *
 * The accessors are simply a binding between the groups and the
 * resolver that provides a convenient access to the permissions.
 * The introduction paragraphs mentionned accessors were build for
 * specific objects and shared when multiple requests were made. This
 * is in fact incorrect. A new accessor is built every time, however
 * those are very thin and they share a common resolver. These separate
 * instances allow to reconfigure the accessors depending on the
 * environment in which they are used. For example, the accessors are
 * configured with the global groups by default. However, they can be
 * replaced to evaluate the permissions for a different user.
 *
 * Each ResolverFactory will generate a hash from the context which
 * represents a unique key to the matching resolver it would provide.
 * The hash provided by the global factory is a constant key, the one
 * provided by the object factory is straightforward and the one
 * provided for categories is a list of all categories applicable to
 * the object. These hashes are used to shortcut the amount of
 * database queries executed by reusing as much data as possible.
 */
class Perms
{
	private static $instance;

	private $prefix = '';
	private $groups = array();
	private $factories = array();
	private $checkSequence = null;

	private $hashes = array();

	/** 
	 * Provides a new accessor configured with the global settings and
	 * a resolver appropriate to the context requested.
	 */
	public static function get( $context = array() )
	{
		if (! is_array($context)) {
			$args = func_get_args();<commit_msg>[DOC] Perms: Added some notes and an example about how to get perms for other users<commit_after><?php
// (c) Copyright 2002-2014 by authors of the Tiki Wiki CMS Groupware Project
// 
// 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.
// $Id$


/**
 * Facade class of the permission subsystem. Once configured, the ::get()
 * static method can be used to obtain accessors for specific objects.
 * The accessor will contain all the rules applicable to the object.
 *
 * Sample usage:
 *   $perms = Perms::get( array(
 *       'type' => 'wiki page',
 *       'object' => 'HomePage',
 *   ) );
 *
 *   if ( $perms->view_calendar ) {
 *      // ...
 *   }
 *
 * Global permissions may be obtained using Perms::get() without a context.
 *
 * The facade also provides a convenient way to filter lists based on
 * permissions. Using the method will also used the underlying::bulk()
 * method to charge permissions for multiple objects at once and reduce
 * the amount of queries required.
 *
 * Sample usage:
 *   $pages = $tikilib->listpages();
 *
 *   $filtered = Perms::filter(
 *       array( 'type' => 'wiki page' ), 
 *       'object',
 *       $pages,
 *       array( 'object' => 'pageName' ),
 *       'view' );
 *
 * The sample above would return the data without elements not visible,
 * assuming tiki_p_view is required, in the same format as provided.
 * In a standard configuration, this filter would use a maximum of
 * 4 queries to the database, less if some elements were previously
 * loaded.
 *
 * The permission facade handles local caching of the decision rules,
 * meaning that calling the facade for the same object twice will not
 * cause multiple queries to the database. Rather, the same object will
 * be provided. Moreover, if two objects use the same rules, like two
 * objects with the same set of categories, the rules will be shared
 * between the two accessors.
 *
 * Configuration of the facade is required only once. Configuration
 * includes indicating which rules apply, which are the active groups
 * for the current user and a prefix for backwards compatibility. The 
 * rules are provided as a list of ResolverFactory objects. Each of
 * these objects will fetch the permissions applicable for the given
 * context. The first factory providing a Resolver for the context
 * will be the applicable set of rules. For example, when configured
 * with ObjectFactory, CategoryFactory and GlobalFactory, the facade
 * would first search for object permissions, if none are found, it
 * would fall back to categories and finally to globals. Global
 * guarentees a basic set of rules.
 *
 * The context is provided as an array for extensibility. Currently,
 * type and object are the only two known keys.
 *
 * Resolvers are group agnostic, meaning the same resolver will be
 * provided no matter which groups have been configured. This allows
 * for more caching possible. As a general rule, the permission sub-
 * system fetches all the information it may require and counts on
 * caching to have the extra cost diminished over multiple requests.
 *
 * The accessors are simply a binding between the groups and the
 * resolver that provides a convenient access to the permissions.
 * The introduction paragraphs mentionned accessors were build for
 * specific objects and shared when multiple requests were made. This
 * is in fact incorrect. A new accessor is built every time, however
 * those are very thin and they share a common resolver. These separate
 * instances allow to reconfigure the accessors depending on the
 * environment in which they are used. For example, the accessors are
 * configured with the global groups by default. However, they can be
 * replaced to evaluate the permissions for a different user
 * by creating a new Perms_Context object before accessing the perms,
 * e.g.
 * 		$permissionContext = new Perms_Context($aUserName);
 *
 * Each ResolverFactory will generate a hash from the context which
 * represents a unique key to the matching resolver it would provide.
 * The hash provided by the global factory is a constant key, the one
 * provided by the object factory is straightforward and the one
 * provided for categories is a list of all categories applicable to
 * the object. These hashes are used to shortcut the amount of
 * database queries executed by reusing as much data as possible.
 */
class Perms
{
	private static $instance;

	private $prefix = '';
	private $groups = array();
	private $factories = array();
	private $checkSequence = null;

	private $hashes = array();

	/** 
	 * Provides a new accessor configured with the global settings and
	 * a resolver appropriate to the context requested.
	 */
	public static function get( $context = array() )
	{
		if (! is_array($context)) {
			$args = func_get_args();
{'fraction_non_alphanumeric': 0.06651423820411557, 'fraction_numerical': 0.0018707129494907504, 'mean_word_length': 3.6668283220174587, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6094001', 'n_tokens_mistral': 2403, 'n_tokens_neox': 2331, 'n_words': 1332}