Skip to content

Commit ec8c39f

Browse files
authored
Merge pull request #81 from alleyinteractive/feature/BASS-150/modernize-ad-layers-part-2
Feature/bass 150/modernize ad layers part 2
2 parents 2e8850a + b48681d commit ec8c39f

28 files changed

+4093
-8
lines changed

.github/workflows/phpcs.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: PHPCS
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
phpcs:
11+
name: PHP coding standards
12+
runs-on: ubuntu-latest
13+
strategy:
14+
fail-fast: true
15+
matrix:
16+
php: [7.4]
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v2
21+
22+
- name: Get Composer cache directory
23+
id: composer-cache
24+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
25+
26+
- name: Set up Composer caching
27+
uses: actions/cache@v2
28+
env:
29+
cache-name: cache-composer-dependencies
30+
with:
31+
path: ${{ steps.composer-cache.outputs.dir }}
32+
key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
33+
restore-keys: |
34+
${{ matrix.php }}-composer-
35+
36+
- name: Setup PHP
37+
uses: shivammathur/setup-php@v2
38+
with:
39+
php-version: ${{ matrix.php }}
40+
tools: composer:v2
41+
coverage: none
42+
43+
- name: Install dependencies
44+
uses: ramsey/composer-install@v1
45+
with:
46+
composer-options: "--no-progress --no-ansi --no-interaction"
47+
48+
- name: Log information
49+
run: |
50+
echo "$GITHUB_REF"
51+
echo "$GITHUB_EVENT_NAME"
52+
git --version
53+
php --version
54+
composer --version
55+
56+
- name: Validate Composer
57+
run: composer validate --strict
58+
59+
- name: Run PHPCS
60+
run: composer run phpcs

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ This defines what custom variables are available for targeting and makes them av
7373

7474
## Ad Servers
7575

76-
The architecture of Ad Layers abstracts the functionality that would be common to any ad server and allows for extending the built-in Ad_Layers_Ad_Server class to add support for additional ad servers. Currently, Ad Layers only supports DoubleClick for Publishers (DFP).
76+
The architecture of Ad Layers abstracts the functionality that would be common to any ad server and allows for extending the built-in Ad_Server class to add support for additional ad servers. Currently, Ad Layers only supports DoubleClick for Publishers (DFP).
7777

7878
### DFP
7979

@@ -169,13 +169,13 @@ ad_layers_dfp_after_ad_units
169169

170170
### Filter Hooks by Class
171171

172-
#### Ad_Layers_Ad_Server
172+
#### Ad_Server
173173

174174
ad_layers_ad_server_settings
175175

176176
ad_layers_ad_servers
177177

178-
ad_layer_ad_server_setting
178+
ad_layers_ad_server_setting
179179

180180
ad_layers_ad_server_get_domain
181181

ad-layers.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414

1515
namespace Ad_Layers;
1616

17+
// TODO: Remove if this remains unused.
18+
if ( ! defined( 'AD_LAYERS_OPTION_NAME' ) ) {
19+
/**
20+
* Option name for ad layers settings.
21+
*
22+
* @var string
23+
*/
24+
define( 'AD_LAYERS_OPTION_NAME', 'ad_layers' );
25+
}
26+
1727
// Include functions for working with assets (primarily JavaScript).
1828
require_once __DIR__ . '/inc/assets.php';
1929
require_once __DIR__ . '/inc/asset-loader-bridge.php';
@@ -23,3 +33,9 @@
2333

2434
// Include functions.php for registering custom post types, etc.
2535
require_once __DIR__ . '/functions.php';
36+
37+
// Include admin-facing features.
38+
if ( is_admin() ) {
39+
require_once __DIR__ . '/inc/class-ad-layers-admin.php';
40+
require_once __DIR__ . '/inc/class-ad-layers-meta-boxes.php';
41+
}

entries/ad-layers-admin/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './style.scss';

entries/ad-layers-admin/style.scss

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//--------------------------------------------------------------
2+
// Admin/Fieldmanager style helpers.
3+
//--------------------------------------------------------------
4+
5+
.fm-ad_layers-wrapper .fmjs-remove,
6+
.fm-ad_layers-wrapper .fm-add-another-wrapper {
7+
display: none;
8+
}
9+
10+
.ad-layers-column-list {
11+
margin: 0;
12+
padding: 0;
13+
14+
li {
15+
white-space: pre;
16+
}
17+
}

