Files
2026-04-28 15:13:50 +02:00

333 lines
9.5 KiB
PHP

<?php
/**
* Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
* use, copy, modify, and distribute this software in source code or binary
* form for use in connection with the web services and APIs provided by
* Facebook.
*
* As with any software that integrates with the Facebook platform, your use
* of this software is subject to the Facebook Developer Principles and
* Policies [http://developers.facebook.com/policy/]. This copyright notice
* shall be included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace FacebookPixelPlugin\FacebookAds\Object\ServerSide;
use InvalidArgumentException;
/**
* Normalizer Class
*
* @category Class
* @package FacebookAds\Object\ServerSide
*/
class Normalizer {
/**
* @param string $field to be normalized.
* @param string $data value to be normalized
* @return string
*/
public static function normalize($field, $data) {
if ($data == null || strlen($data) == 0) {
return null;
}
// Check if already hashed. If yes, don't try to normalize an already hashed data.
if (Util::isHashed($data)) {
return $data;
}
$data = trim(strtolower($data));
$normalized_data = $data;
switch ($field) {
case 'em':
$normalized_data = Normalizer::normalizeEmail($data);
break;
case 'ph':
$normalized_data = Normalizer::normalizePhone($data);
break;
case 'zp':
$normalized_data = Normalizer::normalizeZipCode($data);
break;
case 'ct':
$normalized_data = Normalizer::normalizeCity($data);
break;
case 'st':
$normalized_data = Normalizer::normalizeState($data);
break;
case 'country':
$normalized_data = Normalizer::normalizeCountry($data);
break;
case 'currency':
$normalized_data = Normalizer::normalizeCurrency($data);
break;
case 'f5first':
$normalized_data = Normalizer::normalizeF5($data);
break;
case 'f5last':
$normalized_data = Normalizer::normalizeF5($data);
break;
case 'fi':
$normalized_data = Normalizer::normalizeFi($data);
break;
case 'dobd':
$normalized_data = Normalizer::normalizeDobd($data);
break;
case 'dobm':
$normalized_data = Normalizer::normalizeDobm($data);
break;
case 'doby':
$normalized_data = Normalizer::normalizeDoby($data);
break;
case 'delivery_category':
$normalized_data = Normalizer::normalizeDeliveryCategory($data);
break;
case 'action_source':
$normalized_data = Normalizer::normalizeActionSource($data);
break;
default:
}
return $normalized_data;
}
/**
* @param string $email Email address to be normalized.
* @return string
*/
private static function normalizeEmail($email) {
// Validates email against RFC 822
$result = filter_var($email, FILTER_SANITIZE_EMAIL);
if (!filter_var($result, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email format for the passed email: ' . $email . 'Please check the passed email format.');
}
return $result;
}
/**
* @param string $city city name to be normalized.
* @return string
*/
private static function normalizeCity($city) {
return trim(preg_replace('/[0-9.\s\-()]/', '', $city));
}
/**
* @param string $state state name to be normalized.
* @return string
*/
private static function normalizeState($state) {
return preg_replace('/[^a-z]/', '', $state);
}
/**
* @param string $country country code to be normalized(ISO 3166-2).
* @return string
*/
private static function normalizeCountry($country) {
$result = preg_replace('/[^a-z]/i', '', $country);
if (strlen($result) != 2) {
throw new InvalidArgumentException('Invalid country format passed(' . $country . '). Country Code should be a two-letter ISO Country Code');
}
return $result;
}
/**
* @param string $zip postal code to be normalized.
* @return string
*/
private static function normalizeZipCode($zip) {
// Removing the spaces from the zip code. Eg:
$zip = preg_replace('/[ ]/', '', $zip);
// If the code has more than one part, retain the first part.
$zip = explode('-', $zip)[0];
return $zip;
}
/**
* @param string $phone phone number to be normalized.
* @return string
*/
private static function normalizePhone($phone) {
$result = trim(preg_replace('/[a-z()-]/', '', $phone));
if (Normalizer::isInternationalNumber($result)) {
$result = preg_replace('/[\-\s+]/', '', $result);
}
return $result;
}
/**
* @param string $currency currency code to be normalized(ISO 4217).
* @return string
*/
private static function normalizeCurrency($currency) {
$result = preg_replace('/[^a-z]/i', '', $currency);
if (strlen($result) != 3) {
throw new InvalidArgumentException('Invalid currency format passed(' . $currency . '). Currency Code should be a three-letter ISO Currency Code');
}
return $result;
}
/**
* @param string $name A first or last name to be normalized.
* @return string
*/
private static function normalizeF5($name) {
return substr($name, 0, 5);
}
/**
* @param string $fi A first initial to be normalized.
* @return string
*/
private static function normalizeFi($fi) {
return substr($fi, 0, 1);
}
/**
* @param string $dobd A date of birth day to be normalized.
* @return string
*/
private static function normalizeDobd($dobd) {
if (strlen($dobd) == 1) {
$dobd = '0' . $dobd;
}
if (!preg_match('/^[0-9]{2}$/', $dobd)) {
throw new InvalidArgumentException('Invalid dobd passed(' . $dobd . '). Date of birth day should be in format "DD".');
}
$dobd_int = intval($dobd);
$in_day_range = ($dobd_int >= 1) && ($dobd_int <= 31);
if (!$in_day_range) {
throw new InvalidArgumentException('Invalid dobd passed(' . $dobd . '). Date of birth day should be in format "DD".');
}
return $dobd;
}
/**
* @param string $dobm A date of birth month to be normalized.
* @return string
*/
private static function normalizeDobm($dobm) {
if (strlen($dobm) == 1) {
$dobm = '0' . $dobm;
}
if (!preg_match('/^[0-9]{2}$/', $dobm)) {
throw new InvalidArgumentException('Invalid dobm passed(' . $dobm . '). Date of birth month should be in format "MM".');
}
$dobm_int = intval($dobm);
$in_month_range = ($dobm_int >= 1) && ($dobm_int <= 12);
if (!$in_month_range) {
throw new InvalidArgumentException('Invalid dobm passed(' . $dobm . '). Date of birth month should be in format "MM".');
}
return $dobm;
}
/**
* @param string $doby A date of birth year to be normalized.
* @return string
*/
private static function normalizeDoby($doby) {
if (!preg_match('/^[0-9]{4}$/', $doby)) {
throw new InvalidArgumentException('Invalid doby passed(' . $doby . '). Date of birth year should be in format "YYYY".');
}
return $doby;
}
/**
* Normalizes the type of DeliveryCategory and throws error if invalid.
* @param string $delivery_category type of DeliveryCategory.
* @return string
*/
private static function normalizeDeliveryCategory($delivery_category) {
$delivery_categories = DeliveryCategory::getInstance()->getValues();
if(!DeliveryCategory::getInstance()->isValidValue($delivery_category))
throw new InvalidArgumentException('Invalid delivery_category passed: ' . $delivery_category .
'.Allowed values are one of ' . implode(",",$delivery_categories));
return $delivery_category;
}
/**
* @param string $phone_number Phone number to be normalized.
* @return bool
*/
private static function isInternationalNumber($phone_number) {
// Remove spaces and hyphens
$phone_number = preg_replace('/[\-\s]/', '', $phone_number);
// Strip + and up to 2 leading 0s
$phone_number = preg_replace('/^\+?0{0,2}/', '', $phone_number);
if (substr($phone_number, 0, 1) === '0') {
return false;
}
// International Phone number with country calling code.
$international_number_regex = '/^\d{1,4}\(?\d{2,3}\)?\d{4,}$/';
return preg_match($international_number_regex, $phone_number);
}
/**
* Normalizes the action_source and throws an error if invalid.
* @param string $action_source type of DeliveryCategory.
* @return string
*/
private static function normalizeActionSource($action_source) {
$action_sources = ActionSource::getInstance()->getValues();
if (!ActionSource::getInstance()->isValidValue($action_source)) {
throw new InvalidArgumentException(sprintf(
'Invalid action_source passed: %s. Allowed values are one of %s',
$action_source,
implode(",", $action_sources)
));
}
return $action_source;
}
}