Skip to content

Commit

Permalink
Integrate fb instant articles (#9)
Browse files Browse the repository at this point in the history
* FIA wrap in an iframe

* FIA: Add referrer, aplus_data, javascript via the _attach_orbyd method and the adHelper.js file.

* FIA: correct width for Ads

* FIA: make ad-tag configurable

* Refactor token lookup into service (According to https://github.com/NoDiskInDriveA/module-ivw_integration/tree/8.x-1.x-fia-must-go-somewhere)
  • Loading branch information
tjwelde authored and dbosen committed Sep 5, 2016
1 parent f77a414 commit b73f6ef
Show file tree
Hide file tree
Showing 12 changed files with 889 additions and 166 deletions.
49 changes: 49 additions & 0 deletions ad_integration.module
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ function ad_integration_theme() {
'ad_tag' => NULL,
),
),
'ad_slot_fia' => array(
'template' => 'ad-slot-fia',
'variables' => array(
'referrer' => NULL,
'ad_tag' => NULL,
'data' => NULL,
'adengine' => NULL,
),
),
);
}

Expand Down Expand Up @@ -101,6 +110,46 @@ function ad_integration_page_attachments(array &$page) {
}
}

/**
* Adds the ad template for Facebook Instant Articles
*
* Implements hook_preprocess_views_view_row_fia().
*/
function ad_integration_preprocess_views_view_row_fia(&$variables) {
/** @var \Drupal\ad_integration\AdIntegrationInterface $advertisingService */
$advertisingService = \Drupal::service('ad_integration');
$ad_provider = $advertisingService->getAdProvider();

$config = Drupal::config('ad_integration.settings');
$ad_tag = $config->get('adsc_fia_tag');

$node = $variables['row']['#node'];
$data = array('entity' => $node);

if ($ad_provider == 'orbyd' && !empty($ad_tag)) {
$adRender = array(
'#theme' => 'ad_slot_fia',
'#referrer' => $GLOBALS['base_url'],
'#ad_tag' => $ad_tag,
'#data' => array(
'adunit1' => $advertisingService->getAdUnit1($data),
'adunit2' => $advertisingService->getAdUnit2($data),
'adunit3' => $advertisingService->getAdUnit3($data),
'keyword' => $advertisingService->getKeyword($data),
'admode' => $advertisingService->getAdMode($data),
),
);
$adengine = $advertisingService->getAdEngine();
if ($adengine) {
$adRender += array(
'#adengine' => $adengine,
);
}
$adHtml = render($adRender);
$variables['options']['automatic_ad'] = $adHtml;
}
}

/**
* @param array $page
* @param $advertisingService
Expand Down
5 changes: 4 additions & 1 deletion ad_integration.services.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
services:
ad_integration:
class: Drupal\ad_integration\AdIntegration
arguments: ['@entity_type.manager', '@entity.query', '@config.factory', '@path.matcher', '@current_route_match', '@token']
arguments: ['@config.factory', '@token']
ad_integration.lookup:
class: Drupal\ad_integration\AdIntegrationLookup
arguments: ['@current_route_match', '@config.factory', '@entity_type.manager']
123 changes: 29 additions & 94 deletions ad_integration.tokens.inc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
* Builds placeholder replacement tokens for ad-related data.
*/

use Drupal\node\Entity\Node;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Component\Utility\Xss;
use Drupal\taxonomy\Entity\Term;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\taxonomy\TermInterface;

/**
* Implements hook_token_info().
Expand Down Expand Up @@ -57,103 +57,38 @@ function ad_integration_tokens($type, $tokens, array $data, array $options, Bubb
$replacements = array();

if ($type == 'advertising') {
foreach ($tokens as $name => $original) {
$replacement = ad_integration_get_setting($name);
$replacements[$original] = $sanitize ? Xss::filter($replacement) : $replacement;
}
}

return $replacements;
}

function ad_integration_get_setting($name) {
/* @var CurrentRouteMatch $currentRoutematch */
$currentRoutematch = \Drupal::service('current_route_match');

$parameters = ['node', 'taxonomy_term'];

