Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into fix/gtm_consent
Browse files Browse the repository at this point in the history
  • Loading branch information
huang-julien committed Sep 12, 2024
2 parents 69da2c6 + 62c950c commit efc3676
Show file tree
Hide file tree
Showing 18 changed files with 686 additions and 85 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules/
.DS_Store
lib/
.husky
dist/
dist/
vendor/
10 changes: 2 additions & 8 deletions data/google-analytics.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,12 @@
"key": "gtag"
},
{
"code": "window[{{l}}]=window[{{l}}]||[];window['gtag-'+{{l}}]=function (){window[{{l}}].push(arguments);};window['gtag-'+{{l}}]('consent', {{consentType}}, {{consentValues}});window['gtag-'+{{l}}]('js',new Date());window['gtag-'+{{l}}]('config',{{id}})",
"code": "window[{{l}}]=window[{{l}}]||[];window['gtag-'+{{l}}]=function (){window[{{l}}].push(arguments);};{{#consentValues}}window['gtag-'+{{l}}]('consent', {{consentType}}, {{consentValues}});{{/consentValues}}window['gtag-'+{{l}}]('js',new Date());window['gtag-'+{{l}}]('config',{{id}})",
"params": ["id"],
"optionalParams": {
"l": "dataLayer",
"consentType": "default",
"consentValues": {
"ad_user_data": "denied",
"ad_personalization": "denied",
"ad_storage": "denied",
"analytics_storage": "denied",
"wait_for_update": 500
}
"consentValues": null
},
"strategy": "worker",
"location": "head",
Expand Down
117 changes: 83 additions & 34 deletions inc/Data/ThirdPartyDataFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ThirdPartyDataFormatter
/**
* Formats third party data for a given set of input arguments and returns the corresponding output.
*
* @see https://github.com/GoogleChromeLabs/third-party-capital/blob/0831b937a8468e0f74bd79edd5a59fa8b2e6e763/src/utils/index.ts#L94
* @see https://github.com/GoogleChromeLabs/third-party-capital/blob/54cd44d1bd197a7809ab2f6ede4d13a973087c3d/src/utils/index.ts#L105
*
* @param ThirdPartyData $data Third party data to format.
* @param array<string, mixed> $args Input arguments to format third party data with.
Expand All @@ -31,15 +31,20 @@ public static function formatData(ThirdPartyData $data, array $args): ThirdParty
$htmlData = $data->getHtml();
$scriptsData = $data->getScripts();

$allScriptParams = array_reduce(
$scriptsData,
static function ($acc, ThirdPartyScriptData $scriptData) {
foreach ($scriptData->getParams() as $param) {
$acc[] = $param;
}
return $acc;
},
[]
$allScriptParams = array_unique(
array_reduce(
$scriptsData,
static function ($acc, ThirdPartyScriptData $scriptData) {
foreach ($scriptData->getParams() as $param) {
$acc[] = $param;
}
foreach (array_keys($scriptData->getOptionalParams()) as $param) {
$acc[] = $param;
}
return $acc;
},
[]
)
);

$scriptUrlParamInputs = self::intersectArgs($args, $allScriptParams);
Expand Down Expand Up @@ -84,20 +89,24 @@ static function ($acc, ThirdPartyScriptData $scriptData) {
}
if (isset($newData['scripts']) && $newData['scripts']) {
$newData['scripts'] = array_map(
static function ($scriptData) use ($scriptUrlParamInputs) {
static function ($scriptData) use ($args) {
if (isset($scriptData['url'])) {
$scriptData['url'] = self::formatUrl(
$scriptData['url'],
$scriptData['params'],
$scriptUrlParamInputs
$scriptData['params'] ?? [],
$args,
[],
$scriptData['optionalParams'] ?? []
);
} else {
$scriptData['code'] = self::formatCode(
$scriptData['code'],
$scriptUrlParamInputs
$args,
$scriptData['optionalParams'] ?? []
);
}
unset($scriptData['params']); // Params are irrelevant for formatted output.
// Params are irrelevant for formatted output.
unset($scriptData['params'], $scriptData['optionalParams']);
return $scriptData;
},
$newData['scripts']
Expand All @@ -110,7 +119,7 @@ static function ($scriptData) use ($scriptUrlParamInputs) {
/**
* Formats the given HTML arguments into an HTML string.
*
* @see https://github.com/GoogleChromeLabs/third-party-capital/blob/0831b937a8468e0f74bd79edd5a59fa8b2e6e763/src/utils/index.ts#L55
* @see https://github.com/GoogleChromeLabs/third-party-capital/blob/54cd44d1bd197a7809ab2f6ede4d13a973087c3d/src/utils/index.ts#L66
*
* @param string $element Element tag name for the HTML element.
* @param array<string, mixed> $attributes Attributes for the HTML element.
Expand Down Expand Up @@ -152,17 +161,24 @@ public static function formatHtml(
/**
* Formats the given URL arguments into a URL string.
*
* @see https://github.com/GoogleChromeLabs/third-party-capital/blob/0831b937a8468e0f74bd79edd5a59fa8b2e6e763/src/utils/index.ts#L28
* @see https://github.com/GoogleChromeLabs/third-party-capital/blob/54cd44d1bd197a7809ab2f6ede4d13a973087c3d/src/utils/index.ts#L28
*
* @param string $url Base URL.
* @param string[] $params Parameter names.
* @param array<string, mixed> $args Input arguments for the src attribute query parameters.
* @param array<string, mixed> $slugParamArg Optional. Input argument for the src attribute slug query parameter.
* Default empty array.
* @param string $url Base URL.
* @param string[] $params Parameter names.
* @param array<string, mixed> $args Input arguments for the src attribute query parameters.
* @param array<string, mixed> $slugParamArg Optional. Input argument for the src attribute slug query parameter.
* Default empty array.
* @param array<string, mixed> $optionalParams Optional. Optional parameter names and their defaults.
* Default empty array.
* @return string HTML string.
*/
public static function formatUrl(string $url, array $params, array $args, array $slugParamArg = []): string
{
public static function formatUrl(
string $url,
array $params,
array $args,
array $slugParamArg = [],
array $optionalParams = []
): string {
if ($slugParamArg) {
$slug = array_values($slugParamArg)[0];

Expand All @@ -179,34 +195,67 @@ public static function formatUrl(string $url, array $params, array $args, array
}
}

$queryArgs = [];
if ($params && $args) {
$queryArgs = self::intersectArgs($args, $params);
if ($queryArgs) {
$url = self::setUrlQueryArgs($url, $queryArgs);
}
if ($optionalParams) {
foreach ($optionalParams as $k => $v) {
if (isset($args[$k])) {
$queryArgs[$k] = $args[$k];
} elseif ($v) {
$queryArgs[$k] = $v;
}
}
}

if ($queryArgs) {
$url = self::setUrlQueryArgs($url, $queryArgs);
}

return $url;
}

/**
* Formats the given code arguments into a code string.
*
* @see https://github.com/GoogleChromeLabs/third-party-capital/blob/0831b937a8468e0f74bd79edd5a59fa8b2e6e763/src/utils/index.ts#L48
* @see https://github.com/GoogleChromeLabs/third-party-capital/blob/54cd44d1bd197a7809ab2f6ede4d13a973087c3d/src/utils/index.ts#L52
*
* @param string $code Code string with placeholders for URL query parameters.
* @param array<string, mixed> $args Input arguments for the src attribute query parameters.
* @param string $code Code string with placeholders for URL query parameters.
* @param array<string, mixed> $args Input arguments for the src attribute query parameters.
* @param array<string, mixed> $optionalParams Optional. Optional parameter names and their defaults.
* Default empty array.
* @return string HTML string.
*/
public static function formatCode(string $code, array $args): string
{
public static function formatCode(
string $code,
array $args,
array $optionalParams = []
): string {
// Conditionals.
$code = preg_replace_callback(
'/{{#([^{}]+?)}}(.*){{\/\1}}/',
static function ($matches) use ($args, $optionalParams) {
if ((isset($args[ $matches[1] ]) && $args[ $matches[1] ]) ||
(isset($optionalParams[ $matches[1] ]) && $optionalParams[ $matches[1] ])) {
return $matches[2];
}
return '';
},
$code
);

// Variables.
return preg_replace_callback(
'/{{([^}]+)}}/',
static function ($matches) use ($args) {
static function ($matches) use ($args, $optionalParams) {
if (isset($args[ $matches[1] ])) {
return $args[ $matches[1] ];
return json_encode($args[ $matches[1] ]);
}
return '';
if (isset($optionalParams[ $matches[1] ])) {
return json_encode($optionalParams[ $matches[1] ]);
}
return '""'; // The same as `json_encode('')`.
},
$code
);
Expand Down
7 changes: 4 additions & 3 deletions inc/Data/ThirdPartyHtmlAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace GoogleChromeLabs\ThirdPartyCapital\Data;

use GoogleChromeLabs\ThirdPartyCapital\Contracts\Arrayable;
use GoogleChromeLabs\ThirdPartyCapital\Util\HtmlAttributes;

/**
Expand All @@ -22,7 +23,7 @@ class ThirdPartyHtmlAttributes extends HtmlAttributes
*
* @param string $name Attribute name.
* @param mixed $value Attribute value.
* @return mixed Sanitized attribute value.
* @return string|bool|null|Arrayable Sanitized attribute value.
*/
protected function sanitizeAttr(string $name, $value)
{
Expand All @@ -36,8 +37,8 @@ protected function sanitizeAttr(string $name, $value)
/**
* Returns the attribute string for the given attribute name and value.
*
* @param string $name Attribute name.
* @param mixed $value Attribute value.
* @param string $name Attribute name.
* @param string|bool|null|Arrayable $value Attribute value.
* @return string HTML attribute string (starts with a space), or empty string to skip.
*/
protected function toAttrString(string $name, $value): string
Expand Down
3 changes: 0 additions & 3 deletions inc/Data/ThirdPartyHtmlData.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ private function validateData(array $htmlData): void
if (!isset($htmlData['attributes'])) {
throw new InvalidThirdPartyDataException('Missing HTML attributes.');
}
if (!isset($htmlData['attributes']['src'])) {
throw new InvalidThirdPartyDataException('Missing HTML src attribute.');
}
}

/**
Expand Down
23 changes: 22 additions & 1 deletion inc/Data/ThirdPartyScriptData.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ class ThirdPartyScriptData implements Arrayable
*/
private $params;

/**
* Optional parameters for the script and their defaults, if needed.
*
* @var array<string, mixed>
*/
private $optionalParams;

/**
* Constructor.
*
Expand Down Expand Up @@ -159,6 +166,16 @@ public function getParams(): array
return $this->params;
}

/**
* Gets the optional parameters for the script with their defaults, if needed.
*
* @return array<string, mixed> Optional parameters for the script, if needed.
*/
public function getOptionalParams(): array
{
return $this->optionalParams;
}

/**
* Determines whether the script is an external script.
*
Expand Down Expand Up @@ -192,6 +209,9 @@ public function toArray(): array
if ($this->params) {
$data['params'] = $this->params;
}
if ($this->optionalParams) {
$data['optionalParams'] = $this->optionalParams;
}

return $data;
}
Expand Down Expand Up @@ -278,6 +298,7 @@ private function setData(array $scriptData): void
$this->$field = isset($scriptData[ $field ]) ? (string) $scriptData[ $field ] : '';
}

$this->params = isset($scriptData['params']) ? array_map('strval', $scriptData['params']) : [];
$this->params = isset($scriptData['params']) ? array_map('strval', $scriptData['params']) : [];
$this->optionalParams = isset($scriptData['optionalParams']) ? (array) $scriptData['optionalParams'] : [];
}
}
29 changes: 29 additions & 0 deletions inc/ThirdParties/GoogleTagManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
* Class GoogleChromeLabs\ThirdPartyCapital\ThirdParties\GoogleTagManager
*
* @package GoogleChromeLabs/ThirdPartyCapital
* @copyright 2024 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
*/

namespace GoogleChromeLabs\ThirdPartyCapital\ThirdParties;

use GoogleChromeLabs\ThirdPartyCapital\Util\JsonDir;

/**
* Class representing the Google Tag Manager integration.
*/
class GoogleTagManager extends ThirdPartyBase
{

/**
* Gets the path to the third party data JSON file.
*
* @return string Absolute path to the JSON file.
*/
protected function getJsonFilePath(): string
{
return JsonDir::getFilePath('google-tag-manager.json');
}
}
12 changes: 6 additions & 6 deletions inc/ThirdParties/ThirdPartyBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ abstract class ThirdPartyBase implements ThirdParty
*
* @param array<string, mixed> $args Input arguments to set.
*/
public function __construct(array $args)
final public function __construct(array $args)
{
$this->jsonFilePath = $this->getJsonFilePath();

Expand All @@ -65,7 +65,7 @@ public function __construct(array $args)
*
* @return string Third party identifier.
*/
public function getId(): string
final public function getId(): string
{
$this->lazilyInitialize();

Expand All @@ -77,7 +77,7 @@ public function getId(): string
*
* @param array<string, mixed> $args Input arguments to set.
*/
public function setArgs(array $args): void
final public function setArgs(array $args): void
{
$this->args = $args;

Expand All @@ -92,7 +92,7 @@ public function setArgs(array $args): void
*
* @return string HTML output, or empty string if not applicable.
*/
public function getHtml(): string
final public function getHtml(): string
{
$this->lazilyInitialize();

Expand All @@ -106,7 +106,7 @@ public function getHtml(): string
*
* @return string[] List of stylesheet URLs, or empty array if not applicable.
*/
public function getStylesheets(): array
final public function getStylesheets(): array
{
$this->lazilyInitialize();

Expand All @@ -120,7 +120,7 @@ public function getStylesheets(): array
*
* @return ThirdPartyScriptOutput[] List of script definition objects, or empty array if not applicable.
*/
public function getScripts(): array
final public function getScripts(): array
{
$this->lazilyInitialize();

Expand Down
Loading

0 comments on commit efc3676

Please sign in to comment.