Skip to content

Commit fceddb4

Browse files
hongj-srcmeta-codesync[bot]
authored andcommitted
Move getAppendix function to a separate file
Summary: The appendix will be used in multiple util files. Move it out to a separate file. Differential Revision: D84625990 Privacy Context Container: L1399313 fbshipit-source-id: c37a80e6c72758d8b91719330bc5e8c836a0be25
1 parent 55aa63b commit fceddb4

4 files changed

Lines changed: 174 additions & 123 deletions

File tree

php/capi-param-builder/src/ParamBuilder.php

Lines changed: 4 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
require_once 'model/FbcParamConfig.php';
1313
require_once 'model/CookieSettings.php';
1414
require_once 'piiUtil/PIIUtils.php';
15-
require_once 'util/VersionProvider.php';
15+
require_once 'util/AppendixProvider.php';
1616

1717
final class ParamBuilder
1818
{
@@ -21,7 +21,6 @@ final class ParamBuilder
2121
private $domain_list;
2222

2323
// appendix info
24-
private $sdk_version;
2524
private $appendix_new;
2625
private $appendix_normal;
2726

@@ -45,9 +44,9 @@ public function __construct(
4544
$this->fbc_param_configs = array(
4645
new FbcParamConfig(FBCLID, '', CLICK_ID_STRING)
4746
);
48-
$sdk_version = VersionProvider::getVersion();
49-
$this->appendix_new = $this->getAppendix(true, $sdk_version);
50-
$this->appendix_normal = $this->getAppendix(false, $sdk_version);
47+
48+
$this->appendix_new = AppendixProvider::getAppendix(true);
49+
$this->appendix_normal = AppendixProvider::getAppendix(false);
5150

5251
if ($params instanceof ETLDPlus1Resolver) {
5352
$this->etld_plus1_resolver = $params;
@@ -78,52 +77,6 @@ private function validateAppendix($appendix_value) {
7877
return false;
7978
}
8079

81-
private function getAppendix($is_new, $sdk_version) {
82-
try {
83-
// Invalid version format
84-
if (!preg_match('/^\d+(\.\d+){2}$/', $sdk_version)) {
85-
return LANGUAGE_TOKEN;
86-
}
87-
88-
$version_parts = explode('.', $sdk_version);
89-
$major = intval($version_parts[0]);
90-
$minor = intval($version_parts[1]);
91-
$patch = intval($version_parts[2]);
92-
93-
// Create byte indicating if it's new (0x01) or not (0x00)
94-
$is_new_byte = $is_new ? 0x01 : 0x00;
95-
96-
// Create byte array:
97-
// [DEFAULT_FORMAT, LANGUAGE_TOKEN_INDEX, is_new_byte, major, minor,
98-
// patch]
99-
$bytes = pack('C*',
100-
DEFAULT_FORMAT,
101-
LANGUAGE_TOKEN_INDEX,
102-
$is_new_byte,
103-
$major,
104-
$minor,
105-
$patch
106-
);
107-
// Convert to base64 and make it URL-safe
108-
$base64 = base64_encode($bytes);
109-
$base64url_safe = str_replace(
110-
['+', '/', '='],
111-
['-', '_', ''],
112-
$base64
113-
);
114-
115-
return $base64url_safe;
116-
} catch (Exception $e) {
117-
// Fallback to legacy language token if version parsing fails
118-
ini_set('log_errors', 1);
119-
error_log(
120-
"Warning: Failed to generate appendix, using fallback: ".
121-
$e->getMessage()
122-
);
123-
return LANGUAGE_TOKEN;
124-
}
125-
}
126-
12780
// pre-process cookie if it exists
12881
private function preProcess($cookie, $cookie_name, $host)
12982
{
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/*
3+
* Copyright (c) Meta Platforms, Inc. and affiliates.
4+
*
5+
* This source code is licensed under the license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
namespace FacebookAds;
10+
require_once __DIR__ . '/VersionProvider.php';
11+
require_once __DIR__ . '/../model/Constants.php';
12+
13+
class AppendixProvider {
14+
public static function getAppendix($is_new) {
15+
try {
16+
$sdk_version = VersionProvider::getVersion();
17+
18+
// Invalid version format
19+
if (!preg_match('/^\d+(\.\d+){2}$/', $sdk_version)) {
20+
return LANGUAGE_TOKEN;
21+
}
22+
23+
$version_parts = explode('.', $sdk_version);
24+
$major = intval($version_parts[0]);
25+
$minor = intval($version_parts[1]);
26+
$patch = intval($version_parts[2]);
27+
28+
// Create byte indicating if it's new (0x01) or not (0x00)
29+
$is_new_byte = $is_new ? 0x01 : 0x00;
30+
31+
// Create byte array:
32+
// [DEFAULT_FORMAT, LANGUAGE_TOKEN_INDEX, is_new_byte, major, minor,
33+
// patch]
34+
$bytes = pack('C*',
35+
DEFAULT_FORMAT,
36+
LANGUAGE_TOKEN_INDEX,
37+
$is_new_byte,
38+
$major,
39+
$minor,
40+
$patch
41+
);
42+
// Convert to base64 and make it URL-safe
43+
$base64 = base64_encode($bytes);
44+
$base64url_safe = str_replace(
45+
['+', '/', '='],
46+
['-', '_', ''],
47+
$base64
48+
);
49+
50+
return $base64url_safe;
51+
} catch (Exception $e) {
52+
// Fallback to legacy language token if version parsing fails
53+
ini_set('log_errors', 1);
54+
error_log(
55+
"Warning: Failed to generate appendix, using fallback: ".
56+
$e->getMessage()
57+
);
58+
return LANGUAGE_TOKEN;
59+
}
60+
}
61+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
/*
3+
* Copyright (c) Meta Platforms, Inc. and affiliates.
4+
*
5+
* This source code is licensed under the license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
use PHPUnit\Framework\TestCase;
10+
use FacebookAds\AppendixProvider;
11+
12+
require_once __DIR__ . '/../src/util/AppendixProvider.php';
13+
14+
final class AppendixProviderTest extends TestCase
15+
{
16+
private $original_composer_content = null;
17+
private $composer_json_path;
18+
19+
protected function setUp(): void
20+
{
21+
// Store the path to composer.json for mocking
22+
$this->composer_json_path = __DIR__ . '/../composer.json';
23+
24+
// Backup original composer.json content if it exists
25+
if (file_exists($this->composer_json_path)) {
26+
$this->original_composer_content = file_get_contents($this->composer_json_path);
27+
}
28+
}
29+
30+
protected function tearDown(): void
31+
{
32+
// Restore original composer.json content
33+
if ($this->original_composer_content !== null) {
34+
file_put_contents($this->composer_json_path, $this->original_composer_content);
35+
} elseif (file_exists($this->composer_json_path)) {
36+
unlink($this->composer_json_path);
37+
}
38+
}
39+
40+
private function mockSdkVersion($version)
41+
{
42+
$composer_data = [
43+
'name' => 'facebook/capi-param-builder',
44+
'version' => $version,
45+
'description' => 'Test version'
46+
];
47+
48+
file_put_contents($this->composer_json_path, json_encode($composer_data, JSON_PRETTY_PRINT));
49+
}
50+
51+
/**
52+
* Helper method to remove composer.json to simulate version not found
53+
*/
54+
private function removeComposerJson()
55+
{
56+
if (file_exists($this->composer_json_path)) {
57+
unlink($this->composer_json_path);
58+
}
59+
}
60+
61+
public function testGetAppendixWithValidAppendix()
62+
{
63+
$this->mockSdkVersion('1.0.1');
64+
$this->assertEquals(AppendixProvider::getAppendix(true), "AQEBAQAB");
65+
$this->assertEquals(AppendixProvider::getAppendix(false), "AQEAAQAB");
66+
67+
$this->mockSdkVersion('1.15.24');
68+
$this->assertEquals(AppendixProvider::getAppendix(true), "AQEBAQ8Y");
69+
$this->assertEquals(AppendixProvider::getAppendix(false), "AQEAAQ8Y");
70+
}
71+
72+
public function testGetAppendixWithInValidAppendix()
73+
{
74+
$this->mockSdkVersion('test123');
75+
$this->assertEquals(AppendixProvider::getAppendix(true), "AQ");
76+
$this->assertEquals(AppendixProvider::getAppendix(false), "AQ");
77+
78+
$this->mockSdkVersion('!@#.%%.^%');
79+
$this->assertEquals(AppendixProvider::getAppendix(true), "AQ");
80+
$this->assertEquals(AppendixProvider::getAppendix(false), "AQ");
81+
}
82+
}

0 commit comments

Comments
 (0)