$entity = NULL;
foreach ($parameters as $parameter) {
/* @var ContentEntityInterface $entity */
if ($entity = $currentRoutematch->getParameter($parameter)) {

// The Entity might not be loaded so we need to check if we only
// got the entity id.
if (is_numeric($entity)) {
switch ($parameter) {
case "node":
$entity = Node::load($entity);
break;

case "taxonomy_term":
$entity = Term::load($entity);
break;

default:
break;
}
}

// Search for ad_integration_settings field.
foreach ($entity->getFieldDefinitions() as $fieldDefinition) {
$fieldType = $fieldDefinition->getType();

// If settings are found, check if an overridden value for the
// given setting is found and return that.
$overiddenSetting = get_overridden_ad_setting($name, $fieldDefinition, $entity);
if (isset($overiddenSetting)) {
return $overiddenSetting;
}

// Check for fallback categories if no ad_integration_setting is found.
if (!isset($termOverride) && $fieldType === 'entity_reference' && $fieldDefinition->getSetting('target_type') === 'taxonomy_term') {
$fieldName = $fieldDefinition->getName();
if ($tid = $entity->$fieldName->target_id) {
if ($term = Term::load($tid)) {
$termOverride = get_overridden_ad_setting_from_term($name, $term);
}
}
}
}

// If we not returned before, it is possible,
// that we found a termOverride.
if (isset($termOverride)) {
return $termOverride;
}
$lookupFrom = 'currentRoute';
if (isset($data['entity']) && $data['entity'] instanceof ContentEntityInterface) {
$lookupFrom = 'entity';
}
}

$default_setting_key = $name . '_default';
return \Drupal::config('ad_integration.settings')->get($default_setting_key);
}

