Skip to content

Commit

Permalink
Discrete push replication complete. Added a settings page too. I adde…
Browse files Browse the repository at this point in the history
…d options to it for proxy settings.
  • Loading branch information
Jesse Blum committed Sep 6, 2012
1 parent 97ee3d5 commit 8d159f1
Show file tree
Hide file tree
Showing 8 changed files with 337 additions and 99 deletions.
2 changes: 1 addition & 1 deletion admin/admin-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
define( 'HN_TS_ADMIN_DIR', HN_TS_PLUGIN_DIR . '/admin' );

// Require utility files
require_once( HN_TS_ADMIN_DIR . '/interface.php' );
require_once( HN_TS_ADMIN_DIR . '/interface.php' );
?>
1 change: 1 addition & 0 deletions admin/interface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

add_action('admin_menu', 'hn_ts_add_admin_menus');
require_once( HN_TS_ADMIN_DIR . '/settings.php' );

/**
* Timestreams Admin menu structure
Expand Down
49 changes: 49 additions & 0 deletions admin/settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
add_action('admin_init', 'hn_ts_init' );
add_action('admin_menu', 'hn_ts_add_page');

// Init plugin options to white list our options
function hn_ts_init(){
register_setting( 'hn_ts_options', 'hn_ts', 'hn_ts_options_validate' );
}

// Add menu page
function hn_ts_add_page() {
add_options_page('Timestreams', 'Timestreams', 'manage_options', 'hn_ts_options', 'hn_ts_options_do_page');
}

// Draw the menu page itself
function hn_ts_options_do_page() {
?>
<div class="wrap">
<h2>Timestreams Options</h2>
<form method="post" action="options.php">
<?php settings_fields('hn_ts_options'); ?>
<?php $options = get_option('hn_ts'); ?>
<table class="form-table">
<tr valign="top"><th scope="row">Proxy Address</th>
<td><input type="text" name="hn_ts[proxyAddr]" value="<?php echo $options['proxyAddr']; ?>" /></td>
</tr>
<tr valign="top"><th scope="row">Proxy Port</th>
<td><input type="text" name="hn_ts[proxyPort]" value="<?php echo $options['proxyPort']; ?>" /></td>
</tr>
</table>
<p class="submit">
<input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
</p>
</form>
</div>
<?php
}

// Sanitize and validate input. Accepts an array, return a sanitized array.
function hn_ts_options_validate($input) {

// Must be safe text with no HTML tags
$input['proxyAddr'] = wp_filter_nohtml_kses($input['proxyAddr']);

// Must be safe text with no HTML tags
$input['proxyPort'] = wp_filter_nohtml_kses($input['proxyPort']);

return $input;
}
318 changes: 238 additions & 80 deletions controllers/replication_ctrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,84 +4,242 @@
* Author: Jesse Blum (JMB)
* Date: 2012
* To do: Add edit/delete functionality
*/

/**
* A form to add replication records
* Todo: add validation & make messages stand out more
* Pass in username and password to hn_ts_insert_replication
*/

