PageRenderTime 181ms CodeModel.GetById 60ms app.highlight 55ms RepoModel.GetById 16ms app.codeStats 0ms

/role-scoper/role-scoper_init.php

https://github.com/adityag2/suneha
PHP | 1047 lines | 703 code | 259 blank | 85 comment | 221 complexity | 22b40c3913f2ed646418c8cd4c6ae2c9 MD5 | raw file
   1<?php
   2if( basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME']) )
   3	die();
   4
   5require_once( dirname(__FILE__).'/hardway/cache-persistent.php');
   6
   7//if ( ! awp_ver( '3.0' ) )
   8//	require_once( dirname(__FILE__).'/wp-legacy_rs.php' );
   9
  10// As of WP 3.0, this is not set until admin_header is loaded, and remains unset for non-admin urls.  To simplify subsequent checks, set it early and universally.
  11$GLOBALS['plugin_page_cr'] = ( is_admin() && isset( $_GET['page'] ) ) ? $_GET['page'] : '';
  12
  13if ( is_admin() )
  14	require_once( dirname(__FILE__).'/admin/admin-init_rs.php' );
  15	
  16if ( IS_MU_RS )
  17	require_once( dirname(__FILE__).'/mu-init_rs.php' );
  18
  19if ( IS_MU_RS || defined('SCOPER_FORCE_FILE_INCLUSIONS') ) {
  20	// workaround to avoid file error on get_home_path() call
  21	if ( file_exists( ABSPATH . '/wp-admin/includes/file.php' ) )
  22		include_once( ABSPATH . '/wp-admin/includes/file.php' );	
  23}
  24
  25// If an htaccess regeneration is triggered by somebody else, insert our rules (normal non-MU installations).
  26if ( ! defined( 'SCOPER_NO_HTACCESS' ) )
  27	add_filter( 'mod_rewrite_rules', 'scoper_mod_rewrite_rules' );
  28
  29add_action( 'delete_option', 'scoper_maybe_rewrite_inclusions' );
  30add_action( 'delete_transient_rewrite_rules', 'scoper_rewrite_inclusions' );
  31
  32// some options can be overridden by constant definition
  33add_filter( 'site_options_rs', 'scoper_apply_constants', 99 );
  34add_filter( 'options_rs', 'scoper_apply_constants', 99 );
  35
  36function scoper_log_init_action() {
  37	define ( 'INIT_ACTION_DONE_RS', true );
  38
  39	require_once( dirname(__FILE__).'/db-config_rs.php');
  40	
  41	$func = "require('" . dirname(__FILE__) . "/db-config_rs.php');";
  42	add_action( 'switch_blog', create_function( '', $func ) );
  43	
  44	if ( is_admin() )
  45		scoper_load_textdomain();
  46
  47	elseif ( defined('XMLRPC_REQUEST') )
  48		require_once( dirname(__FILE__).'/xmlrpc_rs.php');
  49}
  50
  51function scoper_act_set_current_user() {
  52	$id = ( ! empty($GLOBALS['current_user']) ) ? $GLOBALS['current_user']->ID : 0;
  53
  54	if ( defined('MULTISITE') && MULTISITE ) {
  55		scoper_version_check();
  56	}
  57
  58	if ( $id || defined( 'SCOPER_ANON_METAGROUP' ) ) {
  59		require_once( dirname(__FILE__).'/scoped-user.php');
  60		$GLOBALS['current_rs_user'] = new WP_Scoped_User($id);
  61		
  62		// other properties (blog_roles, assigned_term_roles, term_roles) will be set as populated
  63		foreach( array( 'groups', 'assigned_blog_roles' ) as $var ) {
  64			$GLOBALS['current_user']->$var = $GLOBALS['current_rs_user']->$var;
  65		}
  66	} else {
  67		require_once( dirname(__FILE__).'/scoped-user_anon.php');
  68		$GLOBALS['current_rs_user'] = new WP_Scoped_User_Anon();
  69	}
  70
  71	// since sequence of set_current_user and init actions seems unreliable, make sure our current_user is loaded first
  72	if ( ! empty( $GLOBALS['scoper'] ) )
  73		return;
  74	elseif ( defined('INIT_ACTION_DONE_RS') )
  75		scoper_init();
  76	else {
  77		static $done = false;
  78		if ( $done ) { return; } else { $done = true; }
  79		$priority = ( defined( 'SCOPER_EARLY_INIT' ) ) ? 3 : 50;
  80		add_action('init', 'scoper_init', $priority);
  81	}
  82}
  83
  84function scoper_init() {
  85	global $scoper;
  86
  87	// Work around bug in More Taxonomies (and possibly other plugins) where category taxonomy is overriden without setting it public
  88	foreach( array( 'category', 'post_tag' ) as $taxonomy ) {
  89		if ( isset( $GLOBALS['wp_taxonomies'][$taxonomy] ) )
  90			$GLOBALS['wp_taxonomies'][$taxonomy]->public = true;
  91	}
  92	
  93	if ( IS_MU_RS && agp_is_plugin_network_active( SCOPER_BASENAME ) ) {
  94		global $scoper_sitewide_options;
  95		$scoper_sitewide_options = apply_filters( 'sitewide_options_rs' , $scoper_sitewide_options );	
  96	}
  97
  98	require_once( dirname(__FILE__).'/wp-cap-helper_cr.php' );
  99	WP_Cap_Helper_CR::establish_status_caps();
 100	WP_Cap_Helper_CR::force_distinct_post_caps();
 101	WP_Cap_Helper_CR::force_distinct_taxonomy_caps();
 102	
 103	if ( is_admin() ) {
 104		require_once( dirname(__FILE__).'/admin/admin-init_rs.php' );	// TODO: why is the require statement up top not sufficient for NGG 1.7.2 uploader?
 105		scoper_admin_init();	
 106	}
 107
 108	//log_mem_usage_rs( 'scoper_admin_init done' );
 109		
 110	require_once( dirname(__FILE__).'/scoped-user.php');
 111	require_once( dirname(__FILE__).'/role-scoper_main.php');
 112	
 113	//log_mem_usage_rs( 'require role-scoper_main' );
 114	
 115	if ( empty($scoper) ) {		// set_current_user may have already triggered scoper creation and role_cap load
 116		$scoper = new Scoper();
 117		
 118		//log_mem_usage_rs( 'new Scoper done' );
 119		$scoper->init();
 120	}
 121
 122	// ensure that content administrators (as defined by SCOPER_CONTENT_ADMIN_CAP) have all caps for custom types by default
 123	if ( is_content_administrator_rs() ) {
 124		global $current_rs_user;
 125
 126		if ( ! empty($current_rs_user) ) { // user object not set when scoper_init() is manually invoked to support htaccess rule generation on plugin activation
 127			foreach ( get_post_types( array('public' => true, '_builtin' => false) ) as $name )
 128				$current_rs_user->assigned_blog_roles[ANY_CONTENT_DATE_RS]["rs_{$name}_editor"] = true;
 129			
 130			$taxonomies = get_taxonomies( array('public' => true, '_builtin' => false) );
 131			$taxonomies []= 'nav_menu';
 132			foreach ( $taxonomies as $name )
 133				$current_rs_user->assigned_blog_roles[ANY_CONTENT_DATE_RS]["rs_{$name}_manager"] = true;
 134			
 135			$current_rs_user->merge_scoped_blogcaps();
 136			$GLOBALS['current_user']->allcaps = array_merge( $GLOBALS['current_user']->allcaps, $current_rs_user->allcaps );
 137			$GLOBALS['current_user']->assigned_blog_roles = $current_rs_user->assigned_blog_roles;
 138		}
 139	}
 140	
 141	if ( ! empty($_GET['action']) && ( 'expire_file_rules' == $_GET['action'] ) ) {
 142		require_once( dirname(__FILE__).'/attachment-helper_rs.php' );
 143		scoper_requested_file_rule_expire();
 144	}
 145
 146	//log_mem_usage_rs( 'scoper->init() done' );
 147}
 148
 149function rs_get_user( $user_id, $name = '', $args = array() ) {
 150	if ( ! class_exists( 'WP_Scoped_User' ) )
 151		require_once( dirname(__FILE__).'/scoped-user.php');
 152	
 153	return new WP_Scoped_User( $user_id, $name, $args );
 154}
 155
 156function scoper_load_textdomain() {
 157	if ( defined( 'SCOPER_TEXTDOMAIN_LOADED' ) )
 158		return;
 159
 160	load_plugin_textdomain( 'scoper', false, SCOPER_FOLDER . '/languages' );
 161
 162	define('SCOPER_TEXTDOMAIN_LOADED', true);
 163}
 164
 165function scoper_get_init_options() {
 166	define ( 'SCOPER_CUSTOM_USER_BLOGCAPS', scoper_get_option('custom_user_blogcaps') );		// TODO: eliminate this?
 167	
 168	$define_groups = scoper_get_option('define_usergroups');
 169	define ( 'DEFINE_GROUPS_RS', $define_groups );
 170	define ( 'GROUP_ROLES_RS', $define_groups && scoper_get_option('enable_group_roles') );
 171	
 172	define ( 'USER_ROLES_RS', scoper_get_option('enable_user_roles') );
 173	
 174	if ( ! defined('DISABLE_PERSISTENT_CACHE') && ! scoper_get_option('persistent_cache') )
 175		define ( 'DISABLE_PERSISTENT_CACHE', true );
 176
 177	wpp_cache_init( IS_MU_RS && scoper_establish_group_scope() );
 178}
 179
 180function scoper_refresh_options() {
 181	if ( IS_MU_RS && agp_is_plugin_network_active( SCOPER_BASENAME ) ) {
 182		scoper_retrieve_options(true);
 183		scoper_refresh_options_sitewide();
 184	}
 185		
 186	scoper_retrieve_options(false);
 187	
 188	scoper_refresh_default_options();
 189}
 190
 191function scoper_set_conditional_defaults() {
 192	// if the WP installation has 100 or more users at initial Role Scoper installation, default to CSV input of username for role assignment	
 193	global $wpdb;
 194	$num_users = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->users" );
 195	if ( $num_users > 99 )
 196		update_option( 'scoper_user_role_assignment_csv', 1 );
 197}
 198
 199function scoper_refresh_default_options() {
 200	global $scoper_default_options;
 201
 202	require_once( dirname(__FILE__).'/defaults_rs.php');
 203	$scoper_default_options = apply_filters( 'default_options_rs', scoper_default_options() );
 204	
 205	if ( IS_MU_RS && agp_is_plugin_network_active( SCOPER_BASENAME ) )
 206		scoper_apply_custom_default_options( 'scoper_default_options' );
 207}
 208
 209function scoper_refresh_default_otype_options() {
 210	global $scoper_default_otype_options;
 211	
 212	require_once( dirname(__FILE__).'/defaults_rs.php');
 213	$scoper_default_otype_options = apply_filters( 'default_otype_options_rs', scoper_default_otype_options() );
 214	
 215	// compat workaround for old versions of Role Scoping for NGG which use old otype option key structure
 216	if ( isset( $scoper_default_otype_options['use_term_roles']['ngg_gallery:ngg_gallery'] ) && ( ! is_array($scoper_default_otype_options['use_term_roles']['ngg_gallery:ngg_gallery']) ) )
 217		$scoper_default_otype_options['use_term_roles']['ngg_gallery:ngg_gallery'] = array( 'ngg_album' => 1 );
 218		
 219	if ( IS_MU_RS && agp_is_plugin_network_active( SCOPER_BASENAME ) )
 220		scoper_apply_custom_default_options( 'scoper_default_otype_options' );
 221}
 222
 223function scoper_get_default_otype_options() {
 224	if ( did_action( 'scoper_init') ) {
 225		global $scoper_default_otype_options;
 226		
 227		if ( ! isset( $scoper_default_otype_options ) )
 228			scoper_refresh_default_otype_options();
 229			
 230		return $scoper_default_otype_options;
 231	} else
 232		return scoper_default_otype_options();	
 233}
 234
 235function scoper_delete_option( $option_basename, $sitewide = -1 ) {
 236	// allow explicit selection of sitewide / non-sitewide scope for better performance and update security
 237	if ( -1 === $sitewide ) {
 238		global $scoper_options_sitewide;
 239		$sitewide = isset( $scoper_options_sitewide ) && ! empty( $scoper_options_sitewide[$option_basename] );
 240	}
 241
 242	if ( $sitewide ) {
 243		global $wpdb;
 244		scoper_query( "DELETE FROM {$wpdb->sitemeta} WHERE site_id = '$wpdb->siteid' AND meta_key = 'scoper_$option_basename'" );
 245	} else 
 246		delete_option( "scoper_$option_basename" );
 247}
 248
 249function scoper_update_option( $option_basename, $option_val, $sitewide = -1 ) {
 250	// allow explicit selection of sitewide / non-sitewide scope for better performance and update security
 251	if ( -1 === $sitewide ) {
 252		global $scoper_options_sitewide;
 253		$sitewide = isset( $scoper_options_sitewide ) && ! empty( $scoper_options_sitewide[$option_basename] );
 254	}
 255	
 256	if ( $sitewide ) {
 257		global $scoper_site_options;
 258		$scoper_site_options[$option_basename] = $option_val;
 259		
 260		//d_echo("<br /><br />sitewide: $option_basename, value : " . maybe_serialize($option_val) );
 261		update_site_option( "scoper_$option_basename", $option_val );
 262	} else {
 263		//d_echo("<br />blogwide: $option_basename" );
 264		global $scoper_blog_options;
 265		$scoper_blog_options[$option_basename] = $option_val;
 266
 267		update_option( "scoper_$option_basename", $option_val );
 268	}
 269}
 270
 271function scoper_apply_constants($stored_options) {
 272	// If file filtering option is on but the DISABLE constant has been set, turn the option off and regenerate .htaccess
 273	if ( defined( 'DISABLE_ATTACHMENT_FILTERING' ) && DISABLE_ATTACHMENT_FILTERING ) {
 274		if ( ! empty( $stored_options['scoper_file_filtering'] ) ) {
 275			// in this case, we need to both convert the option value to constant value AND trigger .htaccess regeneration
 276			$stored_options['file_filtering'] = 0;
 277			update_option( 'scoper_file_filtering', 0 );
 278			scoper_flush_site_rules();
 279			scoper_expire_file_rules();	
 280		}
 281	}
 282
 283	return $stored_options; 
 284}
 285
 286function scoper_retrieve_options( $sitewide = false ) {
 287	global $wpdb;
 288	
 289	if ( $sitewide ) {
 290		global $scoper_site_options;
 291		
 292		$scoper_site_options = array();
 293
 294		if ( $results = scoper_get_results( "SELECT meta_key, meta_value FROM $wpdb->sitemeta WHERE site_id = '$wpdb->siteid' AND meta_key LIKE 'scoper_%'" ) )
 295			foreach ( $results as $row )
 296				$scoper_site_options[$row->meta_key] = $row->meta_value;
 297				
 298		$scoper_site_options = apply_filters( 'site_options_rs', $scoper_site_options );
 299		return $scoper_site_options;
 300
 301	} else {
 302		global $scoper_blog_options;
 303		
 304		$scoper_blog_options = array();
 305		
 306		if ( $results = scoper_get_results("SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE 'scoper_%'") )
 307			foreach ( $results as $row )
 308				$scoper_blog_options[$row->option_name] = $row->option_value;
 309				
 310		$scoper_blog_options = apply_filters( 'options_rs', $scoper_blog_options );
 311		return $scoper_blog_options;
 312	}
 313}
 314
 315
 316function scoper_get_site_option( $option_basename ) {
 317	return scoper_get_option( $option_basename, true );
 318}
 319
 320function scoper_get_option($option_basename, $sitewide = -1, $get_default = false) {
 321	global $scoper_default_options;
 322	
 323	//if ( empty( $scoper_default_options ) && did_action( 'scoper_init' ) )	// Make sure other plugins have had a chance to apply any filters to default options
 324	if ( empty( $scoper_default_options ) )
 325		scoper_refresh_default_options();
 326
 327	if ( ! $get_default ) {
 328		// allow explicit selection of sitewide / non-sitewide scope for better performance and update security
 329		if ( -1 === $sitewide ) {
 330			global $scoper_options_sitewide;
 331			$sitewide = isset( $scoper_options_sitewide ) && ! empty( $scoper_options_sitewide[$option_basename] );
 332		}
 333	
 334		//dump($scoper_options_sitewide);
 335		
 336		if ( $sitewide ) {
 337			// this option is set site-wide
 338			global $scoper_site_options;
 339			
 340			if ( ! isset($scoper_site_options) || is_null($scoper_site_options) )
 341				$scoper_site_options = scoper_retrieve_options( true );	
 342				
 343			if ( isset($scoper_site_options["scoper_{$option_basename}"]) )
 344				$optval = $scoper_site_options["scoper_{$option_basename}"];
 345			
 346		} else {
 347			//dump($option_basename);
 348			global $scoper_blog_options;
 349			
 350			if ( ! isset($scoper_blog_options) || is_null($scoper_blog_options) )
 351				$scoper_blog_options = scoper_retrieve_options( false );	
 352				
 353			if ( isset($scoper_blog_options["scoper_$option_basename"]) )
 354				$optval = $scoper_blog_options["scoper_$option_basename"];
 355		}
 356	}
 357	
 358	//dump($get_default);
 359	//dump($scoper_blog_options);
 360
 361	if ( ! isset( $optval ) ) {
 362		if ( ! empty($scoper_default_options) && ! empty( $scoper_default_options[$option_basename] ) )
 363			$optval = $scoper_default_options[$option_basename];
 364			
 365		if ( ! isset($optval) ) {
 366			global $scoper_default_otype_options;
 367			if ( isset( $scoper_default_otype_options[$option_basename] ) )
 368				return $scoper_default_otype_options[$option_basename];
 369			
 370			/*
 371			else {
 372				static $hardcode_option_defaults;
 373			
 374				if ( empty($hardcode_option_defaults) ) {
 375					require_once( dirname(__FILE__).'/defaults_rs.php');
 376					$hardcode_option_defaults = scoper_default_options();
 377				}
 378					
 379				if ( isset($hardcode_option_defaults[$option_basename]) )
 380					$optval = $hardcode_option_defaults[$option_basename];	
 381				else {
 382					static $hardcode_otype_option_defaults;
 383					
 384					if ( empty($hardcode_otype_option_defaults) )
 385						$hardcode_otype_option_defaults = scoper_default_otype_options();
 386					
 387					if ( isset($hardcode_otype_option_defaults[$option_basename]) )
 388						$optval = $hardcode_otype_option_defaults[$option_basename];	
 389				}	
 390			}
 391			*/
 392		}
 393	}
 394
 395	if ( isset($optval) )
 396		$optval = maybe_unserialize($optval);
 397	else
 398		$optval = '';
 399		
 400	// merge defaults into stored option array
 401	//if ( ! empty( $GLOBALS['scoper_option_arrays'][$option_basename] ) ) {
 402		
 403	if ( 'use_post_types' == $option_basename ) {
 404		static $default_post_types;
 405		if ( empty($default_post_types) || ! did_action('init') ) {
 406			$default_post_types = array();
 407			
 408			foreach ( array_diff( get_post_types( array( 'public' => true ) ), array( 'attachment' ) ) as $type )
 409				$default_post_types[$type] = 1;
 410		}
 411		
 412		$optval = array_merge( $default_post_types, (array) $optval );
 413
 414	} elseif ( 'use_taxonomies' == $option_basename ) {	
 415		static $default_taxonomies;
 416		if ( empty($default_taxonomies) || ! did_action('init') ) {
 417			$default_taxonomies = array();
 418			
 419			$taxonomies = get_taxonomies( array( 'public' => true ) );
 420			$taxonomies[] = 'nav_menu';
 421
 422			foreach ( $taxonomies as $taxonomy )
 423				$default_taxonomies[$taxonomy] = ( isset( $GLOBALS['rs_default_disable_taxonomies'][$taxonomy] ) ) ? 0 : 1;
 424		}
 425		
 426		$optval = array_diff_key( array_merge( $default_taxonomies, (array) $optval ), $GLOBALS['rs_forbidden_taxonomies'] );  // remove forbidden taxonomies, even if previously stored
 427	} elseif ( 'use_term_roles' == $option_basename ) {
 428		if ( $optval ) {
 429			foreach( array_keys($optval) as $key ) {
 430				$optval[$key] = array_diff_key( $optval[$key], $GLOBALS['rs_forbidden_taxonomies'] ); // remove forbidden taxonomies, even if previously stored
 431			}
 432		}
 433	}
 434	
 435	return $optval;
 436}
 437
 438function scoper_get_otype_option( $option_main_key, $src_name, $object_type = '', $access_name = '')  {
 439	static $otype_options;
 440
 441	// make sure we indicate object roles disabled if object type usage is completely disabled
 442	if ( 'use_object_roles' == $option_main_key ) {
 443		if ( ( 'post' == $src_name ) && $object_type ) {
 444			$use_object_types = scoper_get_option( 'use_post_types' );
 445			if ( ( ! empty($use_object_types) ) && empty( $use_object_types[$object_type] ) )	// since default is to enable all object types, don't interfere if no use_object_types option is stored
 446				return false;
 447		}
 448	}
 449	
 450	$key = "$option_main_key,$src_name,$object_type,$access_name";
 451
 452	if ( empty($otype_options) )
 453		$otype_options = array();
 454	elseif ( isset($otype_options[$key]) )
 455		return $otype_options[$key];
 456
 457	$stored_option = scoper_get_option($option_main_key);
 458
 459	$default_otype_options = scoper_get_default_otype_options();
 460	
 461	// RS stores all portions of the otype option array together, but blending is needed because RS Extensions or other plugins can filter the default otype options array for specific taxonomies / object types
 462	$optval = awp_blend_option_array( 'scoper_', $option_main_key, $default_otype_options, 1, $stored_option );
 463	
 464	// note: access_name-specific entries are not valid for most otype options (but possibly for teaser text front vs. rss)
 465	if ( isset ( $optval[$src_name] ) )
 466		$retval = $optval[$src_name];
 467	
 468	if ( $object_type && isset( $optval["$src_name:$object_type"] ) )
 469		$retval = $optval["$src_name:$object_type"];
 470	
 471	if ( $object_type && $access_name && isset( $optval["$src_name:$object_type:$access_name"] ) )
 472		$retval = $optval["$src_name:$object_type:$access_name"];
 473	
 474
 475	// if no match was found for a source request, accept any non-empty otype match
 476	if ( ! $object_type && ! isset($retval) )
 477		foreach ( $optval as $src_otype => $val )
 478			if ( $val && ( 0 === strpos( $src_otype, "$src_name:" ) ) )
 479				$retval = $val;
 480
 481	if ( ! isset($retval) )
 482		$retval = array();
 483		
 484	$otype_options[$key] = $retval;
 485	
 486	return $retval;
 487}
 488
 489function is_taxonomy_used_rs( $taxonomy ) {
 490	global $scoper_default_otype_options;
 491
 492	$stored_option = (array) scoper_get_option( 'use_term_roles' );
 493	foreach( array_merge( array_keys($scoper_default_otype_options['use_term_roles']), array_keys($stored_option) ) as $key ) {
 494		$term_roles[$key] = ( isset($scoper_default_otype_options['use_term_roles'][$key]) ) ? $scoper_default_otype_options['use_term_roles'][$key] : array();
 495		
 496		if ( isset( $stored_option[$key] ) )
 497			$term_roles[$key] =	array_merge( $term_roles[$key], $stored_option[$key] );
 498	}
 499
 500	foreach ( $term_roles as $taxonomies )  // keyed by src_otype
 501		if ( ! empty( $taxonomies[$taxonomy] ) )
 502			return true;
 503}
 504
 505function scoper_maybe_rewrite_inclusions ( $option_name = '' ) {
 506	if ( $option_name == 'rewrite_rules' )
 507		scoper_rewrite_inclusions();
 508}
 509
 510function scoper_rewrite_inclusions ( $option_name = '' ) {
 511	// force inclusion of required files in case flush_rules() is called from outside wp-admin, to prevent error when calling get_home_path() function
 512	if ( file_exists( ABSPATH . '/wp-admin/includes/misc.php' ) )
 513		include_once( ABSPATH . '/wp-admin/includes/misc.php' );
 514	
 515	if ( file_exists( ABSPATH . '/wp-admin/includes/file.php' ) )
 516		include_once( ABSPATH . '/wp-admin/includes/file.php' );	
 517}
 518
 519// htaccess directive intercepts direct access to uploaded files, converts to WP call with custom args to be caught by subsequent parse_query filter
 520// parse_query filter will return content only if user can read a containing post/page
 521function scoper_mod_rewrite_rules ( $rules ) {
 522	if ( defined( 'SCOPER_NO_HTACCESS' ) )
 523		return $rules;
 524	
 525	$file_filtering = scoper_get_option( 'file_filtering' );
 526
 527	global $scoper;
 528	if ( ! isset($scoper) || is_null($scoper) )
 529		scoper_init();
 530	
 531	require_once( dirname(__FILE__).'/rewrite-rules_rs.php' );
 532
 533	if ( IS_MU_RS ) {
 534		if ( $file_filtering ) {
 535			require_once( dirname(__FILE__).'/rewrite-mu_rs.php' );
 536			$rules = ScoperRewriteMU::insert_site_rules( $rules );
 537		}
 538	} else {
 539		if ( ! strpos( $rules, 'BEGIN Role Scoper' ) ) {
 540			$rs_rules = ScoperRewrite::build_site_rules();
 541			$rules .= $rs_rules;
 542		}
 543	}
 544
 545	return $rules;
 546}
 547
 548function scoper_flush_site_rules() {
 549	require_once( dirname(__FILE__).'/rewrite-rules_rs.php' );
 550	ScoperRewrite::update_site_rules( true );
 551}
 552
 553function scoper_clear_site_rules() {
 554	require_once( dirname(__FILE__).'/rewrite-rules_rs.php' );
 555	remove_filter('mod_rewrite_rules', 'scoper_mod_rewrite_rules');
 556	ScoperRewrite::update_site_rules( false );
 557}
 558
 559function scoper_flush_file_rules() {
 560	require_once( dirname(__FILE__).'/rewrite-rules_rs.php' );
 561	ScoperRewrite::update_blog_file_rules();
 562}
 563
 564
 565function scoper_clear_all_file_rules() {
 566	if ( IS_MU_RS ) {
 567		require_once( dirname(__FILE__).'/rewrite-mu_rs.php' );
 568		ScoperRewriteMU::clear_all_file_rules();
 569	} else {
 570		require_once( dirname(__FILE__).'/rewrite-rules_rs.php' );
 571		ScoperRewrite::update_blog_file_rules( false );
 572	} 
 573}
 574
 575
 576// forces content rules to be regenerated in every MU blog at next access
 577function scoper_expire_file_rules() {
 578	if ( IS_MU_RS )
 579		scoper_update_option( 'file_htaccess_min_date', agp_time_gmt(), true );
 580	else {
 581		if ( did_action( 'scoper_init' ) )
 582			scoper_flush_file_rules();  // for non-MU, just regenerate the file rules (for uploads folder) now
 583		else
 584			add_action( 'scoper_init', 'scoper_flush_file_rules' );
 585	}
 586}
 587
 588
 589function scoper_version_check() {
 590	$ver_change = false;
 591
 592	$ver = get_option('scoper_version');
 593	
 594	if ( empty($ver['db_version']) || version_compare( SCOPER_DB_VERSION, $ver['db_version'], '!=') ) {
 595		$ver_change = true;
 596		
 597		require_once( dirname(__FILE__).'/db-setup_rs.php');
 598		scoper_db_setup($ver['db_version']);
 599	}
 600
 601	// These maintenance operations only apply when a previous version of RS was installed 
 602	if ( ! empty($ver['version']) ) {
 603		
 604		if ( version_compare( SCOPER_VERSION, $ver['version'], '!=') ) {
 605			$ver_change = true;
 606			
 607			require_once( dirname(__FILE__).'/admin/update_rs.php');
 608			scoper_version_updated( $ver['version'] );
 609
 610			scoper_check_revision_settings();
 611		}
 612		
 613	} else {
 614		// first-time install (or previous install was totally wiped)
 615		require_once( dirname(__FILE__).'/admin/update_rs.php');
 616		scoper_set_default_rs_roledefs();
 617	}
 618
 619	if ( $ver_change ) {
 620		$ver = array(
 621			'version' => SCOPER_VERSION, 
 622			'db_version' => SCOPER_DB_VERSION
 623		);
 624		
 625		update_option( 'scoper_version', $ver );
 626	}
 627}
 628
 629function scoper_get_role_handle($role_name, $role_type) {
 630	return $role_type . '_' . str_replace(' ', '_', $role_name);
 631}
 632
 633function scoper_role_names_to_handles($role_names, $role_type, $fill_keys = false) {
 634	$role_names = (array) $role_names;	
 635
 636	$role_handles = array();
 637	foreach ( $role_names as $role_name )
 638		if ( $fill_keys )
 639			$role_handles[ $role_type . '_' . str_replace(' ', '_', $role_name) ] = 1;
 640		else
 641			$role_handles[]= $role_type . '_' . str_replace(' ', '_', $role_name);
 642			
 643	return $role_handles;
 644}
 645
 646function scoper_explode_role_handle($role_handle) {
 647	global $scoper_role_types;
 648	$arr = (object) array();
 649	
 650	foreach ( $scoper_role_types as $role_type ) {
 651		if ( 0 === strpos($role_handle, $role_type . '_') ) {
 652			$arr->role_type = $role_type;
 653			$arr->role_name = substr($role_handle, strlen($role_type) + 1);
 654			break;
 655		}
 656	}
 657	
 658	return $arr;
 659}
 660
 661function scoper_role_handles_to_names($role_handles) {
 662	global $scoper_role_types;
 663
 664	$role_names = array();
 665	foreach ( $role_handles as $role_handle ) {
 666		foreach ( $scoper_role_types as $role_type )
 667			$role_handle = str_replace( $role_type . '_', '', $role_handle);
 668			
 669		$role_names[] = $role_handle;
 670	}
 671	
 672	return $role_names;
 673}
 674
 675function rs_notice($message) {
 676	if ( defined( 'RS_DEBUG' ) ) {
 677		require_once( dirname(__FILE__).'/error_rs.php' );
 678		awp_notice( $message, 'Role Scoper' );
 679	}
 680}
 681
 682
 683// db wrapper methods allow us to easily avoid re-filtering our own query
 684function scoper_db_method($method_name, $query) {
 685	global $wpdb;
 686	//static $buffer;
 687	
 688	if ( is_admin() ) { // Low-level query filtering is necessary due to WP API limitations pertaining to admin GUI.
 689						// But make sure we don't chew our own cud (currently not an issue for front end)
 690		global $scoper_status;
 691	
 692		if ( empty($scoper_status) )
 693			$scoper_status = (object) array();
 694			
 695		/*
 696		$use_buffer = ('query' != $method_name ) && empty($_POST);
 697		
 698		if ( $use_buffer ) {
 699			$key = md5($query);
 700			if ( isset($buffer[$key]) )
 701				return $buffer[$key];
 702		}
 703		*/
 704
 705		$scoper_status->querying_db = true;
 706		$results = call_user_func( array(&$wpdb, $method_name), $query );
 707		$scoper_status->querying_db = false;
 708		
 709		//if ( $use_buffer )
 710		//	$buffer[$key] = $results;
 711		
 712		return $results;
 713	} else
 714		return call_user_func( array(&$wpdb, $method_name), $query );
 715}
 716
 717function scoper_get_results($query) {
 718	return scoper_db_method('get_results', $query);
 719}
 720
 721function scoper_get_row($query) {
 722	return scoper_db_method('get_row', $query);
 723}
 724
 725function scoper_get_col($query) {
 726	return scoper_db_method('get_col', $query);
 727}
 728
 729function scoper_get_var($query) {
 730	return scoper_db_method('get_var', $query);
 731}
 732
 733function scoper_query($query) {
 734	return scoper_db_method('query', $query);
 735}
 736
 737function scoper_querying_db() {
 738	if ( isset($GLOBALS['scoper_status']) )
 739		return ! empty($GLOBALS['scoper_status']->querying_db);
 740}
 741
 742function scoper_any_role_limits() {
 743	global $wpdb;
 744	
 745	$any_limits = (object) array( 'date_limited' => false, 'start_date_gmt' => false, 'end_date_gmt' => false, 'content_date_limited' => false, 'content_min_date_gmt' => false, 'content_max_date_gmt' => false );
 746
 747	if ( scoper_get_var( "SELECT assignment_id FROM $wpdb->user2role2object_rs WHERE date_limited > 0 LIMIT 1" ) ) {
 748		$any_limits->date_limited = true;
 749		
 750		if ( scoper_get_var( "SELECT assignment_id FROM $wpdb->user2role2object_rs WHERE start_date_gmt > 0 LIMIT 1" ) )
 751			$any_limits->start_date_gmt = true;
 752			
 753		if ( scoper_get_var( "SELECT assignment_id FROM $wpdb->user2role2object_rs WHERE end_date_gmt != '" . SCOPER_MAX_DATE_STRING . "' LIMIT 1" ) )
 754			$any_limits->end_date_gmt = true;
 755	}
 756	
 757	if ( scoper_get_var( "SELECT assignment_id FROM $wpdb->user2role2object_rs WHERE content_date_limited > 0 LIMIT 1" ) ) {
 758		$any_limits->content_date_limited = true;
 759		
 760		if ( scoper_get_var( "SELECT assignment_id FROM $wpdb->user2role2object_rs WHERE content_min_date_gmt > 0 LIMIT 1" ) )
 761			$any_limits->content_min_date_gmt = true;
 762			
 763		if ( scoper_get_var( "SELECT assignment_id FROM $wpdb->user2role2object_rs WHERE content_max_date_gmt != '" . SCOPER_MAX_DATE_STRING . "' LIMIT 1" ) )
 764			$any_limits->content_max_date_gmt = true;
 765	}
 766	
 767	return $any_limits;
 768}
 769
 770function scoper_get_duration_clause( $content_date_comparison = '', $table_prefix = 'uro', $enforce_duration_limits = true ) {
 771	static $any_role_limits;
 772	
 773	$clause = '';
 774	
 775	if ( $enforce_duration_limits && scoper_get_option( 'role_duration_limits' ) ) {
 776		if ( ! isset($any_role_limits) )
 777			$any_role_limits = scoper_any_role_limits();
 778		
 779		if ( $any_role_limits->date_limited ) {
 780			$current_time = current_time( 'mysql', 1 );
 781			
 782			$subclauses = array();
 783			
 784			if ( $any_role_limits->start_date_gmt )
 785				$subclauses []= "$table_prefix.start_date_gmt <= '$current_time'";
 786			
 787			if ( $any_role_limits->end_date_gmt )
 788				$subclauses []= "$table_prefix.end_date_gmt >= '$current_time'";
 789			
 790			$role_duration_clause = implode( " AND ", $subclauses );
 791
 792			$clause = " AND ( $table_prefix.date_limited = '0' OR ( $role_duration_clause ) ) ";
 793		}
 794	}
 795
 796	if ( $content_date_comparison && scoper_get_option( 'role_content_date_limits' ) ) {
 797		
 798		if ( ! isset($any_role_limits) )
 799			$any_role_limits = scoper_any_role_limits();
 800		
 801		if ( $any_role_limits->content_date_limited ) {
 802			$current_time = current_time( 'mysql', 1 );
 803			
 804			$subclauses = array();
 805			
 806			if ( $any_role_limits->content_min_date_gmt )
 807				$subclauses []= "$content_date_comparison >= $table_prefix.content_min_date_gmt";
 808			
 809			if ( $any_role_limits->content_max_date_gmt )
 810				$subclauses []= "$content_date_comparison <= $table_prefix.content_max_date_gmt";
 811			
 812			$content_date_clause = implode( " AND ", $subclauses );
 813
 814			$clause .= " AND ( $table_prefix.content_date_limited = '0' OR ( $content_date_clause ) ) ";
 815		}
 816	}
 817	
 818	return $clause;
 819}
 820
 821function scoper_get_property_array( &$arr, $id_prop, $buffer_prop ) {
 822	if ( ! is_array($arr) )
 823		return;
 824
 825	$buffer = array();
 826		
 827	foreach ( array_keys($arr) as $key )
 828		$buffer[ $arr[$key]->$id_prop ] = ( isset($arr[$key]->$buffer_prop) ) ? $arr[$key]->$buffer_prop : '';
 829
 830	return $buffer;
 831}
 832
 833function scoper_restore_property_array( &$target_arr, $buffer_arr, $id_prop, $buffer_prop ) {
 834	if ( ! is_array($target_arr) || ! is_array($buffer_arr) )
 835		return;
 836		
 837	foreach ( array_keys($target_arr) as $key )
 838		if ( isset( $buffer_arr[ $target_arr[$key]->$id_prop ] ) )
 839			$target_arr[$key]->$buffer_prop = $buffer_arr[ $target_arr[$key]->$id_prop ];
 840}
 841
 842function scoper_get_taxonomy_usage( $src_name, $object_types = '' ) {
 843	$taxonomies = array();
 844	$object_types = (array) $object_types;
 845
 846	foreach( $object_types as $object_type ) {
 847		if ( taxonomy_exists( $object_type ) )
 848			$use_taxonomies = array( $object_type => 1 );	// taxonomy management roles are always applied
 849		else
 850			$use_taxonomies = scoper_get_otype_option( 'use_term_roles', $src_name, $object_type );
 851
 852		$taxonomies = array_merge( $taxonomies, array_intersect( (array) $use_taxonomies, array( 1 ) ) );  // array cast prevents PHP warning on first-time execution following update to RS 1.2
 853	}
 854	
 855	if ( $taxonomies ) {
 856		// make sure we indicate non-usage of term roles for taxonomies that are completely disabled for RS
 857		if ( 'post' == $src_name ) {
 858			$use_taxonomies = scoper_get_option( 'use_taxonomies' );
 859			$taxonomies = array_intersect_key( $taxonomies, array_intersect( $use_taxonomies, array( 1 ) ) );
 860		}
 861		
 862		return array_keys($taxonomies);
 863	} else
 864		return array();
 865}
 866
 867function cr_find_post_type( $post_arg = '', $return_default = true ) {
 868	// the post argument is already an object.  Just return its post_type property
 869	if ( is_object( $post_arg ) )
 870		return $post_arg->post_type;
 871
 872	if ( $post_arg ) {
 873		// post_arg is not an object.  If its value matches global post, use that
 874		if ( ! empty($GLOBALS['post']) && is_object($GLOBALS['post']) && ( $post_arg == $GLOBALS['post']->ID ) && ( 'revision' != $GLOBALS['post']->post_type ) ) {
 875			$_type = $GLOBALS['post']->post_type;
 876
 877			if ( 'revision' == $_type )
 878				$_type = get_post_field( 'post_type', $GLOBALS['post']->post_parent );
 879		}
 880			
 881		// we have a post id but it doesn't match global post, so retrieve it
 882		if ( $_post = get_post( $post_arg ) ) {
 883			$_type = $_post->post_type;
 884			
 885			if ( 'revision' == $_type )
 886				$_type = get_post_field( 'post_type', $_post->post_parent );
 887		}
 888		
 889		if ( ! empty($_type) )
 890			return $_type;
 891	}
 892	
 893	// no post id was passed in, or we couldn't retrieve it for some reason, so check $_REQUEST args
 894	global $pagenow;
 895
 896	if ( ! empty( $GLOBALS['post'] ) && is_object($GLOBALS['post']) && ! empty( $GLOBALS['post']->post_type ) ) {
 897		$object_type = $GLOBALS['post']->post_type;
 898
 899		if ( 'revision' == $object_type )
 900			$object_type = get_post_field( 'post_type', $GLOBALS['post']->post_parent );
 901
 902	} elseif ( ! empty( $GLOBALS['wp_query']->queried_object ) && ! empty( $GLOBALS['wp_query']->queried_object->post_type ) ) {
 903		$object_type = $GLOBALS['wp_query']->queried_object->post_type;
 904		
 905	} elseif ( ! empty( $GLOBALS['wp_query']->queried_object ) && ! empty( $GLOBALS['wp_query']->queried_object->name ) ) {
 906		$object_type = $GLOBALS['wp_query']->queried_object->name;
 907		
 908	} elseif ( in_array( $pagenow, array( 'post-new.php', 'edit.php' ) ) ) {
 909		$object_type = ! empty( $_GET['post_type'] ) ? $_GET['post_type'] : 'post';
 910		
 911	} elseif ( in_array( $pagenow, array( 'edit-tags.php' ) ) ) {
 912		$object_type = ! empty( $_GET['taxonomy'] ) ? $_GET['taxonomy'] : 'category';
 913
 914	} elseif ( in_array( $pagenow, array( 'admin-ajax.php' ) ) && ! empty( $_REQUEST['taxonomy'] ) ) {
 915		$object_type = $_REQUEST['taxonomy'];
 916		
 917	} elseif ( ! empty( $_POST['post_ID'] ) ) {
 918		if ( $_post = get_post( $_POST['post_ID'] ) )
 919			$object_type = $_post->post_type;
 920				
 921	} elseif ( ! empty( $_GET['post'] ) ) {	 // post.php
 922		if ( $_post = get_post( $_GET['post'] ) )
 923			$object_type = $_post->post_type;
 924	
 925	} elseif( ! empty( $GLOBALS['scoper_object_type'] ) ) {
 926		$object_type = $GLOBALS['scoper_object_type'];
 927
 928	} elseif( ! empty($_SERVER) && is_array($_SERVER) && isset( $_SERVER['HTTP_REFERER'] ) && is_string($_SERVER['HTTP_REFERER']) ) {
 929		if ( $pos = strpos( $_SERVER['HTTP_REFERER'], '?' ) ) {
 930			$arg_str = substr( $_SERVER['HTTP_REFERER'], $pos + 1 );
 931			$args = wp_parse_args( $arg_str );
 932	
 933			if ( ! empty( $args['post'] ) ) {
 934				if ( $_post = get_post( $args['post'] ) ) {
 935					if ( isset( $_post->post_type ) ) {
 936						//rs_errlog( "cr_find_post_type - {$_post->post_type} from http_referer" );
 937						return $_post->post_type;
 938					}
 939				}
 940			}	
 941		}
 942	}
 943
 944	if ( empty($object_type) ) {
 945		if ( $return_default ) // default to post type
 946			return 'post';
 947	} elseif ( 'any' != $object_type ) {
 948		return $object_type;
 949	}
 950}
 951
 952function cr_find_object_type( $src_name, $object = '' ) {
 953	if ( 'post' == $src_name )
 954		return cr_find_post_type( $object );
 955	
 956	global $scoper;
 957	$src = $scoper->data_sources->get( $src_name );
 958	$object_id = ( is_object($object ) ) ? $src->cols->id : $object;
 959
 960	return $scoper->data_sources->detect( 'type', $src_name, $object_id );
 961}
 962
 963function cr_get_type_object( $src_name, $object_type ) {
 964	if ( 'post' == $src_name )
 965		return get_post_type_object( $object_type );
 966		
 967	global $scoper;
 968	return $scoper->data_sources->member_property( $src_name, 'object_types', $object_type );
 969}
 970
 971function scoper_get_object_id($src_name = 'post', $object_type = '') {
 972	global $scoper;
 973	return $scoper->data_sources->detect( 'id', $src_name, 0, $object_type );	
 974}
 975
 976
 977function is_administrator_rs( $src_or_tx = '', $admin_type = 'content', $user = '' ) {
 978	if ( ! $user ) {
 979		global $current_user;
 980		$user = $current_user;
 981		
 982		if ( IS_MU_RS && function_exists('is_super_admin') && is_super_admin() ) {
 983			return true;
 984		}
 985	}
 986
 987	if ( empty($user->ID) )
 988		return false;
 989		
 990	$return = '';
 991
 992	$admin_cap_name = scoper_get_administrator_cap( $admin_type );
 993	$return = ! empty( $user->allcaps[$admin_cap_name] );
 994	
 995	if ( ! $return && $src_or_tx && ! empty($GLOBALS['scoper']) ) {
 996		if ( ! is_object($src_or_tx) ) {
 997			global $scoper;
 998			if ( ! $src_or_tx = $scoper->data_sources->get( $src_or_tx ) )
 999				$src_or_tx = $scoper->taxonomies->get( $src_or_tx );
1000		}
1001			
1002		if ( is_object($src_or_tx) && ! empty($src_or_tx->defining_module) ) {
1003			if ( ! in_array( $src_or_tx->defining_module, array( 'role-scoper', 'wordpress', 'wp' ) ) ) {
1004				// user is not a universal administrator, but are they an administrator for the specified module (plugin-defined data source) ?
1005				static $admin_caps;
1006				
1007				if ( ! isset($admin_caps) )
1008					$admin_caps = apply_filters( 'define_administrator_caps_rs', array() );
1009		
1010				if ( ! empty( $admin_caps[ $src_or_tx->defining_module ] ) )
1011					$return = ! empty( $user->allcaps[ $admin_caps[ $src_or_tx->defining_module ] ] );
1012			}
1013		}
1014	}
1015	
1016	return $return;
1017}
1018
1019function is_option_administrator_rs( $user = '' ) {
1020	return is_administrator_rs( '', 'option', $user );
1021}
1022
1023function is_user_administrator_rs( $user = '' ) {
1024	return is_administrator_rs( '', 'user', $user );
1025} 
1026
1027function is_content_administrator_rs( $user = '' ) {
1028	return is_administrator_rs( '', 'content', $user );
1029}
1030
1031function scoper_get_administrator_cap( $admin_type ) {
1032	if ( ! $admin_type )
1033		$admin_type = 'content';
1034	
1035	// Note: to differentiate content administrator role, define a custom cap such as "administer_all_content", add it to a custom Role, and add the following line to wp-config.php: define( 'SCOPER_CONTENT_ADMIN_CAP', 'cap_name' );
1036	$default_cap = array( 'option' => 'manage_options', 'user' => 'edit_users', 'content' => 'activate_plugins' );
1037
1038	$constant_name = 'SCOPER_' . strtoupper($admin_type) . '_ADMIN_CAP';
1039	$cap_name = ( defined( $constant_name ) ) ? constant( $constant_name ) : $default_cap[$admin_type];
1040	
1041	if ( 'read' == $cap_name )	// avoid catostrophic mistakes
1042		$cap_name = $default_cap[$admin_type];
1043		
1044	return $cap_name;
1045}
1046
1047?>