Skip to content

Commit

Permalink
Prebid 7: remove support for legacy FPD (#8372)
Browse files Browse the repository at this point in the history
* Remove conversion from 'fpd' to 'ortb2' in setConfig

* Convert uses (or really, un-uses) of legacy-formatted FPD in tests

* Remove uses of `convertLegacyFpd` where possible; move logic outside of `config`

* Move  from core to inmarBidAdapter
  • Loading branch information
dgirardi authored Jun 1, 2022
1 parent a3364b5 commit a5f1ae8
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 196 deletions.
11 changes: 5 additions & 6 deletions modules/adrelevantisBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,12 @@ export const spec = {
payload.referrer_detection = refererinfo;
}

let fpdcfg = config.getLegacyFpd(bidderRequest.ortb2);
if (fpdcfg && fpdcfg.context) {
let fdata = {
keywords: fpdcfg.context.keywords || '',
category: fpdcfg.context.data.category || ''
const ortb2Site = bidderRequest.ortb2?.site;
if (ortb2Site) {
payload.fpd = {
keywords: ortb2Site.keywords || '',
category: deepAccess(ortb2Site, 'ext.data.category') || ''
}
payload.fpd = fdata;
}

const request = formatRequest(payload, bidderRequest);
Expand Down
3 changes: 1 addition & 2 deletions modules/beopBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export const spec = {
buildRequests: function(validBidRequests, bidderRequest) {
const slots = validBidRequests.map(beOpRequestSlotsMaker);
const pageUrl = getPageUrl(bidderRequest.refererInfo, window);
const fpd = config.getLegacyFpd(bidderRequest.ortb2);
const gdpr = bidderRequest.gdprConsent;
const firstSlot = slots[0];
const payloadObject = {
Expand All @@ -48,7 +47,7 @@ export const spec = {
pid: firstSlot.pid,
url: pageUrl,
lang: (window.navigator.language || window.navigator.languages[0]),
kwds: (fpd && fpd.site && fpd.site.keywords) || [],
kwds: bidderRequest.ortb2?.site?.keywords || [],
dbg: false,
slts: slots,
is_amp: deepAccess(bidderRequest, 'referrerInfo.isAmp'),
Expand Down
25 changes: 23 additions & 2 deletions modules/inmarBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { logError } from '../src/utils.js';
import {logError, mergeDeep} from '../src/utils.js';
import { config } from '../src/config.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
Expand Down Expand Up @@ -40,7 +40,7 @@ export const spec = {
uspConsent: bidderRequest.uspConsent,
currencyCode: config.getConfig('currency.adServerCurrency'),
coppa: config.getConfig('coppa'),
firstPartyData: config.getLegacyFpd(bidderRequest.ortb2),
firstPartyData: getLegacyFpd(bidderRequest.ortb2),
prebidVersion: '$prebid.version$'
};

Expand Down Expand Up @@ -107,4 +107,25 @@ export const spec = {
}
};

function getLegacyFpd(ortb2) {
if (typeof ortb2 !== 'object') return;

let duplicate = {};

Object.keys(ortb2).forEach((type) => {
let prop = (type === 'site') ? 'context' : type;
duplicate[prop] = (prop === 'context' || prop === 'user') ? Object.keys(ortb2[type]).filter(key => key !== 'data').reduce((result, key) => {
if (key === 'ext') {
mergeDeep(result, ortb2[type][key]);
} else {
mergeDeep(result, {[key]: ortb2[type][key]});
}

return result;
}, {}) : ortb2[type];
});

return duplicate;
}

registerBidder(spec);
6 changes: 6 additions & 0 deletions modules/luponmediaBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@ function newOrtbBidRequest(bidRequest, bidderRequest, currentImps) {
deepSetValue(data, 'source.ext.schain', bidRequest.schain);
}

// TODO: getConfig('fpd.context') should not have worked even with legacy FPD support - 'fpd' gets translated
// into 'ortb2' by `setConfig`
// Unclear what the intent was here - maybe `const {context: siteData, user: userData} = getLegacyFpd(config.getConfig('ortb2'))` ?
// (with PB7 `config.getConfig('ortb2')` should be replaced by `bidderRequest.ortb2`)
const siteData = Object.assign({}, bidRequest.params.inventory, config.getConfig('fpd.context'));
const userData = Object.assign({}, bidRequest.params.visitor, config.getConfig('fpd.user'));

Expand All @@ -453,6 +457,8 @@ function newOrtbBidRequest(bidRequest, bidderRequest, currentImps) {
deepSetValue(data, 'ext.prebid.bidderconfig.0', bidderData);
}

// TODO: bidRequest.fpd is not the right place for pbadslot - who's filling that in, if anyone?
// is this meant to be bidRequest.ortb2Imp.ext.data.pbadslot?
const pbAdSlot = deepAccess(bidRequest, 'fpd.context.pbAdSlot');
if (typeof pbAdSlot === 'string' && pbAdSlot) {
deepSetValue(data.imp[0].ext, 'context.data.adslot', pbAdSlot);
Expand Down
3 changes: 1 addition & 2 deletions modules/zeta_global_sspBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,12 @@ export const spec = {
if (!impData.banner && !impData.video) {
impData.banner = buildBanner(request);
}
const fpd = config.getLegacyFpd(bidderRequest.ortb2) || {};
let payload = {
id: bidderRequest.auctionId,
cur: [DEFAULT_CUR],
imp: [impData],
site: params.site ? params.site : {},
device: {...fpd.device, ...params.device},
device: {...(bidderRequest.ortb2?.device || {}), ...params.device},
user: params.user ? params.user : {},
app: params.app ? params.app : {},
ext: {
Expand Down
132 changes: 7 additions & 125 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,119 +367,6 @@ export function newConfig() {
return bidderConfig;
}

/**
* Returns backwards compatible FPD data for modules
*/
function getLegacyFpd(obj) {
if (typeof obj !== 'object') return;

let duplicate = {};

Object.keys(obj).forEach((type) => {
let prop = (type === 'site') ? 'context' : type;
duplicate[prop] = (prop === 'context' || prop === 'user') ? Object.keys(obj[type]).filter(key => key !== 'data').reduce((result, key) => {
if (key === 'ext') {
mergeDeep(result, obj[type][key]);
} else {
mergeDeep(result, {[key]: obj[type][key]});
}

return result;
}, {}) : obj[type];
});

return duplicate;
}

/**
* Returns backwards compatible FPD data for modules
*/
function getLegacyImpFpd(obj) {
if (typeof obj !== 'object') return;

let duplicate = {};

if (deepAccess(obj, 'ext.data')) {
Object.keys(obj.ext.data).forEach((key) => {
if (key === 'pbadslot') {
mergeDeep(duplicate, {context: {pbAdSlot: obj.ext.data[key]}});
} else if (key === 'adserver') {
mergeDeep(duplicate, {context: {adServer: obj.ext.data[key]}});
} else {
mergeDeep(duplicate, {context: {data: {[key]: obj.ext.data[key]}}});
}
});
}

return duplicate;
}

/**
* Copy FPD over to OpenRTB standard format in config
*/
function convertFpd(opt) {
let duplicate = {};

Object.keys(opt).forEach((type) => {
let prop = (type === 'context') ? 'site' : type;
duplicate[prop] = (prop === 'site' || prop === 'user') ? Object.keys(opt[type]).reduce((result, key) => {
if (key === 'data') {
mergeDeep(result, {ext: {data: opt[type][key]}});
} else {
mergeDeep(result, {[key]: opt[type][key]});
}

return result;
}, {}) : opt[type];
});

return duplicate;
}

/**
* Copy Impression FPD over to OpenRTB standard format in config
* Only accepts bid level context.data values with pbAdSlot and adServer exceptions
*/
function convertImpFpd(opt) {
let duplicate = {};

Object.keys(opt).filter(prop => prop === 'context').forEach((type) => {
Object.keys(opt[type]).forEach((key) => {
if (key === 'data') {
mergeDeep(duplicate, {ext: {data: opt[type][key]}});
} else {
if (typeof opt[type][key] === 'object' && !Array.isArray(opt[type][key])) {
Object.keys(opt[type][key]).forEach(data => {
mergeDeep(duplicate, {ext: {data: {[key.toLowerCase()]: {[data.toLowerCase()]: opt[type][key][data]}}}});
});
} else {
mergeDeep(duplicate, {ext: {data: {[key.toLowerCase()]: opt[type][key]}}});
}
}
});
});

return duplicate;
}

/**
* Copy FPD over to OpenRTB standard format in each adunit
*/
function convertAdUnitFpd(arr) {
let convert = [];

arr.forEach((adunit) => {
if (adunit.fpd) {
(adunit['ortb2Imp']) ? mergeDeep(adunit['ortb2Imp'], convertImpFpd(adunit.fpd)) : adunit['ortb2Imp'] = convertImpFpd(adunit.fpd);
convert.push((({ fpd, ...duplicate }) => duplicate)(adunit));
} else {
convert.push(adunit);
}
});

return convert;
}

/*
* Sets configuration given an object containing key-value pairs and calls
* listeners that were added by the `subscribe` function
Expand All @@ -494,14 +381,13 @@ export function newConfig() {
let topicalConfig = {};

topics.forEach(topic => {
let prop = (topic === 'fpd') ? 'ortb2' : topic;
let option = (topic === 'fpd') ? convertFpd(options[topic]) : options[topic];
let option = options[topic];

if (isPlainObject(defaults[prop]) && isPlainObject(option)) {
option = Object.assign({}, defaults[prop], option);
if (isPlainObject(defaults[topic]) && isPlainObject(option)) {
option = Object.assign({}, defaults[topic], option);
}

topicalConfig[prop] = config[prop] = option;
topicalConfig[topic] = config[topic] = option;
});

callSubscribers(topicalConfig);
Expand Down Expand Up @@ -594,14 +480,13 @@ export function newConfig() {
bidderConfig[bidder] = {};
}
Object.keys(config.config).forEach(topic => {
let prop = (topic === 'fpd') ? 'ortb2' : topic;
let option = (topic === 'fpd') ? convertFpd(config.config[topic]) : config.config[topic];
let option = config.config[topic];

if (isPlainObject(option)) {
const func = mergeFlag ? mergeDeep : Object.assign;
bidderConfig[bidder][prop] = func({}, bidderConfig[bidder][prop] || {}, option);
bidderConfig[bidder][topic] = func({}, bidderConfig[bidder][topic] || {}, option);
} else {
bidderConfig[bidder][prop] = option;
bidderConfig[bidder][topic] = option;
}
});
});
Expand Down Expand Up @@ -691,9 +576,6 @@ export function newConfig() {
setBidderConfig,
getBidderConfig,
mergeBidderConfig,
convertAdUnitFpd,
getLegacyFpd,
getLegacyImpFpd
};
}

Expand Down
5 changes: 3 additions & 2 deletions src/prebid.js
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,8 @@ $$PREBID_GLOBAL$$.removeAdUnit = function (adUnitCode) {
$$PREBID_GLOBAL$$.requestBids = hook('async', function ({ bidsBackHandler, timeout, adUnits, adUnitCodes, labels, auctionId, ortb2 } = {}) {
events.emit(REQUEST_BIDS);
const cbTimeout = timeout || config.getConfig('bidderTimeout');
adUnits = (adUnits && config.convertAdUnitFpd(isArray(adUnits) ? adUnits : [adUnits])) || $$PREBID_GLOBAL$$.adUnits;
adUnits = adUnits || $$PREBID_GLOBAL$$.adUnits;
adUnits = (isArray(adUnits) ? adUnits : [adUnits]);
logInfo('Invoking $$PREBID_GLOBAL$$.requestBids', arguments);
const ortb2Fragments = {
global: mergeDeep({}, config.getAnyConfig('ortb2') || {}, ortb2 || {}),
Expand Down Expand Up @@ -687,7 +688,7 @@ $$PREBID_GLOBAL$$.requestBids.before(executeCallbacks, 49);
*/
$$PREBID_GLOBAL$$.addAdUnits = function (adUnitArr) {
logInfo('Invoking $$PREBID_GLOBAL$$.addAdUnits', arguments);
$$PREBID_GLOBAL$$.adUnits.push.apply($$PREBID_GLOBAL$$.adUnits, config.convertAdUnitFpd(isArray(adUnitArr) ? adUnitArr : [adUnitArr]));
$$PREBID_GLOBAL$$.adUnits.push.apply($$PREBID_GLOBAL$$.adUnits, isArray(adUnitArr) ? adUnitArr : [adUnitArr]);
// emit event
events.emit(ADD_AD_UNITS);
};
Expand Down
8 changes: 5 additions & 3 deletions test/spec/adUnits_spec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'src/prebid.js';

describe('Publisher API _ AdUnits', function () {
var assert = require('chai').assert;
var expect = require('chai').expect;
Expand All @@ -23,10 +25,10 @@ describe('Publisher API _ AdUnits', function () {
}
]
}, {
fpd: {
context: {
pbAdSlot: 'adSlotTest',
ortb2Imp: {
ext: {
data: {
pbadslot: 'adSlotTest',
inventory: [4],
keywords: 'foo,bar',
visitor: [1, 2, 3],
Expand Down
11 changes: 0 additions & 11 deletions test/spec/config_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,6 @@ describe('config API', function () {
expect(getConfig('foo')).to.eql({baz: 'qux'});
});

it('moves fpd config into ortb2 properties', function () {
setConfig({fpd: {context: {keywords: 'foo,bar', data: {inventory: [1]}}}});
expect(getConfig('ortb2')).to.eql({site: {keywords: 'foo,bar', ext: {data: {inventory: [1]}}}});
expect(getConfig('fpd')).to.eql(undefined);
});

it('moves fpd bidderconfig into ortb2 properties', function () {
setBidderConfig({bidders: ['bidderA'], config: {fpd: {context: {keywords: 'foo,bar', data: {inventory: [1]}}}}});
expect(getBidderConfig()).to.eql({'bidderA': {ortb2: {site: {keywords: 'foo,bar', ext: {data: {inventory: [1]}}}}}});
});

it('sets debugging', function () {
setConfig({ debug: true });
expect(getConfig('debug')).to.be.true;
Expand Down
Loading

0 comments on commit a5f1ae8

Please sign in to comment.