Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 419f543
Showing
5 changed files
with
214 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Copyright (c) 2012, Ian Barber | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | ||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
A [YouRLs](http://yourls.org/) plugin to queue clicks to Amazon SimpleDB before processing. This allows using a regular MySQL store even in the face of a high frequency of writes, without concern of connection limit overflow. Clicks are inserted later into the database via an import job. | ||
|
||
Install | ||
======= | ||
|
||
Ensure that the AWS PHP Client is installed: http://aws.amazon.com/sdkforphp/ | ||
|
||
To install the plugin itself copy the plugins/sdblog folder to your plugins folder (usually user/plugins). | ||
|
||
Configuration | ||
======= | ||
|
||
To access SimpleDB you will need to include your AWS key and secret key, available from the AWS console. These should be defined in your YouRLs config.php | ||
|
||
define('AWS_KEY', 'KEY_GOES_HERE'); | ||
define('AWS_SECRET_KEY', 'SECRET_KEY_HERE'); | ||
|
||
You can additionally define the region to run in and the domain (database name) for SimpleDB with the following parameters: | ||
|
||
define('SDB_REGION', AmazonSDB::REGION_EU_W1); | ||
define('SDB_DOMAIN', 'myqueuetable'); | ||
|
||
Usage | ||
====== | ||
|
||
The plugin will automatically shunt clicks onto a SimpleDB call. At appropriate points you are | ||
required to run the import.php script in order to pull the click data into the main YouRLS database | ||
for use in generating statistics. This can be done from a cron script, for example | ||
|
||
*/5 * * * * php /var/www/user/plugins/sdblog/import.php 2>&1 /dev/null | ||
|
||
The timing of the script will depend on your need for accuracy in statistics versus tolerance for database writes. |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php | ||
chdir(dirname(__FILE__)); | ||
|
||
define('SDB_IMPORTER', true); | ||
require_once( dirname(__FILE__).'/../../../includes/load-yourls.php' ); | ||
require_once( dirname(__FILE__).'/plugin.php' ); | ||
|
||
global $ydb; | ||
$sdb = sdblog_get_database(); | ||
$select = "SELECT * FROM `" . SDB_DOMAIN . "`"; | ||
$next_token = null; | ||
$count = 0; | ||
$id_holder = array(); | ||
$currId = 0; | ||
|
||
// Insert all log message - we're assuming input filtering happened earlier | ||
$query = array(); | ||
$clicks = array(); | ||
|
||
do { | ||
if($next_token) { | ||
$response = $sdb->select($select, array('NextToken' => $next_token)); | ||
} else { | ||
$response = $sdb->select($select); | ||
} | ||
foreach($response->body->SelectResult->Item as $item) { | ||
$count++; | ||
$id_holder[$currId][(string)$item->Name] = null; | ||
if($count % 25 == 0) { | ||
$currId++; | ||
$id_holder[$currId] = array(); | ||
} | ||
$value = array(); | ||
foreach($item->Attribute as $attrib) { | ||
$value[(string)$attrib->Name] = (string)$attrib->Value; | ||
} | ||
|
||
$query[] = "(FROM_UNIXTIME(" . $value['time'] . "), '" . | ||
$value['keyword'] . "', '" . | ||
$value['referer'] . "', '" . | ||
$value['ua'] . "', '" . | ||
$value['ip'] . "', '" . | ||
yourls_geo_ip_to_countrycode($value['ip']) . "')"; | ||
|
||
if(!isset($clicks[$value['keyword']])) { | ||
$clicks[$value['keyword']] = 0; | ||
} | ||
$clicks[$value['keyword']]++; | ||
} | ||
|
||
$next_token = isset($response->body->SelectResult->NextToken) ? | ||
(string) $response->body->SelectResult->NextToken : | ||
null; | ||
} while($next_token); | ||
|
||
$q = "INSERT INTO `" . YOURLS_DB_TABLE_LOG . "` | ||
(click_time, shorturl, referrer, user_agent, ip_address, country_code) | ||
VALUES " . implode(",", $query); | ||
$ydb->query($q); | ||
|
||
|
||
foreach($clicks as $keyword => $click_count) { | ||
$ydb->query('UPDATE ' . YOURLS_DB_TABLE_URL . ' SET clicks = clicks + ' . $click_count . ' WHERE keyword = \'' . $keyword . '\''); | ||
} | ||
|
||
if($count == 0 ) { | ||
die("No clicks\n"); | ||
} | ||
|
||
echo "Inserted $count Clicks\n"; | ||
|
||
$deleted = 0; | ||
foreach($id_holder as $ids) { | ||
if(count($ids) > 0 ) { | ||
$deleted += count($ids); | ||
$response = $sdb->batch_delete_attributes(SDB_DOMAIN, $ids); | ||
} | ||
} | ||
|
||
echo "Deleted $deleted Clicks\n"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
/* | ||
Plugin Name: SimpleDB Logging | ||
Plugin URI: http://virgingroupdigital.wordpress.com | ||
Description: Pushes log updates to Amazon SimpleDB | ||
Version: 0.1 | ||
Author: Ian Barber <ian.barber@gmail.com> | ||
Author URI: http://phpir.com/ | ||
*/ | ||
include_once 'AWSSDKforPHP/sdk.class.php'; | ||
|
||
if( !class_exists( 'AmazonSDB' ) ) { | ||
yourls_die( 'This plugin requires with AWS SDK for PHP: http://aws.amazon.com/sdkforphp/' ); | ||
} | ||
|
||
if(!defined('AWS_KEY') || !defined('AWS_SECRET_KEY')) { | ||
yourls_die( 'This plugin requires an amazon key. Define AWS_KEY and AWS_SECRET_KEY in your config.php' ); | ||
} | ||
|
||
/* Set this in config.php to use a specific region */ | ||
if(!defined('SDB_REGION')) { | ||
define("SDB_REGION", false); | ||
} | ||
|
||
/* Can override the database name in SDB */ | ||
if(!defined('SDB_DOMAIN')) { | ||
define('SDB_DOMAIN', 'yourlslog'); | ||
} | ||
|
||
yourls_add_filter( 'shunt_update_clicks', 'sdblog_shunt_update_clicks' ); | ||
yourls_add_filter( 'shunt_log_redirect', 'sdblog_shunt_log_redirect' ); | ||
yourls_add_filter( 'activated_plugin', 'sdblog_plugin_activate' ); | ||
|
||
/** | ||
* Activate the plugin by creating the SimpleDB queue. | ||
* | ||
* @return void | ||
**/ | ||
function sdblog_plugin_activate() | ||
{ | ||
$sdb = sdblog_get_database(); | ||
|
||
$response = $sdb->create_domain(SDB_DOMAIN); | ||
if(!$response->isOK()) { | ||
yourls_die( 'Could not create domain for SimpleDB logging' ); | ||
} | ||
} | ||
|
||
/** | ||
* Skip click updating - that will be processed out of the queue | ||
* | ||
* @return bool | ||
**/ | ||
function sdblog_shunt_update_clicks($false, $keyword) | ||
{ | ||
return true; | ||
} | ||
|
||
|
||
/** | ||
* Log clicks to SimpleDB | ||
* | ||
* @return bool | ||
**/ | ||
function sdblog_shunt_log_redirect($false, $keyword) | ||
{ | ||
$sdb = sdblog_get_database(); | ||
$values = array( | ||
'keyword' => yourls_sanitize_string( $keyword ), | ||
'referer' => ( isset( $_SERVER['HTTP_REFERER'] ) ? yourls_sanitize_url( $_SERVER['HTTP_REFERER'] ) : 'direct' ), | ||
'ua' => yourls_get_user_agent(), | ||
'ip' => yourls_get_IP(), | ||
'time' => time() | ||
); | ||
|
||
$response = $sdb->put_attributes(SDB_DOMAIN, uniqid(), $values); | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Return the SimpleDB object | ||
* | ||
* @return AmazonSDB | ||
**/ | ||
function sdblog_get_database() | ||
{ | ||
$sdb = new AmazonSDB(); | ||
if(defined('SDB_REGION') && SDB_REGION) { | ||
$sdb->set_region(SDB_REGION); | ||
} | ||
return $sdb; | ||
} |