/**
* Extends IXR_Client with a version of query() suitable for use behind proxy servers
* (without authentication)
* @author pszjmb
*
*/
class Proxied_IXR_Client extends IXR_Client{
var $proxyAddr;
var $proxyPort;

function __construct($proxyAddr, $proxyPort, $server, $path = false, $port = 80, $timeout = 15) {
parent::__construct($server, $path, $port, $timeout);
$this->proxyAddr = $proxyAddr;
$this->proxyPort = $proxyPort;
}

/**
* Same as parent's query() except for minor changes as per
* http://thedeadone.net/how-to/livejournal-and-wordpress/
* to support proxied requests.
* @return boolean
*/
function hn_ts_addReplicationRecord(){
?>
<h3>Add Replication Record</h3>
<form id="replicationform" method="post" action="">
<table class="form-table">
<tr valign="top">
<th scope="row">Local Table *</th>
<td>
<input type="text" name="local_table" />
</td>
</tr>

<tr valign="top">
<th scope="row">Remote-User Login Name *</th>
<td>
<input type="text" name="remote_user_login" />
</td>
</tr>

<tr valign="top">
<th scope="row">Remote-User Password *</th>
<td>
<input type="password" name="pwrd" />
</td>
</tr>

<tr valign="top">
<th scope="row">Remote Url *</th>
<td>
<input type="text" name="remote_url" />
</td>
</tr>

<tr valign="top">
<th scope="row">Remote Table *</th>
<td>
<input type="text" name="remote_table" />
</td>
</tr>

<tr valign="top">
<th scope="row">Continuous</th>
<td>
<input type="checkbox" name="continuous" value="Yes" />
</td>
</tr>

</table>

<p class="submit">
<input type="submit" name='submit' class="button-primary" value="<?php _e('Add Replication Record') ?>" />
</p>

</form>
<hr />
<?php
$cont = 0;
if(isset($_POST['continuous']) && $_POST['continuous'] == 'Yes'){
$cont = 1;
}
if(isset($_POST['local_table']) && $_POST['local_table'] &&
isset($_POST['remote_user_login']) && $_POST['remote_user_login'] &&
isset($_POST['pwrd']) && $_POST['pwrd'] &&
isset($_POST['remote_url']) && $_POST['remote_url'] &&
isset($_POST['remote_table']) && $_POST['remote_table']) {
$db = new Hn_TS_Database();
$replication = $db->hn_ts_insert_replication(array("","",
$_POST['local_table'], $_POST['remote_user_login'],
$_POST['pwrd'], $_POST['remote_url'], $_POST['remote_table'],
$cont,"")
);
echo 'Record added.';
}
}
function query()
{
$args = func_get_args();
$method = array_shift($args);
$request = new IXR_Request($method, $args);
$length = $request->getLength();
$xml = $request->getXml();
$r = "\r\n";
$request = "POST {$this->path} HTTP/1.0$r";

// Merged from WP #8145 - allow custom headers
$this->headers['Host'] = 'http://'.$this->server;
$this->headers['Content-Type'] = 'text/xml';
$this->headers['User-Agent'] = $this->useragent;
$this->headers['Content-Length']= $length;

foreach( $this->headers as $header => $value ) {
$request = "POST http://{$this->server}{$this->path} HTTP/1.0$r";
$request .= "{$header}: {$value}{$r}";
}
$request .= $r;

$request .= $xml;

// Now send the request
if ($this->debug) {
echo '<pre class="ixr_request">'.htmlspecialchars($request)."\n</pre>\n\n";
}

if ($this->timeout) {
//$fp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout);
$fp = fsockopen($this->proxyAddr, $this->proxyPort, $errno, $errstr, $this->timeout);
} else {
//$fp = @fsockopen($this->server, $this->port, $errno, $errstr);
$fp = fsockopen($this->proxyAddr, $this->proxyPort, $errno, $errstr);
}
if (!$fp) {
$this->error = new IXR_Error(-32300, 'transport error - could not open socket');
return false;
}
fputs($fp, $request);
$contents = '';
$debugContents = '';
$gotFirstLine = false;
$gettingHeaders = true;
while (!feof($fp)) {
$line = fgets($fp, 4096);
if (!$gotFirstLine) {
// Check line for '200'
if (strstr($line, '200') === false) {
$this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200');
return false;
}
$gotFirstLine = true;
}
if (trim($line) == '') {
$gettingHeaders = false;
}
if (!$gettingHeaders) {
// merged from WP #12559 - remove trim
$contents .= $line;
}
if ($this->debug) {
$debugContents .= $line;
}
}
if ($this->debug) {
echo '<pre class="ixr_response">'.htmlspecialchars($debugContents)."\n</pre>\n\n";
}

// Now parse what we've got back
$this->message = new IXR_Message($contents);
if (!$this->message->parse()) {
// XML error
$this->error = new IXR_Error(-32700, 'parse error. not well formed');
return false;
}

// Is the message a fault?
if ($this->message->messageType == 'fault') {
$this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
return false;
}

// Message must be OK
return true;
}
}
/**
* Performs a complete copy of a local table to a remote table.
* @param int $replRecordID is a row id from the Replication Table
* @return mixed|string, on success the time the replication started or 'Replication failed.'
*/
function hn_ts_replicate_full($replRecordID){

$db = new Hn_TS_Database();
$replRow = $db->hn_ts_getReplRow($replRecordID);
if ($replRow != null) {
$date = new DateTime();
$date = str_replace("T"," ",
substr_replace(gmdate("Y-m-d\TH:i:s\Z", $date->getTimestamp() ) ,"",-1));
var_dump(replicateXmlRpc($replRow));
if($db->hn_ts_updateReplRow($replRecordID, $date)){
return "<br />$date";
}else{
return 'Replication failed.';
}
}else{
return 'Replication failed.';
}
}

