Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
danielbachhuber committed Feb 10, 2012
2 parents 41cc15f + 9bf1d97 commit a7d8c21
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 19 deletions.
57 changes: 44 additions & 13 deletions ad-code-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Plugin URI: http://automattic.com
Description: Easy ad code management
Author: Daniel Bachhuber, Rinat Khaziev, Automattic
Version: 0.1.1
Version: 0.1.2
Author URI: http://automattic.com
GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
Expand All @@ -24,7 +24,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
define( 'AD_CODE_MANAGER_VERSION', '0.1.1' );
define( 'AD_CODE_MANAGER_VERSION', '0.1.2' );
define( 'AD_CODE_MANAGER_ROOT' , dirname( __FILE__ ) );
define( 'AD_CODE_MANAGER_FILE_PATH' , AD_CODE_MANAGER_ROOT . '/' . basename( __FILE__ ) );
define( 'AD_CODE_MANAGER_URL' , plugins_url( '/', __FILE__ ) );
Expand Down Expand Up @@ -72,7 +72,10 @@ function action_init() {
'singular_name' => __( 'DFP Ad Codes' ),
);

// Allow new domains to be whitelisted
/**
* Configuration filter: acm_whitelisted_script_urls
* A security filter to whitelist which ad code script URLs can be added in the admin
*/
$this->whitelisted_script_urls = apply_filters( 'acm_whitelisted_script_urls', $this->whitelisted_script_urls );

// Allow other conditionals to be used
Expand All @@ -85,6 +88,10 @@ function action_init() {
'is_tag',
'has_tag',
);
/**
* Configuration filter: acm_whitelisted_conditionals
* Extend the list of usable conditional functions with your own awesome ones.
*/
$this->whitelisted_conditionals = apply_filters( 'acm_whitelisted_conditionals', $this->whitelisted_conditionals );
$this->logical_operator = apply_filters( 'acm_logical_operator', 'OR'); //allow users to filter default logical operator

Expand Down Expand Up @@ -137,6 +144,11 @@ function action_init() {
)
),
);
/**
* Configuration filter: acm_ad_tag_ids
* Extend set of default tag ids. Ad tag ids are used as a parameter
* for your template tag (e.g. do_action( 'acm_tag', 'my_top_leaderboard' ))
*/
$this->ad_tag_ids = apply_filters( 'acm_ad_tag_ids', $this->ad_tag_ids );