/**
* @param $name
* @param $fieldDefinition
* @param $entity
*/
function get_overridden_ad_setting($name, $fieldDefinition, $entity) {
if ($fieldDefinition->getType() === 'ad_integration_settings') {
$fieldName = $fieldDefinition->getName();
if (!empty($entity->$fieldName->get(0)->$name)) {
return $entity->$fieldName->get(0)->$name;
elseif (isset($data['term']) && $data['term'] instanceof TermInterface) {
$lookupFrom = 'term';
}
}
}

function get_overridden_ad_setting_from_term($name, Term $term) {
foreach ($term->getFieldDefinitions() as $fieldDefinition) {
$override = get_overridden_ad_setting($name, $fieldDefinition, $term);
if (isset($override)) {
return $override;
/** @var \Drupal\ad_integration\AdIntegrationLookupInterface $lookup */
$lookup = \Drupal::service('ad_integration.lookup');
foreach ($tokens as $name => $original) {
switch ($lookupFrom) {
case 'currentRoute':
$replacement = $lookup->byCurrentRoute($name);
break;

case 'entity':
$replacement = $lookup->byEntity($name, $data['entity']);
break;

case 'term':
$replacement = $lookup->byTerm($name, $data['term']);
break;

default:
$replacement = NULL;
break;
}
$replacements[$original] = $sanitize ? Xss::filter($replacement) : $replacement;
}
}

foreach (\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadParents($term->id()) as $parent) {
$override = get_overridden_ad_setting_from_term($name, $parent);
if (isset($override)) {
return $override;
}
}
return $replacements;
}
14 changes: 7 additions & 7 deletions config/install/ad_integration.settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ adsc_unit1_default: ''
adsc_unit2_default: ''
adsc_unit3_default: ''

adsc_unit2_values: ''
adsc_unit3_values: ''
adsc_unit2_values: []
adsc_unit3_values: []

adsc_unit1_overridable: 0
adsc_unit2_overridable: 1
adsc_unit3_overridable: 1
adsc_unit1_overridable: false
adsc_unit2_overridable: true
adsc_unit3_overridable: true

adsc_mode_default: ''
adsc_mode_overridable: 0
adsc_mode_overridable: false

adsc_keyword: ''
adsc_keyword: ''
11 changes: 7 additions & 4 deletions config/schema/ad_integration.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,26 @@ ad_integration.settings:
adsc_unit1_default:
type: string
label: 'Ad unit 1'
adsc_unit1_overridable:
type: boolean
label: 'Ad unit 1 is overridable'
adsc_unit2_default:
type: string
label: 'Ad unit 2'
adsc_unit2_overridable:
type: bool
type: boolean
label: 'Ad unit 2 is overridable'
adsc_unit3_default:
type: string
label: 'Ad unit 3'
adsc_unit3_overridable:
type: bool
type: boolean
label: 'Ad unit 3 is overridable'
adsc_mode_default:
type: string
label: 'Adsc mode'
adsc_mode_overridable:
type: bool
type: boolean
label: 'Adsc mode is overridable'
adsc_unit2_values:
type: sequence
Expand All @@ -49,4 +52,4 @@ ad_integration.settings:
label: 'Possible Ad unit 3 values'
sequence:
type: string
label: 'Value'
label: 'Value'
64 changes: 10 additions & 54 deletions src/AdIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,13 @@
* @package Drupal\ad_integration
*/
class AdIntegration implements AdIntegrationInterface {
/**
* The entity storage object for taxonomy terms.
*
* @var TermStorageInterface
*/
protected $termStorage;

/**
* The entity query object for nodes.
*
* @var \Drupal\Core\Entity\Query\Sql\Query
*/
protected $nodeQuery;

/**
* The config factory.
*
* @var ImmutableConfig
*/
protected $settings;

/**
* The current path match.
*
* @var PathMatcher
*/
protected $pathMatch;

/**
* The current route match.
*
* @var CurrentRouteMatch
*/
protected $currentRouteMatch;

/**
* The token object.
*
Expand All @@ -60,68 +32,52 @@ class AdIntegration implements AdIntegrationInterface {
/**
* Generates Advertising information.
*
* @param EntityTypeManagerInterface $entity_manager
* The entity query object for taxonomy terms.
* @param QueryFactory $query
* The entity query object for taxonomy terms.
* @param ConfigFactoryInterface $config_factory
* The config factory service.
* @param PathMatcher $path_match
* The current path match.
* @param CurrentRouteMatch $current_route_match
* The current route match.
* @param Token $token
* Token service.
*/
public function __construct(
EntityTypeManagerInterface $entity_manager,
QueryFactory $query,
ConfigFactoryInterface $config_factory,
PathMatcher $path_match,
CurrentRouteMatch $current_route_match,
Token $token
) {
$this->termStorage = $entity_manager->getStorage('taxonomy_term');
$this->nodeQuery = $query->get('node');
$this->settings = $config_factory->get('ad_integration.settings');
$this->pathMatch = $path_match;
$this->currentRouteMatch = $current_route_match;
$this->token = $token;
}

/**
* {@inheritdoc}
*/
public function getAdUnit1() {
return $this->token->replace('[advertising:adsc_unit1]', array(), array('sanitize' => FALSE));
public function getAdUnit1($data = array()) {
return $this->token->replace('[advertising:adsc_unit1]', $data, array('sanitize' => FALSE));
}

/**
* {@inheritdoc}
*/
public function getAdUnit2() {
return $this->token->replace('[advertising:adsc_unit2]', array(), array('sanitize' => FALSE));
public function getAdUnit2($data = array()) {
return $this->token->replace('[advertising:adsc_unit2]', $data, array('sanitize' => FALSE));
}

/**
* {@inheritdoc}
*/
public function getAdUnit3() {
return $this->token->replace('[advertising:adsc_unit3]', array(), array('sanitize' => FALSE));
public function getAdUnit3($data = array()) {
return $this->token->replace('[advertising:adsc_unit3]', $data, array('sanitize' => FALSE));
}

/**
* {@inheritdoc}
*/
public function getKeyword() {
return $this->token->replace('[advertising:adsc_keyword]', array(), array('sanitize' => FALSE));
public function getKeyword($data = array()) {
return $this->token->replace('[advertising:adsc_keyword]', $data, array('sanitize' => FALSE));
}

/**
* {@inheritdoc}
*/
public function getAdMode() {
return $this->token->replace('[advertising:adsc_mode]', array(), array('sanitize' => FALSE));
public function getAdMode($data = array()) {
return $this->token->replace('[advertising:adsc_mode]', $data, array('sanitize' => FALSE));
}

/**
Expand Down
Loading

0 comments on commit b73f6ef

Please sign in to comment.