Skip to content
This repository has been archived by the owner on Jun 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #147 from BurdaMagazinOrg/feature/INREL-6531-amazo…
Browse files Browse the repository at this point in the history
…n-tag-non-productdb

INREL-6531: Replace Amazon tag for non-ProductDB products
  • Loading branch information
IT-Cru authored Oct 16, 2019
2 parents b346fba + 4f97a16 commit 0cfbb44
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
<?php

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\file\Entity\File;
use Drupal\infinite_advertising_products\ReplaceAmazonTags;

/**
* Implements hook_ENTITY_TYPE_presave() for advertising_product entities.
*/
function infinite_advertising_products_advertising_product_presave(EntityInterface $entity) {
if ($entity->bundle() == 'advertising_product_tracdelight') {
/** @var \Drupal\advertising_products\Entity\AdvertisingProduct $entity */
Expand Down Expand Up @@ -69,3 +74,46 @@ function infinite_advertising_products_preprocess_advertising_product(&$variable
// Provide data_attributes for advertising product TWIG file.
$variables['data_attributes'] = $data_attributes;
}

/**
* Implements hook_ENTITY_TYPE_view_alter() for node entities.
*/
function infinite_advertising_products_node_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
$view_modes = [
'amp',
'full',
'lazyloading',
];
if (($entity->hasField('field_amazon_tag'))
&& !$entity->field_amazon_tag->isEmpty()
&& in_array($build['#view_mode'], $view_modes)) {

$build['#post_render'][] = 'infinite_advertising_products_replace_amazon_tag';
}
}

/**
* Post render callback to replace Amazon tag for non-ProductDB products.
*
* @param $markup
* The markup result of the rendering.
*
* @param $elements
* The elements of the rendering.
*
* @return mixed
* The markup result.
*/
function infinite_advertising_products_replace_amazon_tag($markup, $elements) {
$node = $elements['#node'];
$replaceAttr = 'data-external-url';

// We need on AMP another attribute to replace.
if ($view_mode = $elements['#view_mode'] == 'amp') {
$replaceAttr = 'href';
}

$contentReplaceAmazonTags = new ReplaceAmazonTags($node->field_amazon_tag->value, $replaceAttr);
$contentReplaceAmazonTags->replaceAmazonTags($markup);
return $contentReplaceAmazonTags->getMarkup();
}
126 changes: 126 additions & 0 deletions modules/infinite_advertising_products/src/ReplaceAmazonTags.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php

namespace Drupal\infinite_advertising_products;

use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Render\Markup;
use Drupal\Core\Url;
use QueryPath\DOMQuery;
use Symfony\Component\DomCrawler\Crawler;

/**
* Defines a Replace Amazon Tags object.
*
* @package Drupal\infinite_advertising_products
*/
class ReplaceAmazonTags {

/**
* Overridden Amazon Tag.
*
* @var string
*/
protected $amazonTag;

/**
* The Symfony DOM crawler.
*
* @var Crawler
*/
protected $crawler;

/**
* The QueryPath DOM query.
*
* @var DOMQuery
*/
protected $queryPath;

/**
* The attribute we want to replace.
*
* @var string
*/
protected $replaceAttr;

/**
* Array of product selectors for non-AMP.
*
* @var array
*/
protected $selectors = [
'a.item-product[data-vars-product-provider="amazon"]',
'.item-ecommerce[data-provider="amazon"]',
];

/**
* Constructs a ReplaceAmazonTags object.
*
* @param $amazonTag
* The Amazon tag to override.
* @param string $replaceAttr
* The attribute we want to replace.
*/
public function __construct($amazonTag, $replaceAttr = 'data-external-url') {
$this->amazonTag = $amazonTag;
$this->crawler = new Crawler();
$this->replaceAttr = $replaceAttr;
}

/**
* Replace Amazon tag for all non-ProductDB products in given HTML markup.
*
* @param \Drupal\Core\Render\Markup $markup
* The HTML markup to replace Amazon tag of Amazon products.
*/
public function replaceAmazonTags(Markup $markup) {

// Loading the html here instead of passing it into the constructor
// prevents problems with the charset.
$this->crawler->addHtmlContent($markup);

foreach ($this->selectors as $selector) {
$itemProducts = $this->crawler->filter($selector);
foreach ($itemProducts as $itemProduct) {
$amazonUrl = $itemProduct->getAttribute($this->replaceAttr);
if (parse_url($amazonUrl) !== FALSE) {
$itemProduct->setAttribute($this->replaceAttr, $this->getChangedAmazonUrl($amazonUrl));
}
}
}
}

/**
* Get Amazon URL with replaced Amazon tag.
*
* @param $amazonUrl
* The Amazon URL of a Amazon product.
*
* @return \Drupal\Core\GeneratedUrl|string
* The Amazon URL with replaced Amazon tag.
*/
private function getChangedAmazonUrl($amazonUrl) {
$amazonUrl = UrlHelper::parse($amazonUrl);
$amazonUrl['query']['tag'] = $this->amazonTag;
$options = [
'query' => $amazonUrl['query'],
'fragment' => $amazonUrl['fragment'],
];
return Url::fromUri($amazonUrl['path'], $options)->toString();
}

/**
* Get markup from given DOM crawler.
*
* @return \Drupal\Component\Render\MarkupInterface|string
*/
public function getMarkup() {
libxml_use_internal_errors(TRUE);
$this->queryPath = html5qp($this->crawler);
libxml_clear_errors();

$html = $this->queryPath->find('body')->innerHtml5();
return Markup::create($html);
}

}

0 comments on commit 0cfbb44

Please sign in to comment.