$this->register_acm_post_type();
Expand Down Expand Up @@ -314,7 +326,7 @@ function ad_code_edit_actions() {
$this->create_ad_code( $ad_code_vals );
break;
case 'edit':
$this->edit_ad_code( intval( $_GET[ 'id' ] ), $ad_code_vals );
$this->edit_ad_code( intval( $_POST[ 'id' ] ), $ad_code_vals );
break;
case 'del':
$this->delete_ad_code( intval( $_POST[ 'id' ] ) );
Expand All @@ -337,6 +349,7 @@ function conditionals_edit_actions() {
$result = $this->create_conditional( intval( $_GET['id'] ), $conditional_vals );
break;
case 'edit':
$conditional_vals['id'] = intval( $_POST['id'] ); // we need this for edit action to work correctly
$result = $this->edit_conditional( intval( $_GET['id'] ), $conditional_vals, true );
break;
case 'del':
Expand Down Expand Up @@ -383,7 +396,7 @@ function edit_ad_code( $ad_code_id, $ad_code = array() ) {
if ( 0 !== $ad_code_id && $ad_code['site_name'] && $ad_code['zone1'] ) {
update_post_meta( $ad_code_id, 'site_name', $ad_code['site_name'] );
update_post_meta( $ad_code_id, 'zone1', $ad_code['zone1'] );
}
}
return;
}

Expand Down Expand Up @@ -588,8 +601,13 @@ function register_ad_codes( $ad_codes = array() ) {
$ad_code = array_merge( $default, $ad_code );

foreach ( (array)$this->ad_tag_ids as $default_tag ) {
// May be we should add plugin setting for default url. For now just apply the filter which should return default url if $ad_code['url'] is empty
$this->register_ad_code( $default_tag['tag'], apply_filters( 'acm_empty_url', $ad_code['url'] ), $ad_code['conditionals'], array_merge( $default_tag['url_vars'], $ad_code['url_vars'] ) );
/**
* Configuration filter: acm_default_url
* If you don't specify a URL for your ad code when registering it in
* the WordPress admin or at a code level, you can simply apply it with
* a custom filter defined.
*/
$this->register_ad_code( $default_tag['tag'], apply_filters( 'acm_default_url', $ad_code['url'] ), $ad_code['conditionals'], array_merge( $default_tag['url_vars'], $ad_code['url_vars'] ) );
}
}
}
Expand Down Expand Up @@ -656,11 +674,16 @@ function action_acm_tag( $tag_id ) {
continue;

// Run our conditional and use any arguments that were passed
if ( !empty( $cond_args ) )
if ( !empty( $cond_args ) ) {
/**
* Configuration filter: acm_conditional_args
* For certain conditionals (has_tag, has_category), you might need to
* pass additional arguments.
*/
$result = call_user_func_array( $cond_func, apply_filters( 'acm_conditional_args', $cond_args, $cond_func ) );
else
} else {
$result = call_user_func( $cond_func );

}

// If our results don't match what we need, don't include this ad code
if ( $cond_result !== $result )
Expand Down Expand Up @@ -689,19 +712,27 @@ function action_acm_tag( $tag_id ) {
// @todo possibly complicated logic for determining which
// script is executed while factoring in:
// - priority against other ad codes

$code_to_display = $display_codes[0];

// Run $url aganist a whitelist to make sure it's a safe URL
if ( !$this->validate_script_url( $code_to_display['url'] ) )
return;

// Allow the user to filter the basic output HTML, possibly based on tag_id
// This can be useful if they need different script tags based
/**
* Configuration filter: acm_output_html
* Support multiple ad formats ( e.g. Javascript ad tags, or simple HTML tags )
* by adjusting the HTML rendered for a given ad tag.
*/
$output_html = apply_filters( 'acm_output_html', $this->output_html, $tag_id );

// Parse the output and replace any tokens we have left. But first, load the script URL
$output_html = str_replace( '%url%', $code_to_display['url'], $output_html );
/**
* Configuration filter: acm_output_tokens
* Register output tokens depending on the needs of your setup. Tokens are the
* keys to be replaced in your script URL.
*/
$output_tokens = apply_filters( 'acm_output_tokens', $this->output_tokens, $tag_id, $code_to_display );
foreach( (array)$output_tokens as $token => $val ) {
$output_html = str_replace( $token, $val, $output_html );
Expand Down
182 changes: 176 additions & 6 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,185 @@ Contributors: danielbachhuber, rinatkhaziev, automattic
Tags: advertising, ad codes
Requires at least: 3.1
Tested up to: 3.3.1
Stable tag: 0.1.1
Stable tag: 0.1.2

Easy ad code management.
Manage your ad codes through the WordPress admin in a safe and easy way.

== Description ==

Easily manage your ads via nice and simple UI. Each ad code has unlimited amount of conditionals. Conditionals are core WordPress methods like is_page(), is_category(), or your custom methods.
Ad Code Manager gives non-developers an interface in the WordPress admin for configuring your complex set of ad codes.

Currently works with:
To set things up, you'll need to add small template tags to your theme where you'd like your ads to appear. These are called "ad tags." Then, you'll need to define a common set of parameters for your ad provider. These parameters include all of the tag IDs you've established in your template, the default script URL, the default output, etc.

* Doubleclick for publishers
* More to come
Once this code-level configuration is in place, the Ad Code Manager admin interface will allow you to add new ad codes, modify the parameters for your script URL, and define conditionals to determine when the ad code appears. Conditionals are core WordPress functions like is_page(), is_category(), or your own custom functions.

Ad Code Manager currently works with Doubleclick for Publishers and [we'd like to abstract it to other providers](https://github.com/danielbachhuber/Ad-Code-Manager/issues/4)

[Fork the plugin on Github](https://github.com/danielbachhuber/Ad-Code-Manager) and [follow our development blog](http://adcodemanager.wordpress.com/).

== Installation ==

Since the plugin is in its early stages, there are a couple additional configuration steps:

1. Upload `ad-code-manager` to the `/wp-content/plugins/` directory
1. Activate the plugin through the 'Plugins' menu in WordPress
1. Incorporate ad tags in your theme template
1. Implement filters to make the plugin work with your provider
1. Configure your ad codes in the WordPress admin

== Configuration Filters ==

There are some filters which will allow you to easily customize output of the plugin. You should place these filters in your themes functions.php file or someplace safe.

[Check out this gist](https://gist.github.com/1631131) to see all of the filters in action.

= acm_default_url =

Currently, we don't store tokenized script URL anywhere so this filter is a nice place to set default value.

Arguments:
* string $url The tokenized url of Ad Code

Example usage: Set your default ad code URL

`add_filter( 'acm_default_url', 'my_acm_default_url' );
function my_acm_default_url( $url ) {
if ( 0 === strlen( $url ) ) {
return "http://ad.doubleclick.net/adj/%site_name%/%zone1%;s1=%zone1%;s2=;pid=%permalink%;fold=%fold%;kw=;test=%test%;ltv=ad;pos=%pos%;dcopt=%dcopt%;tile=%tile%;sz=%sz%;";
}
}`

= acm_output_tokens =

Register output tokens depending on the needs of your setup. Tokens are the keys to be replaced in your script URL.

Arguments:
* array $output_tokens Any existing output tokens
* string $tag_id Unique tag id
* array $code_to_display Ad Code that matched conditionals

Example usage: Test to determine whether you're in test or production by passing ?test=on query argument

`add_filter( 'acm_output_tokens', 'my_acm_output_tokens', 10, 3 );
function my_acm_output_tokens( $output_tokens, $tag_id, $code_to_display ) {
$output_tokens['%test%'] = isset( $_GET['test'] ) && $_GET['test'] == 'on' ? 'on' : '';
return $output_tokens;
}`

= acm_ad_tag_ids =

Extend set of default tag ids. Ad tag ids are used as a parameter for your template tag (e.g. do_action( 'acm_tag', 'my_top_leaderboard' ))

Arguments:
* array $tag_ids array of default tag ids

Example usage: Add a new ad tag called 'my_top_leaderboard'

`add_filter( 'acm_ad_tag_ids', 'my_acm_ad_tag_ids' );
function my_acm_ad_tag_ids( $tag_ids ) {
$tag_ids[] = array(
'tag' => 'my_top_leaderboard', // tag_id
'url_vars' => array(
'sz' => '728x90', // %sz% token
'fold' => 'atf', // %fold% token
'my_custom_token' => 'something' // %my_custom_token% will be replaced with 'something'
);
return $tag_ids;
}`

= acm_output_html =

Support multiple ad formats ( e.g. Javascript ad tags, or simple HTML tags ) by adjusting the HTML rendered for a given ad tag.

Arguments:
* string $output_html The original output HTML
* string $tag_id Ad tag currently being accessed

Example usage:

`add_filter( 'acm_output_html', 'my_acm_output_html', 10, 2 );
function my_acm_output_html( $output_html, $tag_id ) {
switch ( $tag_id ) {
case 'my_leaderboard':
$output_html = '<a href="%url%"><img src="%image_url%" /></a>';
break;
case 'rich_media_leaderboard':
$output_html = '<script> // omitted </script>';
break;
default:
break;
}
return $output_html;
}`

= acm_whitelisted_conditionals =

Extend the list of usable conditional functions with your own awesome ones. We whitelist these so users can't execute random PHP functions.

Arguments:
* array $conditionals Default conditionals

Example usage: Register a few custom conditional callbacks

`add_filter( 'acm_whitelisted_conditionals', 'my_acm_whitelisted_conditionals' );
function my_acm_whitelisted_conditionals( $conditionals ) {
$conditionals[] = 'my_is_post_type';
$conditionals[] = 'is_post_type_archive';
$conditionals[] = 'my_page_is_child_of';
return $conditionals;
}`

= acm_conditional_args =

For certain conditionals (has_tag, has_category), you might need to pass additional arguments.

Arguments:
* array $cond_args Existing conditional arguments
* string $cond_func Conditional function (is_category, is_page, etc)

Example usage: has_category() and has_tag() use has_term(), which requires the object ID to function properly

`add_filter( 'acm_conditional_args', 'my_acm_conditional_args', 10, 2 );
function my_acm_conditional_args( $cond_args, $cond_func ) {
global $wp_query;
// has_category and has_tag use has_term
// we should pass queried object id for it to produce correct result
if ( in_array( $cond_func, array( 'has_category', 'has_tag' ) ) ) {
if ( $wp_query->is_single == true ) {
$cond_args[] = $wp_query->queried_object->ID;
}
}
// my_page_is_child_of is our custom WP conditional tag and we have to pass queried object ID to it
if ( in_array( $cond_func, array( 'my_page_is_child_of' ) ) && $wp_query->is_page ) {
$cond_args[] = $cond_args[] = $wp_query->queried_object->ID;
}

return $cond_args;
}`

= acm_whitelisted_script_urls =

A security filter to whitelist which ad code script URLs can be added in the admin

Arguments:
* array $whitelisted_urls Existing whitelisted ad code URLs

Example usage: Allow Doubleclick for Publishers ad codes to be used

`add_filter( 'acm_whitelisted_script_urls', 'my_acm_whitelisted_script_urls' );
function my_acm_whiltelisted_script_urls( $whitelisted_urls ) {
$whitelisted_urls = array( 'ad.doubleclick.net' );
return $whitelisted_urls;
}`

== Changelog ==

= 0.1.2 (February 9, 2012) =
* Readme with full description and examples
* Bug fix: Save the proper value when editing actions

= 0.1.1 =
* Bug fix release

= 0.1 =
* Initial release

0 comments on commit a7d8c21

Please sign in to comment.