...
 
Commits (168)
RewriteEngine On
RewriteBase /
#Uncommenbt to lock WP
#RewriteCond %{REQUEST_URI} ^(.*)?register.*$ [OR]
#RewriteCond %{REQUEST_URI} ^(.*)?wp-comment-post\.php(.*)$ [OR]
#RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ [OR]
#RewriteCond %{REQUEST_URI} ^(.*)?wp-post\.php(.*)$ [OR]
#RewriteCond %{REQUEST_URI} ^(.*)?wp-admin$
#RewriteRule ^(.*)$ http://cavallette.noblogs.org/2013/11/8487 [R,L]
RewriteRule ^index\.php$ - [L]
#### moved blogs.
RewriteCond %{HTTP_HOST} ^ventitre\.noblogs\.org [NC]
RewriteRule ^/?(.*) http://www.ventitre.org/$1 [L,R=301,NE]
####
#avoid inspection of queries log
RewriteRule ^/noblogs_queries.* /ancheno [L,R=404]
# uploaded files
RewriteRule ^files/(.+) wp-includes/ms-files.php?file=$1 [L]
RewriteCond %{HTTP_X_FORWARDED_PROTO} https [NC]
RewriteRule ^gallery/([0-9]+)/(previews|previews-med)/(.*)$ https://noblogs.org/oldgal/$1/$2/$3 [R=301,L]
RewriteRule ^gallery/([0-9]+)/(previews|previews-med)/(.*)$ http://noblogs.org/oldgal/$1/$2/$3 [R=301,L]
#RewriteRule ^gallery/([0-9]+)/(previews|previews-med)/(.*)$ oldgal/$1/$2/$3 [L]
RewriteRule ^gallery/[0-9]+/(.*)$ wp-includes/ms-files.php?file=2010/08/$1 [L]
RewriteRule ^resource/[^/]+/preview/(.*)$ wp-includes/ms-files.php?file=2010/08/$1 [L]
RewriteRule ^resource/[^/]+/download/(.*)$ wp-includes/ms-files.php?file=2010/08/$1 [L]
# BEGIN WPSuperCache
<IfModule mod_rewrite.c>
AddDefaultCharset UTF-8
# Commented in order to cache more
# RewriteCond %{REQUEST_URI} !^.*[^/]$
RewriteCond %{REQUEST_URI} !^.*//.*$
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{QUERY_STRING} !.*=.*
RewriteCond %{HTTP:Cookie} !^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$
RewriteCond %{HTTP:X-Wap-Profile} !^[a-z0-9\"]+ [NC]
RewriteCond %{HTTP:Profile} !^[a-z0-9\"]+ [NC]
RewriteCond %{HTTP_USER_AGENT} !^.*(2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800).*
RewriteCond %{HTTP_user_agent} !^(w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-).*
RewriteCond %{HTTP:Accept-Encoding} gzip
#RewriteCond %{HTTP:X-Forwarded-Proto} !^https$
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/%{HTTP:X-Forwarded-Proto}/$1/index.html.gz -f
RewriteRule ^(.*) "/wp-content/cache/supercache/%{HTTP_HOST}/%{HTTP:X-Forwarded-Proto}/$1/index.html.gz" [L]
#Commented in order to cache more
#RewriteCond %{REQUEST_URI} !^.*[^/]$
RewriteCond %{REQUEST_URI} !^.*//.*$
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{QUERY_STRING} !.*=.*
RewriteCond %{HTTP:Cookie} !^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$
RewriteCond %{HTTP:X-Wap-Profile} !^[a-z0-9\"]+ [NC]
RewriteCond %{HTTP:Profile} !^[a-z0-9\"]+ [NC]
RewriteCond %{HTTP_USER_AGENT} !^.*(2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800).*
RewriteCond %{HTTP_user_agent} !^(w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-).*
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/%{HTTP:X-Forwarded-Proto}/$1/index.html -f
#RewriteCond %{HTTP:X-Forwarded-Proto} !^https$
RewriteRule ^(.*) "/wp-content/cache/supercache/%{HTTP_HOST}/%{HTTP:X-Forwarded-Proto}/$1/index.html" [L]
</IfModule>
# END WPSuperCache
# BEGIN WordPress
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule . index.php [L]
# END WordPress
# BEGIN noblogs
# .git doesn't exist
RedirectMatch 404 /\\.git(/|$)
# END noblogs
This diff is collapsed.
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*.noblogs.org" />
</cross-domain-policy>
<?php
// Common settings
$wpdb->persistent = true;
$wpdb->max_connections = 30;
/* Disable responsiveness check, is not needed in our configuration and is causing
connection errors for the wrong implementation */
$wpdb->check_tcp_responsiveness = false;
include_once('r2db/db-hash.php');
include_once('r2db/db-backends.php');
// Set up global dataset with master databases
noblogs_load_global_dataset(NOBLOGS_MASTER_CONFIG, NOBLOGS_HOST_FILE);
// Add all the sharded blog databases.
$wpdb_reverse_backend_map = noblogs_load_backends(NOBLOGS_BACKEND_CONFIG, $wpdb->hash_map);
favicon.ico

246 Bytes

Uso di HyperDB con il piano R di A/I
------------------------------------
I database di noblogs sono distribuiti su piu' di un backend, utilizzando
un sistema di consistent hashing che associa ogni blog_id ad un backend
specifico.
L'elenco dei backend e' specificato nel file /etc/noblogs/backends.
Lo schema e' molto semplice e si basa sull'ID pubblico di ciascun server
(es, latitanza:1, confino:3, etc). Ogni server ha un database 'noblogs_ID'
(in /opt/noblogs/mysql), cui puo' accedere l'utente 'noblogsdb'.
<?php
function noblogs_split_db($file) {
$db_url = trim(file_get_contents($file));
return parse_url($db_url);
}
function noblogs_load_backends($db_config_file, $hashptr) {
global $wpdb;
$backend_map = array();
$fp = @fopen($db_config_file, "r");
if (!$fp) {
die("Database backends not configured!");
}
while (($line = fgets($fp, 1024)) !== false) {
$wline = rtrim($line);
if ($wline == "" || $wline[0] == '#') {
continue;
}
$line_parts = explode(" ", $wline);
$server_id = $line_parts[0];
$dataset = "backend_" . $server_id;
$backend_url = $line_parts[2];
$backend_url_data = parse_url($backend_url);
$backend = array(
"host" => $backend_url_data["host"] . ":" . $backend_url_data["port"],
"user" => $backend_url_data["user"],
"password" => $backend_url_data["pass"],
"name" => substr($backend_url_data["path"], 1),
"dataset" => $dataset,
"read" => 1, "write" => 1, "timeout" => 10
);
$wpdb->add_database($backend);
$hashptr->addTarget($dataset);
$backend_map[$dataset] = $backend;
}
fclose($fp);
return $backend_map;
}
function noblogs_load_global_dataset($master_file, $ip_file) {
global $wpdb;
$mdata = noblogs_split_db($master_file);
$ldata = trim(file_get_contents($ip_file));
$globaldb = array(
"host" => $mdata["host"] . ":" . $mdata["port"],
"user" => $mdata["user"],
"password" => $mdata["pass"],
"name" => substr($mdata["path"], 1),
"dataset" => "global",
"read" => 1, "write" => 1, "timeout" => 2
);
if ($mdata['host'] == $ldata) {
$wpdb->add_database($globaldb);
} else {
$globaldb['read'] = 0;
$wpdb->add_database($globaldb);
$globaldb['host'] = $ldata . ":" . $mdata["port"];
$globaldb['read'] = 1;
$globaldb['write'] = 0;
$wpdb->add_database($globaldb);
}
}
<?php
require_once(dirname(__FILE__) . '/flexihash.php');
require_once( ABSPATH . 'wp-config.php' );
$wpdb->hash_map = new Flexihash(null, R2DB_FLEXIHASH_REPLICAS);
/* Hashing function to map blogs to databases.
*
* Implements a consistent hashing scheme using Flexihash.
*/
function noblogs_db_callback($query, $wpdb) {
$wpdb_hash = $wpdb->hash_map;
if (preg_match("/^{$wpdb->base_prefix}(\d+)_/", $wpdb->table, $matches)) {
$blog_id = $matches[1];
return $wpdb_hash->lookup($blog_id);
}
}
$wpdb->add_callback('noblogs_db_callback');
<?php
/**
* Flexihash - A simple consistent hashing implementation for PHP.
*
* The MIT License
*
* Copyright (c) 2008 Paul Annesley
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author Paul Annesley
* @link http://paul.annesley.cc/
* @copyright Paul Annesley, 2008
*/
/**
* A simple consistent hashing implementation with pluggable hash algorithms.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash
{
/**
* The number of positions to hash each target to.
*
* @var int
*/
private $_replicas = 64;
/**
* The hash algorithm, encapsulated in a Flexihash_Hasher implementation.
* @var object Flexihash_Hasher
*/
private $_hasher;
/**
* Internal counter for current number of targets.
* @var int
*/
private $_targetCount = 0;
/**
* Internal map of positions (hash outputs) to targets
* @var array { position => target, ... }
*/
private $_positionToTarget = array();
/**
* Internal map of targets to lists of positions that target is hashed to.
* @var array { target => [ position, position, ... ], ... }
*/
private $_targetToPositions = array();
/**
* Whether the internal map of positions to targets is already sorted.
* @var boolean
*/
private $_positionToTargetSorted = false;
/**
* Constructor
* @param object $hasher Flexihash_Hasher
* @param int $replicas Amount of positions to hash each target to.
*/
public function __construct(Flexihash_Hasher $hasher = null, $replicas = null)
{
$this->_hasher = $hasher ? $hasher : new Flexihash_Crc32Hasher();
if (!empty($replicas)) $this->_replicas = $replicas;
}
/**
* Add a target.
* @param string $target
* @param float $weight
* @chainable
*/
public function addTarget($target, $weight=1)
{
if (isset($this->_targetToPositions[$target]))
{
throw new Flexihash_Exception("Target '$target' already exists.");
}
$this->_targetToPositions[$target] = array();
// hash the target into multiple positions
for ($i = 0; $i < round($this->_replicas*$weight); $i++)
{
$position = $this->_hasher->hash($target . $i);
$this->_positionToTarget[$position] = $target; // lookup
$this->_targetToPositions[$target] []= $position; // target removal
}
$this->_positionToTargetSorted = false;
$this->_targetCount++;
return $this;
}
/**
* Add a list of targets.
* @param array $targets
* @param float $weight
* @chainable
*/
public function addTargets($targets, $weight=1)
{
foreach ($targets as $target)
{
$this->addTarget($target,$weight);
}
return $this;
}
/**
* Remove a target.
* @param string $target
* @chainable
*/
public function removeTarget($target)
{
if (!isset($this->_targetToPositions[$target]))
{
throw new Flexihash_Exception("Target '$target' does not exist.");
}
foreach ($this->_targetToPositions[$target] as $position)
{
unset($this->_positionToTarget[$position]);
}
unset($this->_targetToPositions[$target]);
$this->_targetCount--;
return $this;
}
/**
* A list of all potential targets
* @return array
*/
public function getAllTargets()
{
return array_keys($this->_targetToPositions);
}
/**
* Looks up the target for the given resource.
* @param string $resource
* @return string
*/
public function lookup($resource)
{
$targets = $this->lookupList($resource, 1);
if (empty($targets)) throw new Flexihash_Exception('No targets exist');
return $targets[0];
}
/**
* Get a list of targets for the resource, in order of precedence.
* Up to $requestedCount targets are returned, less if there are fewer in total.
*
* @param string $resource
* @param int $requestedCount The length of the list to return
* @return array List of targets
*/
public function lookupList($resource, $requestedCount)
{
if (!$requestedCount)
throw new Flexihash_Exception('Invalid count requested');
// handle no targets
if (empty($this->_positionToTarget))
return array();
// optimize single target
if ($this->_targetCount == 1)
return array_unique(array_values($this->_positionToTarget));
// hash resource to a position
$resourcePosition = $this->_hasher->hash($resource);
$results = array();
$collect = false;
$this->_sortPositionTargets();
// search values above the resourcePosition
foreach ($this->_positionToTarget as $key => $value)
{
// start collecting targets after passing resource position
if (!$collect && $key > $resourcePosition)
{
$collect = true;
}
// only collect the first instance of any target
if ($collect && !in_array($value, $results))
{
$results []= $value;
}
// return when enough results, or list exhausted
if (count($results) == $requestedCount || count($results) == $this->_targetCount)
{
return $results;
}
}
// loop to start - search values below the resourcePosition
foreach ($this->_positionToTarget as $key => $value)
{
if (!in_array($value, $results))
{
$results []= $value;
}
// return when enough results, or list exhausted
if (count($results) == $requestedCount || count($results) == $this->_targetCount)
{
return $results;
}
}
// return results after iterating through both "parts"
return $results;
}
public function __toString()
{
return sprintf(
'%s{targets:[%s]}',
get_class($this),
implode(',', $this->getAllTargets())
);
}
// ----------------------------------------
// private methods
/**
* Sorts the internal mapping (positions to targets) by position
*/
private function _sortPositionTargets()
{
// sort by key (position) if not already
if (!$this->_positionToTargetSorted)
{
ksort($this->_positionToTarget, SORT_REGULAR);
$this->_positionToTargetSorted = true;
}
}
}
/**
* Hashes given values into a sortable fixed size address space.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
interface Flexihash_Hasher
{
/**
* Hashes the given string into a 32bit address space.
*
* Note that the output may be more than 32bits of raw data, for example
* hexidecimal characters representing a 32bit value.
*
* The data must have 0xFFFFFFFF possible values, and be sortable by
* PHP sort functions using SORT_REGULAR.
*
* @param string
* @return mixed A sortable format with 0xFFFFFFFF possible values
*/
public function hash($string);
}
/**
* Uses CRC32 to hash a value into a signed 32bit int address space.
* Under 32bit PHP this (safely) overflows into negatives ints.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash_Crc32Hasher
implements Flexihash_Hasher
{
/* (non-phpdoc)
* @see Flexihash_Hasher::hash()
*/
public function hash($string)
{
return crc32($string);
}
}
/**
* Uses CRC32 to hash a value into a 32bit binary string data address space.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash_Md5Hasher
implements Flexihash_Hasher
{
/* (non-phpdoc)
* @see Flexihash_Hasher::hash()
*/
public function hash($string)
{
return substr(md5($string), 0, 8); // 8 hexits = 32bit
// 4 bytes of binary md5 data could also be used, but
// performance seems to be the same.
}
}
/**
* An exception thrown by Flexihash.
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash_Exception extends Exception
{
}
#!/opt/noblogs/cron/php-noblogs
<?php
// Load wordpress api.
define('WP_CACHE',false);
/** Setup WordPress environment */
require_once('wp-load.php');
require_once('db-config.php');
function old_hash($dbid) {
if (($dbid % 2) == 0) {
return array('host' => '172.16.1.3',
'port' => '3307',
'user' => 'noblogs',
'password' => 'n0bl0gst3st',
'db' => 'noblogs_2');
} else {
return array('host' => '172.16.1.8',
'port' => '3307',
'user' => 'noblogsusr',
'password' => 'n0bl0gsdb4xpw!',
'db' => 'noblogs');
}
}
function new_hash($dbid, $reversemap) {
global $wpdb;
$lookup = $wpdb->hash_map->lookup($dbid);
$backend = $reversemap[$lookup];
$result = array();
if (preg_match('/^(.*):([0-9]*)$/', $backend['host'], $matches)) {
$result['host'] = $matches[1];
$result['port'] = $matches[2];
}
$result['user'] = $backend['user'];
$result['password'] = $backend['password'];
$result['db'] = $backend['name'];
return $result;
}
function mysqlopts(&$attrs) {
return ("-h" . $attrs['host'] . " -P" . $attrs['port'] . " -u" . $attrs['user']
. " '-p" . $attrs['password'] . "'");
}
function mysqlurl(&$attrs) {
return ("mysql://" . $attrs['user'] . "@" . $attrs['host']
. ":" . $attrs['port'] . "/" . $attrs['db']);
}
function get_all_blogs()
{
global $wpdb;
// $sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE public = 1 AND deleted = 0 AND archived = '0' ORDER BY domain, path";
$sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE public = 0 ORDER BY domain, path";
$result = $wpdb->get_results($sql);
return ($result);
}
$hashmap = new Flexihash();
$reverse_backend_map = noblogs_load_backends(NOBLOGS_BACKEND_CONFIG, $hashmap);
$new_counts = array();
$moved_count = 0;
$blogs = get_all_blogs();
foreach ($blogs as $blog) {
$blog_id = $blog->blog_id;
$old_params = old_hash($blog_id);
$old_dburi = mysqlurl($old_params);
$new_params = new_hash($blog_id, $reverse_backend_map);
$new_dburi = mysqlurl($new_params);
if ($new_counts[$new_params['host']]) {
$new_counts[$new_params['host']] += 1;
} else {
$new_counts[$new_params['host']] = 1;
}
if ($old_dburi != $new_dburi) {
echo "echo moving blog $blog_id from " . $old_params['host'] . " to " . $new_params['host'] . "\n";
echo "tables=\$(mysql " . mysqlopts($old_params) . " " . $old_params['db'] . " -NBe \"show tables like 'wp\\_" . $blog_id . "\\_%'\")\n";
echo "mysqldump --opt " . mysqlopts($old_params) . " " . $old_params['db'] . " \${tables} \\\n";
echo " | mysql " . mysqlopts($new_params) . " " . $new_params['db'] . "\n";
$moved_count += 1;
} else {
echo "echo blog $blog_id stays on " . $old_params['host'] . "\n";
}
}
echo "\n\n\nBlog distribution:\n";
print_r($new_counts);
print "\n $moved_count blogs moved\n";
#!/opt/noblogs/cron/php-noblogs
<?php
if ($argv[1]) {
$blog_domain = $argv[1];
if (!preg_match('/\.noblogs\.org$/', $blog_domain)) {
$blog_domain = $blog_domain . '.noblogs.org';
}
} else {
die("Usage: get-backend <blog_name>\n");
}
// Load wordpress api.
define('WP_CACHE',false);
/** Setup WordPress environment */
require_once('wp-load.php');
require_once('db-config.php');
function new_hash($dbid, $reversemap) {
global $wpdb;
$lookup = $wpdb->hash_map->lookup($dbid);
$backend = $reversemap[$lookup];
$result = array();
if (preg_match('/^(.*):([0-9]*)$/', $backend['host'], $matches)) {
$result['host'] = $matches[1];
$result['port'] = $matches[2];
}
$result['user'] = $backend['user'];
$result['password'] = $backend['password'];
$result['db'] = $backend['name'];
return $result;
}
function get_blog($domain)
{
global $wpdb;
// $sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE public = 1 AND deleted = 0 AND archived = '0' ORDER BY domain, path";
$sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE domain = '" . $domain . "'";
$result = $wpdb->get_results($sql);
return ($result[0]);
}
$hashmap = new Flexihash();
$reverse_backend_map = noblogs_load_backends(NOBLOGS_BACKEND_CONFIG, $hashmap);
$blog = get_blog($blog_domain);
$backend = new_hash($blog->blog_id, $reverse_backend_map);
echo "\n" . $blog_domain . " (id " . $blog->blog_id . ")\n\n";
print_r($backend);
#!/opt/noblogs/cron/php-noblogs
<?php
/*
Parse command line options
*/
$opts = getopt('',array('no-database', 'calc-size', 'db-only'));
if (array_key_exists('calc-size', $opts)) {
$opts['no-database'] = true;
$g_added_size = array();
}
$new_topology = array_pop($argv);
$old_topology = array_pop($argv);
if (!($new_topology && $old_topology)) {
usage();
exit(-1);
}
// Get all blogs
define('WP_CACHE',false);
require_once('wp-load.php');
require_once('db-config.php');
$blogs = get_all_blogs();
$n_hashmap = new Flexihash();
$new_map = noblogs_load_backends($new_topology, $n_hashmap);
$o_hashmap = new Flexihash();
$old_map = noblogs_load_backends($old_topology, $o_hashmap);
foreach ($blogs as $blog) {
$blog_id = $blog->blog_id;
$old_params = fhash($blog_id, $old_map, $o_hashmap);
$old_dburi = mysqlurl($old_params);
$new_params = fhash($blog_id, $new_map, $n_hashmap);
$new_dburi = mysqlurl($new_params);
if ($new_counts[$new_params['host']]) {
$new_counts[$new_params['host']] += 1;
} else {
$new_counts[$new_params['host']] = 1;
}
if ($old_dburi != $new_dburi) {
echo "echo moving blog $blog_id from " . $old_params['host'] . " to " . $new_params['host'] . "\n";
if ( !array_key_exists('no-database', $opts) ) {
echo "tables=\$(mysql " . mysqlopts($old_params) . " " . $old_params['db'] . " -NBe \"show tables like 'wp\\_" . $blog_id . "\\_%'\")\n";
echo "mysqldump --opt " . mysqlopts($old_params) . " " . $old_params['db'] . " \${tables} \\\n";
echo " | mysql " . mysqlopts($new_params) . " " . $new_params['db'] . "\n";
}
if (!array_key_exists('db-only',$opts)) {
if (array_key_exists('calc-size', $opts)) {
# $cmd = sprintf("ssh root@%s du -sk /opt/noblogs/www/wp-content/blogs.dir/%d", $old_params['host'], $blog_id);
$cmd = sprintf("du -sk /opt/noblogs/www/wp-content/blogs.dir/%d", $blog_id);
list($size, $dummy) = explode("\t",exec($cmd, $ret));
$g_added_size[$new_params['host']] += $size;
} else {
printf("ssh root@%s rsync -avz --delete /opt/noblogs/www/wp-content/blogs.dir/%d root@%s:/opt/noblogs/www/wp-content/blogs.dir/\n", $old_params['host'], $blog_id, $new_params['host']);
}
}
$moved_count += 1;
} else {
echo "echo blog $blog_id stays on " . $old_params['host'] . "\n";
}
}
echo "\n\n\nBlog distribution:\n";
print_r($new_counts);
echo "\n $moved_count blogs moved\n";
if (array_key_exists('calc-size', $opts)) {
echo "Variations in disk space for hosts (kB):\n";
print_r($g_added_size);
}
function fhash($dbid, $reversemap, $hashptr) {
$lookup = $hashptr->lookup($dbid);
$backend = $reversemap[$lookup];
$result = array();
if (preg_match('/^(.*):([0-9]*)$/', $backend['host'], $matches)) {
$result['host'] = $matches[1];
$result['port'] = $matches[2];
}
$result['user'] = $backend['user'];
$result['password'] = $backend['password'];
$result['db'] = $backend['name'];
return $result;
}
function mysqlopts(&$attrs) {
return ("-h" . $attrs['host'] . " -P" . $attrs['port'] . " -u" . $attrs['user']
. " '-p" . $attrs['password'] . "'");
}
function mysqlurl(&$attrs) {
return ("mysql://" . $attrs['user'] . "@" . $attrs['host']
. ":" . $attrs['port'] . "/" . $attrs['db']);
}
function get_all_blogs()
{
global $wpdb;
$sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE deleted = 0 AND archived = '0' ORDER BY domain, path";
$result = $wpdb->get_results($sql);
return ($result);
}
function usage() {
$str = <<<USAGE
noblogs-new-topology.php [--no-database|--calc-size] <OLD_MAP> <NEW_MAP>
USAGE;
echo $str;
}
......@@ -918,6 +918,7 @@ function upgrade_101() {
* @global wpdb $wpdb WordPress database abstraction object.
*/
function upgrade_110() {
return;
global $wpdb;
// Set user_nicename.
......
......@@ -203,7 +203,7 @@ if ( ! is_multisite() ) {
*/
function _add_themes_utility_last() {
// Must use API on the admin_menu hook, direct modification is only possible on/before the _admin_menu hook
add_submenu_page( 'themes.php', __( 'Theme Editor' ), __( 'Theme Editor' ), 'edit_themes', 'theme-editor.php' );
add_submenu_page('themes.php', _x('Editor', 'theme editor'), _x('Editor', 'theme editor'), 'switch_themes', 'theme-editor.php');
}
$count = '';
......
<?php
// WP SUPER CACHE 1.2
function wpcache_broken_message() {
global $wp_cache_config_file;
if ( isset( $wp_cache_config_file ) == false ) {
return '';
}
$doing_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
$xmlrpc_request = defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST;
$rest_request = defined( 'REST_REQUEST' ) && REST_REQUEST;
$robots_request = strpos( $_SERVER['REQUEST_URI'], 'robots.txt' ) != false;
$skip_output = ( $doing_ajax || $xmlrpc_request || $rest_request || $robots_request );
if ( false == strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) && ! $skip_output ) {
echo '<!-- WP Super Cache is installed but broken. The constant WPCACHEHOME must be set in the file wp-config.php and point at the WP Super Cache plugin directory. -->';
}
}
if ( false == defined( 'WPCACHEHOME' ) ) {
define( 'ADVANCEDCACHEPROBLEM', 1 );
} elseif ( ! include_once WPCACHEHOME . 'wp-cache-phase1.php' ) {
if ( ! @is_file( WPCACHEHOME . 'wp-cache-phase1.php' ) ) {
define( 'ADVANCEDCACHEPROBLEM', 1 );
}
}
if ( defined( 'ADVANCEDCACHEPROBLEM' ) ) {
register_shutdown_function( 'wpcache_broken_message' );
}
<?php
/*
Plugin Name: HyperDB
Plugin URI: https://wordpress.org/plugins/hyperdb/
......@@ -51,6 +50,13 @@ define( 'HYPERDB_CONN_HOST_ERROR', 2003 ); // Can't connect to MySQL server on
define( 'HYPERDB_SERVER_GONE_ERROR', 2006 ); // MySQL server has gone away
class hyperdb extends wpdb {
/**
* A/I patch!
* store a FlexiHash() instance here.
*/
var $hash_map;
/**
* The last table that was queried
* @var string
......@@ -306,6 +312,12 @@ class hyperdb extends wpdb {
. ')\W([\w-]+)\W/is', $q, $maybe) )
return $maybe[1];
// SHOW TABLES LIKE (used in some plugins)
if ( preg_match('/^\s*'
. 'SHOW\s+TABLES\s+LIKE\s+'
. '\W(\w+)\W/is', $q, $maybe) )
return $maybe[1];
// Big pattern for the rest of the table-related queries in MySQL 5.0
if ( preg_match('/^\s*(?:'
. '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM'
......@@ -401,6 +413,11 @@ class hyperdb extends wpdb {
$this->run_callbacks( 'dataset_found', $dataset );
if (WP_DEBUG === true) {
$_ai_msg = sprintf("We choose dataset %s for query '%s'", $this->dataset, $query);
$this->print_error($_ai_msg);
}
if ( empty( $this->hyper_servers ) ) {
if ( $this->is_mysql_connection( $this->dbh ) )
return $this->dbh;
......@@ -665,16 +682,19 @@ class hyperdb extends wpdb {
$success = false;
$this->last_connection = compact('dbhname', 'host', 'port', 'user', 'name', 'tcp', 'elapsed', 'success');
$this->db_connections[] = $this->last_connection;
$msg = date( "Y-m-d H:i:s" ) . " Can't select $dbhname - \n";
$msg .= "'referrer' => '{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}',\n";
$msg .= "'server' => {$server},\n";
$msg .= "'host' => {$host},\n";
$msg .= "'error' => " . $this->ex_mysql_error() . ",\n";
$msg .= "'errno' => " . $this->ex_mysql_errno() . ",\n";
$msg .= "'server_state' => $server_state\n";
$msg .= "'lagged_status' => " . ( isset( $lagged_status ) ? $lagged_status : HYPERDB_LAG_UNKNOWN );
$this->print_error( $msg );
/* Workaround to stop logging a/i */
if ( AI_LOG_HYPERDB == true ) {
$msg = date( "Y-m-d H:i:s" ) . " Can't select $dbhname - \n";
$msg .= "'referrer' => '{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}',\n";
$msg .= "'server' => {$server},\n";
$msg .= "'host' => {$host},\n";
$msg .= "'error' => " . $this->ex_mysql_error() . ",\n";
$msg .= "'errno' => " . $this->ex_mysql_errno() . ",\n";
$msg .= "'server_state' => $server_state\n";
$msg .= "'lagged_status' => " . ( isset( $lagged_status ) ? $lagged_status : HYPERDB_LAG_UNKNOWN );
$this->print_error( $msg );
}
}
if ( ! $success || ! isset( $this->dbhs[$dbhname] ) || ! $this->is_mysql_connection( $this->dbhs[$dbhname] ) ) {
......@@ -709,6 +729,15 @@ class hyperdb extends wpdb {
$this->set_charset($this->dbhs[$dbhname], $charset, $collate);
if ( !isset( $charset ) )
$charset = null;
if ( !isset( $collate ) )
$collate = null;
// AI workaround: set all queries to latin1
$this->set_charset($this->dbhs[$dbhname], 'latin1');
$this->dbh = $this->dbhs[$dbhname]; // needed by $wpdb->_real_escape()
$this->last_used_server = compact('host', 'user', 'name', 'read', 'write');
......@@ -857,6 +886,11 @@ class hyperdb extends wpdb {
$statement_after_query = $this->run_callbacks( 'statement_after_query' );
$query_for_log = $query;
// A/I: prevent mysql-proxy to cache the admin section
if (strpos($_SERVER['REQUEST_URI'], '/wp-admin/') !== false) {
$query .= ' /* NO CACHE */';
}
$this->timer_start();
if ( $statement_before_query ) {
$query_for_log = "$statement_before_query; $query_for_log";
......@@ -1428,6 +1462,23 @@ class hyperdb extends wpdb {
} // class hyperdb
$wpdb = new hyperdb();
/**
* AI custom: Logs all queries for debugging purposes
*/
function ai_log_db_queries($query, $time, $backtrace=null, hyperdb $obj ) {
$fh = fopen( ABSPATH . '/profiling/noblogs_queries_'. date('Ymd') . '.log', 'a');
if (!$fh) {
return array($query, $time, $backtrace);
}
fwrite($fh, sprintf("##\n#Date: %s\n#Query time: %s\n%s\n", date('r'), $time, $query));
fclose($fh);
return array($query, $time, $backtrace);
}
$wpdb = new hyperdb();
if ( AI_DB_PROFILER === true ) {
$wpdb->save_queries = true;
$wpdb->save_query_callback = 'ai_log_db_queries';
}
require( DB_CONFIG_FILE );
<?php
/**
* Plugin Name: A/I Common Functions
* Plugin URI: https://noblogs.org
* Description: Custom functions used by Noblogs.
* Author: Autistici/Inventati
* Author URI: https://autistici.org
* Version: 1.0
*/
// Put your code snippets below this line.
/**
* This function will connect wp_mail to a (possibly authenticated)
* external SMTP server, instead of using the PHP mail() function.
*
* Values are constants set in wp-config.php
*/
if (defined('SMTP_HOST')) {
add_action('phpmailer_init', 'send_smtp_email');
function send_smtp_email($phpmailer) {
$phpmailer->isSMTP();
$phpmailer->Host = SMTP_HOST;
$phpmailer->SMTPAuth = SMTP_AUTH;
$phpmailer->Port = SMTP_PORT;
$phpmailer->Username = SMTP_USER;
$phpmailer->Password = SMTP_PASS;
$phpmailer->SMTPSecure = SMTP_SECURE;
$phpmailer->From = SMTP_FROM;
$phpmailer->FromName = SMTP_NAME;
// Do not attempt STARTTLS even if the
// server offers it - use SMTPSecure instead.
$phpmailer->SMTPAutoTLS = false;
}
}
<?php
/*
Plugin Name: A/I - Remove password change notification
Description: Disables email notification of password changes
Version: 0.1
Author: Autistici/Inventati
Author URI: https://autistici.org
*/
function wp_password_change_notification() {}
?>
......@@ -59,6 +59,8 @@ class OS_Disable_WordPress_Updates {
* @author scripts@schloebe.de
*/
function __construct() {
if (!defined('AI_CRON_SCRIPT')) {
add_action( 'admin_init', array(&$this, 'admin_init') );
/*
......@@ -92,8 +94,8 @@ class OS_Disable_WordPress_Updates {
* 3.0
*/
add_filter( 'pre_site_transient_update_core', array($this, 'last_checked_atm') );
/*
* Filter schedule checks
*
......@@ -129,6 +131,7 @@ class OS_Disable_WordPress_Updates {
if( !defined( 'WP_AUTO_UPDATE_CORE') ) define( 'WP_AUTO_UPDATE_CORE', false );
add_filter( 'pre_http_request', array($this, 'block_request'), 10, 3 );
}
}
......@@ -140,13 +143,13 @@ class OS_Disable_WordPress_Updates {
*/
function admin_init() {
if ( !function_exists("remove_action") ) return;
/*
* Remove 'update plugins' option from bulk operations select list
*/
global $current_user;
$current_user->allcaps['update_plugins'] = 0;
/*
* Hide maintenance and update nag
*/
......@@ -154,7 +157,7 @@ class OS_Disable_WordPress_Updates {
remove_action( 'network_admin_notices', 'update_nag', 3 );
remove_action( 'admin_notices', 'maintenance_nag' );
remove_action( 'network_admin_notices', 'maintenance_nag' );
/*
* Disable Theme Updates
......@@ -263,8 +266,8 @@ class OS_Disable_WordPress_Updates {
}
return $event;
}
/**
* Override version check info
*
......@@ -272,12 +275,12 @@ class OS_Disable_WordPress_Updates {
*/
public function last_checked_atm( $t ) {
include( ABSPATH . WPINC . '/version.php' );
$current = new stdClass;
$current->updates = array();
$current->version_checked = $wp_version;
$current->last_checked = time();
return $current;
}
}
......
# Only allow direct access to specific Web-available files.
# Apache 2.2
<IfModule !mod_authz_core.c>
Order Deny,Allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
# Akismet CSS and JS
<FilesMatch "^(form\.js|akismet\.js|akismet\.css)$">
<IfModule !mod_authz_core.c>
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</FilesMatch>
# Akismet images
<FilesMatch "^logo-full-2x\.png$">
<IfModule !mod_authz_core.c>
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</FilesMatch>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
var ak_js = document.getElementById( "ak_js" );
if ( ! ak_js ) {
ak_js = document.createElement( 'input' );
ak_js.setAttribute( 'id', 'ak_js' );
ak_js.setAttribute( 'name', 'ak_js' );
ak_js.setAttribute( 'type', 'hidden' );
}
else {
ak_js.parentNode.removeChild( ak_js );
}
ak_js.setAttribute( 'value', ( new Date() ).getTime() );
var commentForm = document.getElementById( 'commentform' );
if ( commentForm ) {
commentForm.appendChild( ak_js );
}
else {
var replyRowContainer = document.getElementById( 'replyrow' );
if ( replyRowContainer ) {
var children = replyRowContainer.getElementsByTagName( 'td' );
if ( children.length > 0 ) {
children[0].appendChild( ak_js );
}
}
}
\ No newline at end of file
<?php
/**
* @package Akismet
*/
/*
Plugin Name: Akismet Anti-Spam
Plugin URI: https://akismet.com/
Description: Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from spam</strong>. It keeps your site protected even while you sleep. To get started: activate the Akismet plugin and then go to your Akismet Settings page to set up your API key.