Skip to content

Commit a999eb6

Browse files
Merge branch 'develop'
Conflicts: ad-code-manager.php
2 parents 3f99b86 + 55686a6 commit a999eb6

File tree

7 files changed

+3082
-360
lines changed

7 files changed

+3082
-360
lines changed

ad-code-manager.php

Lines changed: 56 additions & 265 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Plugin URI: http://automattic.com
55
Description: Easy ad code management
66
Author: Rinat Khaziev, Jeremy Felt, Daniel Bachhuber, Automattic, doejo
7-
Version: 0.2.2-working
7+
Version: 0.2.2
88
Author URI: http://automattic.com
99
1010
GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
@@ -24,7 +24,7 @@
2424
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2525
2626
*/
27-
define( 'AD_CODE_MANAGER_VERSION', '0.2.2-working' );
27+
define( 'AD_CODE_MANAGER_VERSION', '0.2.2' );
2828
define( 'AD_CODE_MANAGER_ROOT' , dirname( __FILE__ ) );
2929
define( 'AD_CODE_MANAGER_FILE_PATH' , AD_CODE_MANAGER_ROOT . '/' . basename( __FILE__ ) );
3030
define( 'AD_CODE_MANAGER_URL' , plugins_url( '/', __FILE__ ) );
@@ -33,6 +33,7 @@
3333
require_once( AD_CODE_MANAGER_ROOT .'/common/lib/acm-provider.php' );
3434
require_once( AD_CODE_MANAGER_ROOT .'/common/lib/acm-wp-list-table.php' );
3535
require_once( AD_CODE_MANAGER_ROOT .'/common/lib/acm-widget.php' );
36+
require_once( AD_CODE_MANAGER_ROOT .'/common/lib/markdown.php' );
3637

