File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/Utility.tar
CaseInsensitiveDictionary.php 0000644 00000004713 15153567143 0012416 0 ustar 00 <?php
/**
* Case-insensitive dictionary, suitable for HTTP headers
*
* @package Requests\Utilities
*/
namespace WpOrg\Requests\Utility;
use ArrayAccess;
use ArrayIterator;
use IteratorAggregate;
use ReturnTypeWillChange;
use WpOrg\Requests\Exception;
/**
* Case-insensitive dictionary, suitable for HTTP headers
*
* @package Requests\Utilities
*/
class CaseInsensitiveDictionary implements ArrayAccess, IteratorAggregate {
/**
* Actual item data
*
* @var array
*/
protected $data = [];
/**
* Creates a case insensitive dictionary.
*
* @param array $data Dictionary/map to convert to case-insensitive
*/
public function __construct(array $data = []) {
foreach ($data as $offset => $value) {
$this->offsetSet($offset, $value);
}
}
/**
* Check if the given item exists
*
* @param string $offset Item key
* @return boolean Does the item exist?
*/
#[ReturnTypeWillChange]
public function offsetExists($offset) {
if (is_string($offset)) {
$offset = strtolower($offset);
}
return isset($this->data[$offset]);
}
/**
* Get the value for the item
*
* @param string $offset Item key
* @return string|null Item value (null if the item key doesn't exist)
*/
#[ReturnTypeWillChange]
public function offsetGet($offset) {
if (is_string($offset)) {
$offset = strtolower($offset);
}
if (!isset($this->data[$offset])) {
return null;
}
return $this->data[$offset];
}
/**
* Set the given item
*
* @param string $offset Item name
* @param string $value Item value
*
* @throws \WpOrg\Requests\Exception On attempting to use dictionary as list (`invalidset`)
*/
#[ReturnTypeWillChange]
public function offsetSet($offset, $value) {
if ($offset === null) {
throw new Exception('Object is a dictionary, not a list', 'invalidset');
}
if (is_string($offset)) {
$offset = strtolower($offset);
}
$this->data[$offset] = $value;
}
/**
* Unset the given header
*
* @param string $offset The key for the item to unset.
*/
#[ReturnTypeWillChange]
public function offsetUnset($offset) {
if (is_string($offset)) {
$offset = strtolower($offset);
}
unset($this->data[$offset]);
}
/**
* Get an iterator for the data
*
* @return \ArrayIterator
*/
#[ReturnTypeWillChange]
public function getIterator() {
return new ArrayIterator($this->data);
}
/**
* Get the headers as an array
*
* @return array Header data
*/
public function getAll() {
return $this->data;
}
}
FilteredIterator.php 0000644 00000004155 15153567143 0010544 0 ustar 00 <?php
/**
* Iterator for arrays requiring filtered values
*
* @package Requests\Utilities
*/
namespace WpOrg\Requests\Utility;
use ArrayIterator;
use ReturnTypeWillChange;
use WpOrg\Requests\Exception\InvalidArgument;
use WpOrg\Requests\Utility\InputValidator;
/**
* Iterator for arrays requiring filtered values
*
* @package Requests\Utilities
*/
final class FilteredIterator extends ArrayIterator {
/**
* Callback to run as a filter
*
* @var callable
*/
private $callback;
/**
* Create a new iterator
*
* @param array $data The array or object to be iterated on.
* @param callable $callback Callback to be called on each value
*
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data argument is not iterable.
*/
public function __construct($data, $callback) {
if (InputValidator::is_iterable($data) === false) {
throw InvalidArgument::create(1, '$data', 'iterable', gettype($data));
}
parent::__construct($data);
if (is_callable($callback)) {
$this->callback = $callback;
}
}
/**
* Prevent unserialization of the object for security reasons.
*
* @phpcs:disable PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound
*
* @param array $data Restored array of data originally serialized.
*
* @return void
*/
#[ReturnTypeWillChange]
public function __unserialize($data) {}
// phpcs:enable
/**
* Perform reinitialization tasks.
*
* Prevents a callback from being injected during unserialization of an object.
*
* @return void
*/
public function __wakeup() {
unset($this->callback);
}
/**
* Get the current item's value after filtering
*
* @return string
*/
#[ReturnTypeWillChange]
public function current() {
$value = parent::current();
if (is_callable($this->callback)) {
$value = call_user_func($this->callback, $value);
}
return $value;
}
/**
* Prevent creating a PHP value from a stored representation of the object for security reasons.
*
* @param string $data The serialized string.
*
* @return void
*/
#[ReturnTypeWillChange]
public function unserialize($data) {}
}
InputValidator.php 0000644 00000004720 15153567143 0010237 0 ustar 00 <?php
/**
* Input validation utilities.
*
* @package Requests\Utilities
*/
namespace WpOrg\Requests\Utility;
use ArrayAccess;
use CurlHandle;
use Traversable;
/**
* Input validation utilities.
*
* @package Requests\Utilities
*/
final class InputValidator {
/**
* Verify that a received input parameter is of type string or is "stringable".
*
* @param mixed $input Input parameter to verify.
*
* @return bool
*/
public static function is_string_or_stringable($input) {
return is_string($input) || self::is_stringable_object($input);
}
/**
* Verify whether a received input parameter is usable as an integer array key.
*
* @param mixed $input Input parameter to verify.
*
* @return bool
*/
public static function is_numeric_array_key($input) {
if (is_int($input)) {
return true;
}
if (!is_string($input)) {
return false;
}
return (bool) preg_match('`^-?[0-9]+$`', $input);
}
/**
* Verify whether a received input parameter is "stringable".
*
* @param mixed $input Input parameter to verify.
*
* @return bool
*/
public static function is_stringable_object($input) {
return is_object($input) && method_exists($input, '__toString');
}
/**
* Verify whether a received input parameter is _accessible as if it were an array_.
*
* @param mixed $input Input parameter to verify.
*
* @return bool
*/
public static function has_array_access($input) {
return is_array($input) || $input instanceof ArrayAccess;
}
/**
* Verify whether a received input parameter is "iterable".
*
* @internal The PHP native `is_iterable()` function was only introduced in PHP 7.1
* and this library still supports PHP 5.6.
*
* @param mixed $input Input parameter to verify.
*
* @return bool
*/
public static function is_iterable($input) {
return is_array($input) || $input instanceof Traversable;
}
/**
* Verify whether a received input parameter is a Curl handle.
*
* The PHP Curl extension worked with resources prior to PHP 8.0 and with
* an instance of the `CurlHandle` class since PHP 8.0.
* {@link https://www.php.net/manual/en/migration80.incompatible.php#migration80.incompatible.resource2object}
*
* @param mixed $input Input parameter to verify.
*
* @return bool
*/
public static function is_curl_handle($input) {
if (is_resource($input)) {
return get_resource_type($input) === 'curl';
}
if (is_object($input)) {
return $input instanceof CurlHandle;
}
return false;
}
}
AddressUtility.php 0000644 00000002462 15154164574 0010246 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\Utility;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Service;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Google\Service\ShoppingContent\AccountAddress;
defined( 'ABSPATH' ) || exit;
/**
* Class AddressUtility
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\Utility
*
* @since 1.4.0
*/
class AddressUtility implements Service {
/**
* Checks whether two account addresses are the same and returns true if they are.
*
* @param AccountAddress $address_1
* @param AccountAddress $address_2
*
* @return bool True if the two addresses are the same, false otherwise.
*/
public function compare_addresses( AccountAddress $address_1, AccountAddress $address_2 ): bool {
$cmp_street_address = $address_1->getStreetAddress() === $address_2->getStreetAddress();
$cmp_locality = $address_1->getLocality() === $address_2->getLocality();
$cmp_region = $address_1->getRegion() === $address_2->getRegion();
$cmp_postal_code = $address_1->getPostalCode() === $address_2->getPostalCode();
$cmp_country = $address_1->getCountry() === $address_2->getCountry();
return $cmp_street_address && $cmp_locality && $cmp_region && $cmp_postal_code && $cmp_country;
}
}
ArrayUtil.php 0000644 00000000703 15154164574 0007205 0 ustar 00 <?php
namespace Automattic\WooCommerce\GoogleListingsAndAds\Utility;
/**
* A class of utilities for dealing with arrays.
*
* @since 2.4.0
*/
class ArrayUtil {
/**
* Remove empty values from array.
*
* @param array $strings A list of strings.
*
* @return array A list of strings without empty strings.
*/
public static function remove_empty_values( array $strings ): array {
return array_values( array_filter( $strings ) );
}
}
DateTimeUtility.php 0000644 00000002027 15154164574 0010352 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\Utility;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Service;
defined( 'ABSPATH' ) || exit;
/**
* Class DateTimeUtility
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\Utility
*
* @since 1.5.0
*/
class DateTimeUtility implements Service {
/**
* Convert a timezone offset to the closest matching timezone string.
*
* @param string $timezone
*
* @return string
*/
public function maybe_convert_tz_string( string $timezone ): string {
if ( preg_match( '/^([+-]\d{1,2}):?(\d{1,2})$/', $timezone, $matches ) ) {
[ $timezone, $hours, $minutes ] = $matches;
$sign = (int) $hours >= 0 ? 1 : - 1;
$seconds = $sign * ( absint( $hours ) * 60 * 60 + absint( $minutes ) * 60 );
$tz_name = timezone_name_from_abbr( '', $seconds, 0 );
$timezone = $tz_name !== false ? $tz_name : date_default_timezone_get();
}
if ( 'UTC' === $timezone ) {
$timezone = 'Etc/GMT';
}
return $timezone;
}
}
DimensionUtility.php 0000644 00000002562 15154164574 0010607 0 ustar 00 <?php
namespace Automattic\WooCommerce\GoogleListingsAndAds\Utility;
/**
* A class for dealing with Dimensions.
*
* @since 2.4.0
*/
class DimensionUtility {
/**
* Width.
*
* @var int
*/
public int $x;
/**
* Height.
*
* @var int
*/
public int $y;
/**
* DimensionUtility constructor.
*
* @param int $x Width.
* @param int $y Height.
*/
public function __construct( int $x, int $y ) {
$this->x = $x;
$this->y = $y;
}
/**
* Checks if the dimension fulfils the minimum size.
*
* @param DimensionUtility $minimum_size The minimum size.
*
* @return bool true if the dimension is bigger or equal than the the minimum size otherwise false.
*/
public function is_minimum_size( DimensionUtility $minimum_size ): bool {
return $this->x >= $minimum_size->x && $this->y >= $minimum_size->y;
}
/**
* Checks if the dimension is equal to the other one with a specific precision.
*
* @param DimensionUtility $target The dimension to be compared.
* @param int|float $precision The precision to use when comparing the two numbers.
*
* @return bool true if the dimension is equal than the other one otherwise false.
*/
public function equals( DimensionUtility $target, $precision = 1 ): bool {
return wp_fuzzy_number_match( $this->x, $target->x, $precision ) && wp_fuzzy_number_match( $this->y, $target->y, $precision );
}
}
ISOUtility.php 0000644 00000003551 15154164574 0007313 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\Utility;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Service;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\ISO3166\Exception\ISO3166Exception;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\ISO3166\ISO3166DataProvider;
defined( 'ABSPATH' ) || exit;
/**
* Class ISOUtility
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\Utility
*
* @since 1.5.0
*/
class ISOUtility implements Service {
/**
* @var ISO3166DataProvider
*/
protected $iso3166_data_provider;
/**
* ISOUtility constructor.
*
* @param ISO3166DataProvider $iso3166_data_provider
*/
public function __construct( ISO3166DataProvider $iso3166_data_provider ) {
$this->iso3166_data_provider = $iso3166_data_provider;
}
/**
* Validate that the provided input is valid ISO 3166-1 alpha-2 country code.
*
* @param string $country_code
*
* @return bool
*
* @see https://wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements ISO 3166-1 alpha-2
* officially assigned codes.
*/
public function is_iso3166_alpha2_country_code( string $country_code ): bool {
try {
$this->iso3166_data_provider->alpha2( $country_code );
return true;
} catch ( ISO3166Exception $exception ) {
return false;
}
}
/**
* Converts WordPress language code to IETF BCP 47 format.
*
* @param string $wp_locale
*
* @return string IETF BCP 47 language code or 'en-US' if the language code cannot be converted.
*
* @see https://tools.ietf.org/html/bcp47 IETF BCP 47 language codes.
*/
public function wp_locale_to_bcp47( string $wp_locale ): string {
if ( empty( $wp_locale ) || ! preg_match( '/^[-_a-zA-Z0-9]{2,}$/', $wp_locale, $matches ) ) {
return 'en-US';
}
return str_replace( '_', '-', $wp_locale );
}
}
ImageUtility.php 0000644 00000004617 15154164574 0007707 0 ustar 00 <?php
namespace Automattic\WooCommerce\GoogleListingsAndAds\Utility;
use Automattic\WooCommerce\GoogleListingsAndAds\Utility\DimensionUtility;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Service;
use Automattic\WooCommerce\GoogleListingsAndAds\Proxies\WP;
/**
* A class of utilities for dealing with images.
*
* @since 2.4.0
*/
class ImageUtility implements Service {
/**
* The WP Proxy.
*
* @var WP
*/
protected WP $wp;
/**
* ImageUtility constructor.
*
* @param WP $wp WP Proxy.
*/
public function __construct( WP $wp ) {
$this->wp = $wp;
}
/**
* Maybe add a new subsize image.
*
* @param int $attachment_id Attachment ID.
* @param string $subsize_key The subsize key that we are trying to generate.
* @param DimensionUtility $size The new size for the subsize key.
* @param bool $crop Whether to crop the image.
*
* @return bool True if the subsize has been added to the attachment metadata otherwise false.
*/
public function maybe_add_subsize_image( int $attachment_id, string $subsize_key, DimensionUtility $size, bool $crop = true ): bool {
add_image_size( $subsize_key, $size->x, $size->y, $crop );
$metadata = $this->wp->wp_update_image_subsizes( $attachment_id );
remove_image_size( $subsize_key );
if ( is_wp_error( $metadata ) ) {
return false;
}
return isset( $metadata['sizes'][ $subsize_key ] );
}
/**
* Try to recommend a size using the real size, the recommended and the minimum.
*
* @param DimensionUtility $size Image size.
* @param DimensionUtility $recommended Recommended image size.
* @param DimensionUtility $minimum Minimum image size.
*
* @return DimensionUtility|bool False if does not fulfil the minimum size otherwise returns the suggested size.
*/
public function recommend_size( DimensionUtility $size, DimensionUtility $recommended, DimensionUtility $minimum ) {
if ( ! $size->is_minimum_size( $minimum ) ) {
return false;
}
$image_ratio = $size->x / $size->y;
$recommended_ratio = $recommended->x / $recommended->y;
if ( $recommended_ratio > $image_ratio ) {
$x = $size->x > $recommended->x ? $recommended->x : $size->x;
$y = (int) floor( $x / $recommended_ratio );
} else {
$y = $size->y > $recommended->y ? $recommended->y : $size->y;
$x = (int) floor( $y * $recommended_ratio );
}
return new DimensionUtility( $x, $y );
}
}
WPCLIMigrationGTIN.php 0000644 00000014312 15154164574 0010504 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\Utility;
use Automattic\WooCommerce\GoogleListingsAndAds\HelperTraits\GTINMigrationUtilities;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Conditional;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Registerable;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Service;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\AttributeManager;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\ProductRepository;
use Exception;
use WP_CLI;
defined( 'ABSPATH' ) || exit;
/**
* Class WPCLIMigrationGTIN
* Creates a set of utility commands in WP CLI for GTIN Migration
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\Utility
*
* @since 2.9.0
*/
class WPCLIMigrationGTIN implements Service, Registerable, Conditional {
use GTINMigrationUtilities;
/** @var AttributeManager */
public AttributeManager $attribute_manager;
/** @var ProductRepository */
public ProductRepository $product_repository;
/**
* Constructor
*
* @param ProductRepository $product_repository
* @param AttributeManager $attribute_manager
*/
public function __construct( ProductRepository $product_repository, AttributeManager $attribute_manager ) {
$this->product_repository = $product_repository;
$this->attribute_manager = $attribute_manager;
}
/**
* Register service and initialize hooks.
*/
public function register(): void {
WP_CLI::add_hook( 'after_wp_load', [ $this, 'register_commands' ] );
}
/**
* Register the commands
*/
public function register_commands(): void {
WP_CLI::add_command( 'wc g4wc gtin-migration start', [ $this, 'gtin_migration_start' ] );
}
/**
* Starts the GTIN migration in batches
*/
public function gtin_migration_start(): void {
$batch_size = $this->get_batch_size();
$num_products = $this->get_total_products_count();
WP_CLI::log( sprintf( 'Starting GTIN migration for %s products in the store.', $num_products ) );
$progress = WP_CLI\Utils\make_progress_bar( 'GTIN Migration', $num_products / $batch_size );
$processed = 0;
$batch_number = 1;
$start_time = microtime( true );
// First batch
$items = $this->get_items( $batch_number );
$processed += $this->process_items( $items );
$progress->tick();
// Next batches
while ( ! empty( $items ) ) {
++$batch_number;
$items = $this->get_items( $batch_number );
$processed += $this->process_items( $items );
$progress->tick();
}
$progress->finish();
$total_time = microtime( true ) - $start_time;
// Issue a warning if nothing is migrated.
if ( ! $processed ) {
WP_CLI::warning( __( 'No GTIN were migrated.', 'google-listings-and-ads' ) );
return;
}
WP_CLI::success(
sprintf(
/* Translators: %1$d is the number of migrated GTINS and %2$d is the execution time in seconds. */
_n(
'%1$d GTIN was migrated in %2$d seconds.',
'%1$d GTIN were migrated in %2$d seconds.',
$processed,
'google-listings-and-ads'
),
$processed,
$total_time
)
);
}
/**
* Get total of products in the store to be migrated.
*
* @return int The total number of products.
*/
private function get_total_products_count(): int {
$args = [
'status' => 'publish',
'return' => 'ids',
'type' => [ 'simple', 'variation' ],
];
return count( $this->product_repository->find_ids( $args ) );
}
/**
* Get the items for the current batch
*
* @param int $batch_number
* @return int[] Array of WooCommerce product IDs
*/
private function get_items( int $batch_number ): array {
return $this->product_repository->find_all_product_ids( $this->get_batch_size(), $this->get_query_offset( $batch_number ) );
}
/**
* Get the query offset based on a given batch number and the specified batch size.
*
* @param int $batch_number
*
* @return int
*/
protected function get_query_offset( int $batch_number ): int {
return $this->get_batch_size() * ( $batch_number - 1 );
}
/**
* Get the batch size. By default, 100.
*
* @return int The batch size.
*/
private function get_batch_size(): int {
return apply_filters( 'woocommerce_gla_batched_cli_size', 100 );
}
/**
* Process batch items.
*
* @param int[] $items A single batch of WooCommerce product IDs from the get_batch() method.
* @return int The number of items processed.
*/
protected function process_items( array $items ): int {
// update the product core GTIN using G4W GTIN
$products = $this->product_repository->find_by_ids( $items );
$processed = 0;
foreach ( $products as $product ) {
// process variations
if ( $product instanceof \WC_Product_Variable ) {
$variations = $product->get_children();
$processed += $this->process_items( $variations );
continue;
}
// void if core GTIN is already set.
if ( $product->get_global_unique_id() ) {
$this->debug( $this->error_gtin_already_set( $product ) );
continue;
}
$gtin = $this->get_gtin( $product );
if ( ! $gtin ) {
$this->debug( $this->error_gtin_not_found( $product ) );
continue;
}
$gtin = $this->prepare_gtin( $gtin );
if ( ! is_numeric( $gtin ) ) {
$this->debug( $this->error_gtin_invalid( $product, $gtin ) );
continue;
}
try {
$product->set_global_unique_id( $gtin );
$product->save();
++$processed;
$this->debug( $this->successful_migrated_gtin( $product, $gtin ) );
} catch ( Exception $e ) {
$this->error( $this->error_gtin_not_saved( $product, $gtin, $e ) );
}
}
return $processed;
}
/**
* Check if this Service is needed.
*
* @see https://make.wordpress.org/cli/handbook/guides/commands-cookbook/#include-in-a-plugin-or-theme
* @return bool
*/
public static function is_needed(): bool {
return defined( 'WP_CLI' ) && WP_CLI;
}
/**
* Add some info in the debug console.
* Add --debug to see these logs in WP CLI
*
* @param string $message
* @return void
*/
protected function debug( string $message ): void {
WP_CLI::debug( $message );
}
/**
* Add some info in the error console.
*
* @param string $message
* @return void
*/
protected function error( string $message ): void {
WP_CLI::error( $message, false );
}
}