entries/ad-layers-dfp/index.js

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
import './style.scss';
2+
3+
// TODO: Refactor to remove jquery dependency.
4+
/* eslint-disable func-names, no-undef, no-array-constructor, no-param-reassign, consistent-return, prefer-destructuring, max-len */
5+
(function ($) {
6+
/*
7+
The AdLayersDFPAPI class implements functionality specific to DFP For the AdLayersAPI.
8+
*/
9+
AdLayersDFPAPI = function () {};
10+
11+
// Refreshes a specific ad unit
12+
AdLayersDFPAPI.prototype.refresh = function (adUnit) {
13+
if (typeof dfpAdUnits[adUnit] !== 'undefined') {
14+
googletag.pubads().refresh([dfpAdUnits[adUnit]]);
15+
}
16+
};
17+
18+
// Refreshes all ad units
19+
AdLayersDFPAPI.prototype.refreshAll = function () {
20+
if ($.isEmptyObject(dfpAdUnits) === false) {
21+
// DFP needs a numerical indexed array
22+
const unitsToRefresh = new Array();
23+
for (const adUnit in dfpAdUnits) {
24+
if (dfpAdUnits[adUnit]) {
25+
unitsToRefresh.push(dfpAdUnits[adUnit]);
26+
}
27+
}
28+
googletag.pubads().refresh(unitsToRefresh);
29+
}
30+
};
31+
32+
AdLayersDFPAPI.prototype.buildAd = function (slotName, path, sizes, targets, sizeMapping) {
33+
if (AdLayersAPI.isDebug()) {
34+
let adSizes = [];
35+
36+
if (sizeMapping) {
37+
// Get the appropriate sizes for this breakpoint
38+
let maxWidth = -1;
39+
let maxHeight = -1;
40+
$.each(sizeMapping, (index, value) => {
41+
if ($(window).width() >= value[0][0]
42+
&& $(window).height() >= value[0][1]
43+
&& value[0][0] >= maxWidth
44+
&& value[0][1] >= maxHeight
45+
) {
46+
maxWidth = value[0][0];
47+
maxHeight = value[0][1];
48+
adSizes = value[1];
49+
}
50+
});
51+
} else if (sizes && sizes[0]) {
52+
// Ensure sizes is a two-dimensional array
53+
if (!sizes[0][0]) {
54+
sizes = [sizes];
55+
}
56+
adSizes = sizes;
57+
}
58+
59+
AdLayersDFPAPI.addDebugPlaceholder($(`#${adLayersDFP.adUnitPrefix}${slotName}`), adSizes);
60+
} else {
61+
return googletag.cmd.push(() => {
62+
let key;
63+
let value;
64+
const divId = adLayersDFP.adUnitPrefix + slotName;
65+
dfpAdUnits = dfpAdUnits || {};
66+
dfpAdUnits[slotName] = googletag.defineSlot(path, sizes, divId);
67+
if (targets) {
68+
for (key in targets) {
69+
if (targets[key]) {
70+
value = targets[key];
71+
dfpAdUnits[slotName].setTargeting(key, value);
72+
}
73+
}
74+
}
75+
if (sizeMapping) {
76+
dfpAdUnits[slotName].defineSizeMapping(sizeMapping);
77+
}
78+
dfpAdUnits[slotName].addService(googletag.pubads());
79+
googletag.display(divId);
80+
});
81+
}
82+
};
83+
84+
AdLayersDFPAPI.prototype.lazyLoadAd = function (args) {
85+
if (!args.slotName) {
86+
return;
87+
}
88+
89+
if (args.format) {
90+
if (!(dfpAdDetails && dfpAdDetails[args.format])) {
91+
return;
92+
}
93+
if (!args.path) {
94+
args.path = dfpAdDetails[args.format].path;
95+
}
96+
if (!args.sizes) {
97+
args.sizes = dfpAdDetails[args.format].sizes;
98+
}
99+
if (!args.targeting) {
100+
args.targeting = dfpAdDetails[args.format].targeting;
101+
}
102+
if (!args.sizeMapping) {
103+
if (dfpBuiltMappings && dfpBuiltMappings[args.format]) {
104+
args.sizeMapping = dfpBuiltMappings[args.format];
105+
} else {
106+
args.sizeMapping = null;
107+
}
108+
}
109+
}
110+
return this.buildAd(args.slotName, args.path, args.sizes, args.targeting, args.sizeMapping);
111+
};
112+
113+
// Switches sizes in debug mode
114+
AdLayersDFPAPI.swapSizes = function ($size) {
115+
// Unselect all other sizes and set this one
116+
$size.siblings().removeClass('selected');
117+
$size.addClass('selected');
118+
119+
// Set the width and height
120+
$size.parents('.dfp-ad').width($size.data('width'));
121+
$size.parents('.dfp-ad').height($size.data('height'));
122+
123+
// Center the debug container vertically
124+
$size.parents('.dfp-debug-container').css({
125+
top: ($size.data('height') - $size.parents('.dfp-debug-container').outerHeight()) / 2,
126+
});
127+
};
128+
129+
AdLayersDFPAPI.addDebugPlaceholder = function ($adDiv, adSizes) {
130+
// Get the ad slot sizes for the current breakpoint
131+
const adSlot = $adDiv.data('adUnit');
132+
133+
// Set the background
134+
$adDiv.addClass('dfp-debug');
135+
136+
// Create a container for the ad data
137+
$container = $('<div>')
138+
.addClass('dfp-debug-container');
139+
140+
// Add a label
141+
$label = $('<div>')
142+
.addClass('dfp-debug-unit')
143+
.text(adSlot);
144+
$container.append($label);
145+
146+
// Add additional sizes for selection
147+
$.each(adSizes, (index, value) => {
148+
$link = $('<a>')
149+
.attr('href', '#')
150+
.data('width', value[0])
151+
.data('height', value[1])
152+
.text(`${value[0]}x${value[1]}`)
153+
.addClass('dfp-debug-size');
154+
155+
$container.append($link);
156+
});
157+
158+
// Add to the ad div
159+
$adDiv.append($container);
160+
161+
// Set to the first size
162+
AdLayersDFPAPI.swapSizes($adDiv.find('a').first());
163+
};
164+
165+
// Enables debug mode
166+
AdLayersDFPAPI.prototype.debug = function () {
167+
// Iterate through all of the ad units and display them in debug mode
168+
$('.dfp-ad').each(function () {
169+
const $adDiv = $(this);
170+
const adSlot = $adDiv.data('adUnit');
171+
172+
if (adSlot && dfpSizeMapping[adSlot] !== 'undefined') {
173+
// Get the appropriate sizes for this breakpoint
174+
let adSizes = [];
175+
let maxWidth = -1;
176+
let maxHeight = -1;
177+
$.each(dfpSizeMapping[adSlot], (index, value) => {
178+
if ($(window).width() >= value[0][0]
179+
&& $(window).height() >= value[0][1]
180+
&& value[0][0] >= maxWidth
181+
&& value[0][1] >= maxHeight
182+
) {
183+
maxWidth = value[0][0];
184+
maxHeight = value[0][1];
185+
adSizes = value[1];
186+
}
187+
});
188+
189+
AdLayersDFPAPI.addDebugPlaceholder($(this), adSizes);
190+
}
191+
});
192+
193+
// Add a debug bar with general layer information and a DFP console toggle
194+
$layerTitle = $('<div>')
195+
.addClass('dfp-ad-layer')
196+
.text(`${adLayersDFP.layerDebugLabel}: ${dfpAdLayer.title}`);
197+
198+
$googleConsole = $('<a>')
199+
.addClass('dfp-console')
200+
.attr('href', window.location.href.replace('adlayers_debug', 'googfc'))
201+
.text(adLayersDFP.consoleDebugLabel);
202+
203+
$debugBar = $('<div>')
204+
.attr('id', 'dfp-debug-bar')
205+
.addClass('dfp-debug')
206+
.append($layerTitle)
207+
.append($googleConsole);
208+
209+
$('body').append($debugBar);
210+
211+
// If the WordPress admin bar exists, push it down
212+
if ($('#wpadminbar').length) {
213+
$('#dfp-debug-bar').css('top', '32px');
214+
}
215+
};
216+
217+
// Handle click actions for swapping ad unit sizes
218+
$(document).ready(() => {
219+
$('body').on('click', 'a.dfp-debug-size', function (e) {
220+
e.preventDefault();
221+
AdLayersDFPAPI.swapSizes($(this));
222+
});
223+
});
224+
}(jQuery));

0 commit comments

Comments
 (0)