function scoper_maybe_flush_site_rules($new_option_value, $old_option_value) { if ($old_option_value !== $new_option_value) { scoper_flush_site_rules(); } return $new_option_value; }
function _scoper_activate() { // set_current_user may have triggered DB setup already if (empty($GLOBALS['scoper_db_setup_done'])) { require_once dirname(__FILE__) . '/db-setup_rs.php'; $ver = (array) get_option('scoper_version'); $db_ver = isset($ver['db_version']) ? $ver['db_version'] : ''; scoper_db_setup($db_ver); } require_once dirname(__FILE__) . '/admin/admin_lib_rs.php'; ScoperAdminLib::sync_wproles(); scoper_flush_site_rules(); scoper_expire_file_rules(); }
function scoper_apply_constants($stored_options) { // If file filtering option is on but the DISABLE constant has been set, turn the option off and regenerate .htaccess if (defined('DISABLE_ATTACHMENT_FILTERING') && DISABLE_ATTACHMENT_FILTERING) { if (!empty($stored_options['scoper_file_filtering'])) { // in this case, we need to both convert the option value to constant value AND trigger .htaccess regeneration $stored_options['file_filtering'] = 0; update_option('scoper_file_filtering', 0); scoper_flush_site_rules(); scoper_expire_file_rules(); } } return $stored_options; }
function admin_head_base() { if (isset($_POST['rs_defaults'])) { // User asked to restore default options, so restore htaccess rule for attachment filtering (if it's not disabled) scoper_flush_site_rules(); scoper_expire_file_rules(); } }
function scoper_version_updated($prev_version) { if (function_exists('wpp_cache_flush')) { wpp_cache_flush_all_sites(); } // single-pass do loop to easily skip unnecessary version checks do { // roles were stored with invalid assign_for value under some conditions if (version_compare($prev_version, '1.3.45-beta', '<')) { global $wpdb; scoper_query("UPDATE {$wpdb->user2role2object_rs} SET assign_for = 'entity' WHERE assign_for = ''"); } // file filtering rules were not written for new attachments if restriction was based solely on category restrictions if (version_compare($prev_version, '1.3.29-beta', '<')) { scoper_flush_site_rules(); scoper_expire_file_rules(); } // Delete any roles or restrictions inappropriately stored for attachments, revisions or auto-drafts if (version_compare($prev_version, '1.3', '<')) { global $wpdb; scoper_query("DELETE FROM {$wpdb->user2role2object_rs} WHERE role_type = 'wp' AND scope='blog' AND obj_or_term_id = '0'"); scoper_sync_wproles(); scoper_query("DELETE FROM {$wpdb->role_scope_rs} WHERE src_or_tx_name = 'post' AND obj_or_term_id IN ( SELECT ID FROM {$wpdb->posts} WHERE post_type IN ('attachment', 'revision') OR post_status = 'auto-draft' )"); scoper_query("DELETE FROM {$wpdb->user2role2object_rs} WHERE src_or_tx_name = 'post' AND obj_or_term_id IN ( SELECT ID FROM {$wpdb->posts} WHERE post_type IN ('attachment', 'revision') OR post_status = 'auto-draft' )"); } // 1.3.RC4 changed RS cache path to subfolder, so flush the root-stored cache one last time (only for MU / Multisite due to potentially large # of folders, files) if (IS_MU_RS && version_compare($prev_version, '1.3.RC4', '<') && !defined('SKIP_CACHE_MAINT_RS')) { global $wpp_object_cache; $wpp_object_cache = new WP_Persistent_Object_Cache(false); $wpp_object_cache->global_groups = array(''); // forces use of cache root for this maint operation $wpp_object_cache->rm_cache_dir(''); // will delete any files and folders in cache root except .htaccess $wpp_object_cache->cache_enabled = false; // avoid further updating cache in this http session } // 1.2.8 Beta disabled caps for custom post type roles under some circumstances if (version_compare($prev_version, '1.2.7', '>') && version_compare($prev_version, '1.2.8', '<')) { if ($disabled_role_caps = get_option('scoper_disabled_role_caps')) { $okay_role_prefix = array('rs_post', 'rs_page', 'rs_category', 'rs_link', 'rs_ngg'); foreach (array_keys($disabled_role_caps) as $role_handle) { $role_okay = false; foreach ($okay_role_prefix as $pfx) { if (0 === strpos($role_handle, $pfx)) { $role_okay = true; break; } } if (!$role_okay) { unset($disabled_role_caps[$role_handle]); $_modified = true; } } if (!empty($_modified)) { update_option('scoper_disabled_role_caps', $disabled_role_caps); } } } // changes to taxonomy options storage in 1.1.8 if (version_compare($prev_version, '1.1.8', '<')) { global $wp_taxonomies; $enable_tx = get_option('scoper_enable_wp_taxonomies'); $old_use_term_roles = get_option('scoper_use_term_roles'); $use_term_roles = array(); if (is_array($old_use_term_roles)) { // convert existing use_term_roles entries to new array key structure foreach ($old_use_term_roles as $src_otype => $val) { if (is_array($val)) { // don't do this twice! break 2; } if (strpos($src_otype, ':')) { $arr_src_otype = explode(':', $src_otype); $src_name = $arr_src_otype[0]; if ('post' == $src_name) { $use_term_roles[$src_otype]['category'] = intval($val); } elseif ('link' == $src_name) { $use_term_roles[$src_otype]['link_category'] = intval($val); } elseif ('ngg_gallery' == $src_name) { $use_term_roles[$src_otype]['ngg_album'] = intval($val); } // compat workaround for old versions of Role Scoping for NGG which use old otype option key structure } } } if (is_array($enable_tx)) { // Post_tag and custom taxonomies were activated for scoping via enable_wp_taxonomies storage. Move those entries to use_term_roles instead. foreach ($enable_tx as $taxonomy => $val) { if ('post_tag' == $taxonomy) { $use_term_roles['post:post'][$taxonomy] = intval($val); } elseif ($taxonomy && !in_array($taxonomy, array('category', 'link_category'))) { if ($wp_tx = get_taxonomy($taxonomy)) { $object_types = (array) $wp_tx->object_type; foreach ($object_types as $object_type) { $use_term_roles["post:{$object_type}"][$taxonomy] = intval($val); } } } } } if ($use_term_roles) { update_option('scoper_use_term_roles', $use_term_roles); } //delete_option( 'scoper_enable_wp_taxonomies' ); } else { break; } if (version_compare($prev_version, '1.1', '<')) { // htaccess rules modified in v1.1 scoper_flush_site_rules(); scoper_expire_file_rules(); // Option update did not set autoload to no prior to 1.1 global $wpdb; $wpdb->query("UPDATE {$wpdb->options} SET autoload = 'no' WHERE option_name LIKE 'scoper_%' AND option_name != 'scoper_version'"); // stopped storing needless postmeta data for parent=0 in 1.1 global $wpdb; $wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE meta_value = '0' AND meta_key = '_scoper_last_parent'"); } else { break; } // stopped using rs_get_page_children() in 1.0.8 if (version_compare($prev_version, '1.0.8', '<')) { delete_option('scoper_page_children'); } else { break; } if (version_compare($prev_version, '1.0.0', '<')) { include dirname(__FILE__) . '/update-legacy_rs.php'; scoper_version_updated_from_legacy($prev_version); } } while (0); // end single-pass version check loop }
function &build_blog_file_rules() { $new_rules = ''; require_once dirname(__FILE__) . '/analyst_rs.php'; if (!($attachment_results = ScoperAnalyst::identify_protected_attachments())) { return $new_rules; } global $wpdb; require_once dirname(__FILE__) . '/uploads_rs.php'; $home_root = parse_url(get_option('home')); $home_root = trailingslashit($home_root['path']); $uploads = scoper_get_upload_info(); $baseurl = trailingslashit($uploads['baseurl']); $arr_url = parse_url($baseurl); $rewrite_base = $arr_url['path']; $file_keys = array(); $has_postmeta = array(); if ($key_results = scoper_get_results("SELECT pm.meta_value, p.guid, p.ID FROM {$wpdb->postmeta} AS pm INNER JOIN {$wpdb->posts} AS p ON p.ID = pm.post_id WHERE pm.meta_key = '_rs_file_key'")) { foreach ($key_results as $row) { $file_keys[$row->guid] = $row->meta_value; $has_postmeta[$row->ID] = $row->meta_value; } } $new_rules = "<IfModule mod_rewrite.c>\n"; $new_rules .= "RewriteEngine On\n"; $new_rules .= "RewriteBase {$rewrite_base}\n\n"; $main_rewrite_rule = "RewriteRule ^(.*) {$home_root}index.php?attachment=\$1&rs_rewrite=1 [NC,L]\n"; $htaccess_urls = array(); foreach ($attachment_results as $row) { if (false !== strpos($row->guid, $baseurl)) { // no need to include any attachments which are not in the uploads folder if (!empty($file_keys[$row->guid])) { $key = $file_keys[$row->guid]; } else { $key = urlencode(str_replace('.', '', uniqid(strval(rand()), true))); $file_keys[$row->guid] = $key; } if (!isset($has_postmeta[$row->ID]) || $key != $has_postmeta[$row->ID]) { update_post_meta($row->ID, "_rs_file_key", $key); } if (isset($htaccess_urls[$row->guid])) { // if a file is attached to multiple protected posts, use a single rewrite rule for it continue; } $htaccess_urls[$row->guid] = true; $rel_path = str_replace($baseurl, '', $row->guid); // escape spaces $file_path = str_replace(' ', '\\s', $rel_path); // escape horiz tabs (yes, at least one user has them in filenames) $file_path = str_replace(chr(9), '\\t', $file_path); // strip out all other nonprintable characters. Affected files will not be filtered, but we avoid 500 error. Possible TODO: advisory in file attachment utility $file_path = preg_replace('/[\\x00-\\x1f\\x7f]/', '', $file_path); // escape all other regular expression operator characters $file_path = preg_replace('/[\\^\\$\\.\\+\\[\\]\\(\\)\\{\\}]/', '\\\\$0', $file_path); $new_rules .= "RewriteCond %{REQUEST_URI} ^(.*)/{$file_path}" . "\$ [NC]\n"; $new_rules .= "RewriteCond %{QUERY_STRING} !^(.*)rs_file_key={$key}(.*)\n"; $new_rules .= $main_rewrite_rule; if ($pos_ext = strrpos($file_path, '\\.')) { $thumb_path = substr($file_path, 0, $pos_ext); $ext = substr($file_path, $pos_ext + 2); $new_rules .= "RewriteCond %{REQUEST_URI} ^(.*)/{$thumb_path}" . '-[0-9]{2,4}x[0-9]{2,4}\\.' . $ext . "\$ [NC]\n"; $new_rules .= "RewriteCond %{QUERY_STRING} !^(.*)rs_file_key={$key}(.*)\n"; $new_rules .= $main_rewrite_rule; // if resized image file(s) exist, include rules for them $guid_pos_ext = strrpos($rel_path, '.'); $pattern = $uploads['path'] . '/' . substr($rel_path, 0, $guid_pos_ext) . '-??????????????' . substr($rel_path, $guid_pos_ext); if (glob($pattern)) { $new_rules .= "RewriteCond %{REQUEST_URI} ^(.*)/{$thumb_path}" . '-[0-9,a-f]{14}\\.' . $ext . "\$ [NC]\n"; $new_rules .= "RewriteCond %{QUERY_STRING} !^(.*)rs_file_key={$key}(.*)\n"; $new_rules .= $main_rewrite_rule; } } } } // end foreach protected attachment if (IS_MU_RS) { global $blog_id; $file_filtered_sites = (array) get_site_option('scoper_file_filtered_sites'); if (!in_array($blog_id, $file_filtered_sites)) { // this site needs a file redirect rule in root .htaccess scoper_flush_site_rules(); } if (defined('SCOPER_MU_FILE_PROCESSING')) { // unless SCOPER_MU_FILE_PROCESSING is defined (indicating blogs.php has been modified for compatibility), blogs.php processing will be bypassed for all files $content_path = trailingslashit(str_replace($strip_path, '', str_replace('\\', '/', WP_CONTENT_DIR))); $new_rules .= "\n# Default WordPress cache handling\n"; $new_rules .= "RewriteRule ^(.*) {$content_path}blogs.php?file=\$1 [L]\n"; } } $new_rules .= "</IfModule>\n"; return $new_rules; }