/**
* Replicates a databse table using XML-RPC
* @param $replRow is an array containing a Replication Table row
*/
function replicateXmlRpc($replRow){
$options = get_option('hn_ts');

if(count($options['proxyAddr']) > 0){
$client = new Proxied_IXR_Client($options['proxyAddr'], $options['proxyPort'], $replRow->remote_url);
}else{
$client = new IXR_Client($replRow->remote_url);
}

if (!$client->query('timestreams.add_measurements',$replRow->remote_user_login,
$replRow->remote_user_pass,$replRow->remote_table,
'999.1','2012-03-02 00:34:04',
'999.2','2012-03-02 00:34:05',
'999.3','2012-03-02 00:34:06'
)) {
die('An error occurred - '.$client->getErrorCode().":".$client->getErrorMessage());
}
/*if (!$client->query('wp.getCategories','', 'admin','Time349')) {
die('An error occurred - '.$client->getErrorCode().":".$client->getErrorMessage());
}*/
return $response = $client->getResponse();
//var_dump($response);
}


/**
* A form to add replication records
* Todo: add validation & make messages stand out more
* Pass in username and password to hn_ts_insert_replication
*/
function hn_ts_addReplicationRecord(){
?>
<h3>Add Replication Record</h3>
<form id="replicationform" method="post" action="">
<table class="form-table">
<tr valign="top">
<th scope="row">Local Table *</th>
<td><input type="text" name="local_table" />
</td>
</tr>

<tr valign="top">
<th scope="row">Remote-User Login Name *</th>
<td><input type="text" name="remote_user_login" />
</td>
</tr>

<tr valign="top">
<th scope="row">Remote-User Password *</th>
<td><input type="password" name="pwrd" />
</td>
</tr>

<tr valign="top">
<th scope="row">Remote Url *</th>
<td><input type="text" name="remote_url" />
</td>
</tr>

<tr valign="top">
<th scope="row">Remote Table *</th>
<td><input type="text" name="remote_table" />
</td>
</tr>

<tr valign="top">
<th scope="row">Continuous</th>
<td><input type="checkbox" name="continuous" value="Yes" />
</td>
</tr>

</table>

<p class="submit">
<input type="submit" name='submit' class="button-primary"
value="<?php _e('Add Replication Record') ?>" />
</p>

</form>
<hr />
<?php
$cont = 0;
if(isset($_POST['continuous']) && $_POST['continuous'] == 'Yes'){
$cont = 1;
}
if(isset($_POST['local_table']) && $_POST['local_table'] &&
isset($_POST['remote_user_login']) && $_POST['remote_user_login'] &&
isset($_POST['pwrd']) && $_POST['pwrd'] &&
isset($_POST['remote_url']) && $_POST['remote_url'] &&
isset($_POST['remote_table']) && $_POST['remote_table']) {
$db = new Hn_TS_Database();
$replication = $db->hn_ts_insert_replication(array("","",
$_POST['local_table'], $_POST['remote_user_login'],
$_POST['pwrd'], $_POST['remote_url'], $_POST['remote_table'],
$cont,"")
);
echo 'Record added.';
}
}
Loading

0 comments on commit 8d159f1

Please sign in to comment.