3738
class Ad_Code_Manager
3839
{
@@ -59,7 +60,6 @@ function __construct() {
5960

6061
add_action( 'init', array( $this, 'action_load_providers' ) );
6162
add_action( 'init', array( $this, 'action_init' ) );
62-
add_action( 'current_screen', array( $this, 'action_admin_init' ) );
6363

6464
// Incorporate the link to our admin menu
6565
add_action( 'admin_menu' , array( $this, 'action_admin_menu' ) );
@@ -70,14 +70,8 @@ function __construct() {
7070
add_action('current_screen', array( $this, 'contextual_help' ) );
7171
add_action( 'widgets_init', array( $this, 'register_widget' ) );
7272
add_shortcode( 'acm-tag' , array( $this, 'shortcode' ) );
73-
}
74-
75-
/**
76-
* Initialize our subclass of WP_List_Table and set $items
77-
* Hooked to current_screen
78-
*/
79-
function action_admin_init() {
80-
$this->wp_list_table = new $this->providers->{$this->current_provider_slug}['table'];
73+
// Workaround for PHP 5.4 warning: Creating default object from empty value in
74+
$this->providers = new stdClass();
8175
}
8276

8377
/**
@@ -540,7 +534,31 @@ function post_admin_header() {
540534
* Hook in our submenu page to the navigation
541535
*/
542536
function action_admin_menu() {
543-
add_submenu_page( 'tools.php', $this->title, $this->title, $this->manage_ads_cap, $this->plugin_slug, array( $this, 'admin_view_controller' ) );
537+
$hook = add_submenu_page( 'tools.php', $this->title, $this->title, $this->manage_ads_cap, $this->plugin_slug, array( $this, 'admin_view_controller' ) );
538+
add_action( 'load-' . $hook, array( $this, 'action_load_ad_code_manager' ) );
539+
}
540+
541+
/**
542+
* Instantiate the List Table and handle our bulk actions on the load of the page
543+
*
544+
* @since 0.2.2
545+
*/
546+
function action_load_ad_code_manager() {
547+
548+
// Instantiate this list table
549+
$this->wp_list_table = new $this->providers->{$this->current_provider_slug}['table'];
550+
// Handle any bulk action requests
551+
switch( $this->wp_list_table->current_action() ) {
552+
case 'delete':
553+
check_admin_referer( 'acm-bulk-action', 'bulk-action-nonce' );
554+
$ad_code_ids = array_map( 'intval', $_REQUEST['ad-codes'] );
555+
foreach( $ad_code_ids as $ad_code_id ) {
556+
$this->delete_ad_code( $ad_code_id );
557+
}
558+
$redirect_url = add_query_arg( 'message', 'ad-codes-deleted', remove_query_arg( 'message', wp_get_referer() ) );
559+
wp_safe_redirect( $redirect_url );
560+
exit;
561+
}
544562
}
545563

546564
/**
@@ -550,12 +568,29 @@ function action_admin_menu() {
550568
function admin_view_controller() {
551569
require_once( AD_CODE_MANAGER_ROOT . '/common/views/ad-code-manager.tpl.php' );
552570
}
571+
572+
function parse_readme_into_contextual_help() {
573+
ob_start();
574+
include_once(AD_CODE_MANAGER_ROOT . '/readme.txt' );
575+
$readme = ob_get_clean();
576+
$sections = preg_split( "/==(.*)==/", $readme );
577+
// Something's wrong with readme, fail silently
578+
if ( 5 > count( $sections) )
579+
return;
580+
581+
$useful = array( $sections[3], $sections[2], $sections[4] );
582+
foreach ( $useful as $i => $tab ) {
583+
// Because WP.ORG Markdown has a different flavor
584+
$useful[$i] = Markdown( str_replace(array('= ', ' ='), '**', $tab ) );
585+
}
586+
return $useful;
587+
}
553588

554589
function contextual_help() {
555590
global $pagenow;
556591
if ( 'tools.php' != $pagenow || !isset( $_GET['page'] ) || $_GET['page'] != $this->plugin_slug )
557592
return;
558-
593+
list( $installation, $description, $configuration ) = $this->parse_readme_into_contextual_help();
559594
ob_start();
560595
?>
561596
<div id="conditionals-help">
@@ -582,267 +617,23 @@ function contextual_help() {
582617
</div>
583618
<?php
584619
$contextual_help = ob_get_clean();
585-
586-
ob_start();
587-
?>
588-
<p>Ad Code Manager gives non-developers an interface in the WordPress admin for configuring your complex set of ad codes.</p>
589-
<p>We tried to streamline the process and make everyday AdOps a little bit easier</p>
590-
<p>Depending on ad network you use, you will see a set of required fields to fill in (generally, "Ad Code" is a set of parameters you need to pass to ad server, so it could serve proper ad). Then you set conditionals. You can create ad code with conditionals in one easy step</p>
591-
<p>Priorities work pretty much the same way they work in WordPress. Lower numbers correspond with higher priority.
592-
<p>Once you've done creating ad codes, you can easily implement them in your theme using:</p>
593-
<ul>
594-
<li>template tag: <code>&lt;?php do_action( 'acm_tag', $tag_id ) ?&gt;</code> </li>
595-
<li>shortcode: [acm-tag id="tag_id"]</li>
596-
<li>or using widget</li>
597-
</ul>
598-
599-
<?php
600-
$overview = ob_get_clean();
601-
ob_start();
602-
?>
603-
<p>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.</p>
604-
605-
<a href="https://gist.github.com/1631131" target="_blank">Check out this gist</a> to see all of the filters in action.
606-
607-
<p><strong>acm_default_url</strong></p>
608-
609-
<p>Currently, we don't store tokenized script URL anywhere so this filter is a nice place to set default value.</p>
610-
611-
<p>Arguments: <br />
612-
* string $url The tokenized url of Ad Code</p>
613-
<p>Example usage: Set your default ad code URL</p>
614-
<pre>
615-
add_filter( 'acm_default_url', 'my_acm_default_url' );
616-
function my_acm_default_url( $url ) {
617-
if ( 0 === strlen( $url ) ) {
618-
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%;";
619-
}
620-
}
621-
</pre>
622-
623-
<p><strong>acm_output_tokens</strong></p>
624-
625-
<p>Register output tokens depending on the needs of your setup. Tokens are the keys to be replaced in your script URL.</p>
626-
627-
<p>Arguments: <br/>
628-
* array $output_tokens Any existing output tokens <br/>
629-
* string $tag_id Unique tag id <br/>
630-
* array $code_to_display Ad Code that matched conditionals
631-
</p>
632-
<p>Example usage: Test to determine whether you're in test or production by passing ?test=on query argument</p>
633-
634-
<pre>
635-
add_filter( 'acm_output_tokens', 'my_acm_output_tokens', 10, 3 );
636-
function my_acm_output_tokens( $output_tokens, $tag_id, $code_to_display ) {
637-
$output_tokens['%test%'] = isset( $_GET['test'] ) && $_GET['test'] == 'on' ? 'on' : '';
638-
return $output_tokens;
639-
}`
640-
</pre>
641-
642-
<p><strong>acm_ad_tag_ids</strong></p>
643-
644-
<p>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' ))</p>
645-
<p>Arguments: <br />
646-
* array $tag_ids array of default tag ids</p>
647-
648-
<p>Example usage: Add a new ad tag called 'my_top_leaderboard'</p>
649-
650-
<pre>
651-
add_filter( 'acm_ad_tag_ids', 'my_acm_ad_tag_ids' );
652-
function my_acm_ad_tag_ids( $tag_ids ) {
653-
$tag_ids[] = array(
654-
'tag' => 'my_top_leaderboard', // tag_id
655-
'url_vars' => array(
656-
'sz' => '728x90', // %sz% token
657-
'fold' => 'atf', // %fold% token
658-
'my_custom_token' => 'something' // %my_custom_token% will be replaced with 'something'
659-
);
660-
return $tag_ids;
661-
}
662-
</pre>
663-
664-
<p><strong>acm_output_html</strong></p>
665-
666-
<p>Support multiple ad formats ( e.g. Javascript ad tags, or simple HTML tags ) by adjusting the HTML rendered for a given ad tag.</p>
667-
668-
<p>Arguments: <br />
669-
* string $output_html The original output HTML <br />
670-
* string $tag_id Ad tag currently being accessed <br />
671-
</p>
672-
<p>Example usage:</p>
673-
<pre>
674-
add_filter( 'acm_output_html', 'my_acm_output_html', 10, 2 );
675-
function my_acm_output_html( $output_html, $tag_id ) {
676-
switch ( $tag_id ) {
677-
case 'my_leaderboard':
678-
$output_html = '&lt;a href="%url%"&gt; &lt;img src="%image_url%" /&gt;&lt;/a&gt;';
679-
break;
680-
case 'rich_media_leaderboard':
681-
$output_html = '&lt;script&gt; // omitted &lt;/script&gt;';
682-
break;
683-
default:
684-
break;
685-
}
686-
return $output_html;
687-
}
688-
</pre>
689-
<p><strong>acm_whitelisted_conditionals</strong></p>
690-
691-
<p>Extend the list of usable conditional functions with your own awesome ones. We whitelist these so users can't execute random PHP functions.</p>
692-
693-
<p>Arguments: <br />
694-
* array $conditionals Default conditionals</p>
695-
696-
<p>Example usage: Register a few custom conditional callbacks</p>
697-
698-
<pre>
699-
add_filter( 'acm_whitelisted_conditionals', 'my_acm_whitelisted_conditionals' );
700-
function my_acm_whitelisted_conditionals( $conditionals ) {
701-
$conditionals[] = 'my_is_post_type';
702-
$conditionals[] = 'is_post_type_archive';
703-
$conditionals[] = 'my_page_is_child_of';
704-
return $conditionals;
705-
}
706-
</pre>
707-
708-
<p><strong>acm_conditional_args</strong></p>
709-
710-
<p>For certain conditionals (has_tag, has_category), you might need to pass additional arguments.</p>
711-
712-
<p>Arguments: <br />
713-
* array $cond_args Existing conditional arguments <br />
714-
* string $cond_func Conditional function (is_category, is_page, etc)
715-
</p>
716-
717-
<p>Example usage: has_category() and has_tag() use has_term(), which requires the object ID to function properly</p>
718620

719-
<pre>
720-
add_filter( 'acm_conditional_args', 'my_acm_conditional_args', 10, 2 );
721-
function my_acm_conditional_args( $cond_args, $cond_func ) {
722-
global $wp_query;
723-
// has_category and has_tag use has_term
724-
// we should pass queried object id for it to produce correct result
725-
if ( in_array( $cond_func, array( 'has_category', 'has_tag' ) ) ) {
726-
if ( $wp_query->is_single == true ) {
727-
$cond_args[] = $wp_query->queried_object->ID;
728-
}
729-
}
730-
// my_page_is_child_of is our custom WP conditional tag and we have to pass queried object ID to it
731-
if ( in_array( $cond_func, array( 'my_page_is_child_of' ) ) && $wp_query->is_page ) {
732-
$cond_args[] = $cond_args[] = $wp_query->queried_object->ID;
733-
}
734-
735-
return $cond_args;
736-
}
737-
</pre>
738-
739-
<p><strong>acm_whitelisted_script_urls</strong></p>
740-
741-
<p>A security filter to whitelist which ad code script URLs can be added in the admin</p>
742-
743-
<p>Arguments: <br />
744-
* array $whitelisted_urls Existing whitelisted ad code URLs</p>
745-
746-
<p>Example usage: Allow Doubleclick for Publishers ad codes to be used</p>
747-
748-
<pre>add_filter( 'acm_whitelisted_script_urls', 'my_acm_whitelisted_script_urls' );
749-
function my_acm_whiltelisted_script_urls( $whitelisted_urls ) {
750-
$whitelisted_urls = array( 'ad.doubleclick.net' );
751-
return $whitelisted_urls;
752-
}
753-
</pre>
754-
755-
<p><strong>acm_display_ad_codes_without_conditionals</strong></p>
756-
757-
<p>Change the behavior of Ad Code Manager so that ad codes without conditionals display on the frontend. The default behavior is that each ad code requires a conditional to be included in the presentation logic.</p>
758-
759-
<p>Arguments: <br />
760-
* bool $behavior Whether or not to display the ad codes that don't have conditionals</p>
761-
762-
<p>Example usage:</p>
763-
764-
<pre>add_filter( 'acm_display_ad_codes_without_conditionals', '__return_true' );</pre>
765-
766-
<p><strong>acm_provider_slug</strong></p>
767-
768-
<p>By default we use our bundled doubleclick_for_publishers config ( check it in /providers/doubleclick-for-publishers.php ). If you want to add your own flavor of DFP or even implement configuration for some another ad network, you'd have to apply a filter to correct the slug.</p>
769-
770-
<p>Example usage:</p>
771-
772-
<pre>add_filter( 'acm_provider_slug', function() { return 'my-ad-network-slug'; })</pre>
773-
774-
<p><strong>acm_logical_operator</strong></p>
775-
776-
<p>By default logical operator is set to "OR", that is, ad code will be displayed if at least one conditional returns true.
777-
You can change it to "AND", so that ad code will be displayed only if ALL of the conditionals match</p>
778-
779-
<p>Example usage:</p>
780-
781-
<pre>add_filter( 'acm_provider_slug', function( $slug ) { return 'my-ad-network-slug'; })</pre>
782-
783-
<p><strong>acm_manage_ads_cap</strong></p>
784-
785-
<p>By default user has to have "manage_options" cap. This filter comes in handy, if you want to relax the requirements.</p>
786-
787-
<p>Example usage:</p>
788-
789-
<pre>add_filter( 'acm_manage_ads_cap', function( $cap ) { return 'edit_others_posts'; })</pre>
790-
791-
<p><strong>acm_allowed_get_posts_args</strong></p>
792-
793-
<p>This filter is only for edge cases. Most likely you won't have to touch it. Allows to include additional query args for Ad_Code_Manager->get_ad_codes() method.</p>
794-
795-
<p>Example usage:</p>
796-
797-
<code>add_filter( 'acm_allowed_get_posts_args', function( $args_array ) { return array( 'offset', 'exclude' ); })</code>
798-
799-
<p><strong>acm_ad_code_count</strong></p>
800-
801-
<p>By default the total number of ad codes to get is 50, which is reasonable for any small to mid site. However, in some certain cases you would want to increase the limit. This will affect Ad_Code_Manager->get_ad_codes() 'numberposts' query argument.</p>
802-
803-
<p>Example usage:</p>
804-
805-
<pre>add_filter( 'acm_ad_code_count', function( $total ) { return 100; })</pre>
806-
807-
<p><strong>acm_list_table_columns</strong></p>
808-
809-
<p>This filter can alter table columns that are displayed in ACM UI.</p>
810-
811-
<p>Example usage:</p>
812-
813-
<pre>add_filter( 'acm_list_table_columns', function ( $columns ) {
814-
$columns = array(
815-
'id' => __( 'ID', 'ad-code-manager' ),
816-
'name' => __( 'Name', 'ad-code-manager' ),
817-
'priority' => __( 'Priority', 'ad-code-manager' ),
818-
'conditionals' => __( 'Conditionals', 'ad-code-manager' ),
819-
);
820-
return $columns;
821-
} )
822-
</pre>
823-
<p><strong>acm_provider_columns</strong></p>
824-
825-
<p>This filter comes in pair with previous one, it should return array of ad network specific parameters. E.g. in acm_list_table_columns example we have
826-
'id', 'name', 'priority', 'conditionals'. All of them except name are generic for Ad Code Manager. Hence acm_provider_columns should return only "name"</p>
827-
828-
<p>Example usage:</p>
829-
<pre>add_filter( 'acm_provider_columns', function ( $columns ) {
830-
$columns = array(
831-
'name' => __( 'Name', 'ad-code-manager' ),
832-
);
833-
return $columns;
834-
} )</pre>
835-
<?php
836-
$configuration = ob_get_clean();
837621

838622

839623
get_current_screen()->add_help_tab(
840624
array(
841625
'id' => 'acm-overview',
842626
'title' => 'Overview',
843-
'content' => $overview,
627+
'content' => $description,
844628
)
845629
);
630+
get_current_screen()->add_help_tab(
631+
array(
632+
'id' => 'acm-install',
633+
'title' => 'Installation',
634+
'content' => $installation,
635+
)
636+
);
846637
get_current_screen()->add_help_tab(
847638
array(
848639
'id' => 'acm-config',

0 commit comments

Comments
 (0)