SILENT KILLERPanel

Current Path: > home > codekrsu > > ameliagraphics.com > wp-content > plugins > pinterest-for-woocommerce > src > >


Operation   : Linux premium131.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64
Software     : Apache
Server IP    : 162.0.232.56 | Your IP: 216.73.216.111
Domains      : 1034 Domain(s)
Permission   : [ 0755 ]

Files and Folders in: /home/codekrsu//ameliagraphics.com/wp-content/plugins/pinterest-for-woocommerce/src//

NameTypeSizeLast ModifiedActions
API Directory - -
Admin Directory - -
Exception Directory - -
MultichannelMarketing Directory - -
Notes Directory - -
Product Directory - -
Tracking Directory - -
Utilities Directory - -
View Directory - -
AdCredits.php File 8406 bytes August 26 2024 16:35:44.
AdCreditsCoupons.php File 1461 bytes August 26 2024 16:35:44.
AdsCreditCurrency.php File 1946 bytes May 20 2025 15:25:46.
Billing.php File 4901 bytes August 26 2024 16:35:44.
CommerceIntegration.php File 7185 bytes December 04 2024 18:47:06.
Compat.php File 952 bytes November 16 2021 18:14:38.
Crypto.php File 3718 bytes June 23 2025 21:16:30.
FeedFileOperations.php File 4680 bytes August 26 2024 16:35:44.
FeedGenerator.php File 22733 bytes August 26 2024 16:35:44.
FeedRegistration.php File 7230 bytes December 04 2024 18:47:06.
FeedStatusService.php File 20815 bytes March 18 2025 17:31:36.
Feeds.php File 13838 bytes December 04 2024 18:47:06.
Heartbeat.php File 1882 bytes October 23 2024 17:23:10.
LocalFeedConfigs.php File 3327 bytes September 24 2024 11:32:30.
LocaleMapper.php File 3167 bytes March 18 2025 17:31:36.
Logger.php File 3132 bytes August 26 2024 16:35:44.
Merchants.php File 6575 bytes September 24 2024 11:32:30.
PinterestApiException.php File 2767 bytes December 04 2024 18:47:06.
PinterestShippingZone.php File 7161 bytes February 16 2022 03:57:48.
PinterestSyncSettings.php File 3016 bytes August 26 2024 16:35:44.
PluginActivate.php File 785 bytes June 18 2022 00:23:22.
PluginHelper.php File 2537 bytes October 11 2022 17:51:18.
PluginUpdate.php File 11166 bytes May 29 2025 17:27:42.
ProductFeedStatus.php File 4453 bytes August 26 2024 16:35:44.
ProductSync.php File 6351 bytes September 24 2024 11:32:30.
ProductsXmlFeed.php File 17527 bytes February 11 2025 16:39:50.
RefreshToken.php File 3769 bytes August 26 2024 16:35:44.
RichPins.php File 9177 bytes August 26 2024 16:35:44.
SaveToPinterest.php File 3525 bytes April 26 2023 13:47:12.
Shipping.php File 8372 bytes February 16 2022 03:57:48.
TrackerSnapshot.php File 2574 bytes August 26 2024 16:35:44.
Tracking.php File 7488 bytes August 29 2024 22:54:16.
WPConsentAPI.php File 1178 bytes June 16 2025 21:44:24.
error_log File 260 bytes June 23 2025 21:16:32.

Reading File: /home/codekrsu//ameliagraphics.com/wp-content/plugins/pinterest-for-woocommerce/src///Feeds.php

<?php
/**
 * Pinterest for WooCommerce Feeds related helper methods
 *
 * @package     Pinterest_For_WooCommerce/Classes/
 * @version     1.0.0
 */

namespace Automattic\WooCommerce\Pinterest;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Automattic\WooCommerce\Pinterest\API\APIV5;
use Automattic\WooCommerce\Pinterest\Exception\FeedNotFoundException;
use Automattic\WooCommerce\Pinterest\Exception\PinterestApiLocaleException;
use Automattic\WooCommerce\Pinterest\Notes\FeedDeletionFailure;
use Exception;
use Pinterest_For_Woocommerce;
use Throwable;

/**
 * Class handling fetch methods for feed profiles.
 */
class Feeds {

	/**
	 * Feed ACTIVE status which mirrors the Pinterest API feed status.
	 */
	const FEED_STATUS_ACTIVE = 'ACTIVE';

	/**
	 * Feed INACTIVE status which mirrors the Pinterest API feed status.
	 */
	const FEED_STATUS_INACTIVE = 'INACTIVE';

	/**
	 * Feed DELETED status which mirrors the Pinterest API feed status.
	 */
	const FEED_STATUS_DELETED = 'DELETED';

	/**
	 * Feed DOES_NOT_EXIST status which is a custom status.
	 * Represents a feed that was never created.
	 * In case fetching the feed returns no results.
	 */
	const FEED_STATUS_DOES_NOT_EXIST = 'DOES_NOT_EXIST';

	/**
	 * Feed COMPLETED status which mirrors the Pinterest API feed processing result status.
	 */
	const FEED_PROCESSING_STATUS_COMPLETED = 'COMPLETED';

	/**
	 * Feed COMPLETED_EARLY status which mirrors the Pinterest API feed processing result status.
	 */
	const FEED_PROCESSING_STATUS_COMPLETED_EARLY = 'COMPLETED_EARLY';

	/**
	 * Feed DISAPPROVED status which mirrors the Pinterest API feed processing result status.
	 */
	const FEED_PROCESSING_STATUS_DISAPPROVED = 'DISAPPROVED';

	/**
	 * Feed STATUS_FAILED status which mirrors the Pinterest API feed processing result status.
	 */
	const FEED_PROCESSING_STATUS_FAILED = 'FAILED';

	/**
	 * Feed PROCESSING status which mirrors the Pinterest API feed processing result status.
	 */
	const FEED_PROCESSING_STATUS_PROCESSING = 'PROCESSING';

	/**
	 * Feed QUEUED_FOR_PROCESSING status which mirrors the Pinterest API feed processing result status.
	 */
	const FEED_PROCESSING_STATUS_QUEUED_FOR_PROCESSING = 'QUEUED_FOR_PROCESSING';

	/**
	 * Feed UNDER_APPEAL status which mirrors the Pinterest API feed processing result status.
	 */
	const FEED_PROCESSING_STATUS_UNDER_APPEAL = 'UNDER_APPEAL';

	/**
	 * Feed UNDER_REVIEW status which mirrors the Pinterest API feed processing result status.
	 */
	const FEED_PROCESSING_STATUS_UNDER_REVIEW = 'UNDER_REVIEW';

	/**
	 * Create a new feed for the given ad account.
	 *
	 * @since 1.4.0
	 *
	 * @return string The Feed ID or an empty string if failed.
	 * @throws PinterestApiException Pinterest API Exception if there is an error creating the feed.
	 */
	public static function create_feed(): string {
		$ad_account_id = Pinterest_For_WooCommerce()::get_setting( 'tracking_advertiser' );
		$configs       = LocalFeedConfigs::get_instance()->get_configurations();
		$config        = reset( $configs );

		$name             = (string) parse_url( esc_url( get_site_url() ), PHP_URL_HOST );
		$default_country  = Pinterest_For_Woocommerce()::get_base_country();
		$default_currency = get_woocommerce_currency();
		try {
			$default_locale = LocaleMapper::get_locale_for_api();
		} catch ( PinterestApiLocaleException $e ) {
			$default_locale = LocaleMapper::PINTEREST_DEFAULT_LOCALE;
		}

		/**
		 * Filters the default feed name: pinterest_for_woocommerce_unique_feed_name.
		 * This vale appears in the Catalogues - Data sources page at Pinterest.
		 *
		 * @since 1.4.0
		 *
		 * @param string $feed_name The default feed name.
		 */
		$feed_name = apply_filters(
			'pinterest_for_woocommerce_unique_feed_name',
			sprintf(
				// translators: %1$s is a country ISO 2 code, %2$s is a currency ISO 3 code.
				esc_html__( 'Created by Pinterest for WooCommerce at %1$s %2$s|%3$s|%4$s', 'pinterest-for-woocommerce' ),
				esc_html( $name ),
				esc_html( $default_country ),
				esc_html( $default_locale ),
				esc_html( $default_currency )
			)
		);

		$data = array(
			'name'                 => $feed_name,
			'format'               => 'XML',
			'location'             => $config['feed_url'],
			'catalog_type'         => 'RETAIL',
			'default_currency'     => $default_currency,
			'default_locale'       => $default_locale,
			'default_country'      => $default_country,
			'default_availability' => 'IN_STOCK',
		);

		$cache_key    = PINTEREST_FOR_WOOCOMMERCE_PREFIX . '_request_' . md5( wp_json_encode( $data ) . (string) $ad_account_id );
		$cached_error = get_transient( $cache_key );

		if ( false !== $cached_error ) {
			// Faking Pinterest API response to 425 Too early.
			throw new PinterestApiException(
				sprintf(
					/* translators: Pinterest API error code and message. 1: Cached error string. */
					esc_html__(
						'Previous request for the same action failed due to: %1$s. Delaying the next call to prevent repeating errors.',
						'pinterest-for-woocommerce'
					),
					esc_html( $cached_error )
				),
				425
			);
		}

		// Add preferred_processing_schedule to the data after generating cache key because time() is used.
		$data['preferred_processing_schedule'] = array(
			'time'     => gmdate( 'H:i', time() + 5 * MINUTE_IN_SECONDS ),
			'timezone' => 'Etc/UTC',
		);

		try {
			$feed = APIV5::create_feed( $data, $ad_account_id );
		} catch ( PinterestApiException $e ) {
			$delay   = Pinterest_For_Woocommerce()::get_data( 'create_feed_delay' ) ?? MINUTE_IN_SECONDS;
			$message = sprintf( '%1$s - %2$s', esc_html( $e->get_pinterest_code() ), esc_html( $e->getMessage() ) );
			set_transient( $cache_key, $message, $delay );
			// Double the delay.
			Pinterest_For_Woocommerce()::save_data(
				'create_feed_delay',
				min( $delay * 2, 6 * HOUR_IN_SECONDS )
			);
			throw $e;
		}

		static::invalidate_feeds_cache();

		$feed_id = static::match_local_feed_configuration_to_registered_feeds( array( $feed ) );

		// Clean the cached delay.
		Pinterest_For_Woocommerce()::save_data( 'create_feed_delay', false );

		return $feed_id;
	}

	/**
	 * Update a feed for the given ad account.
	 *
	 * @since 1.4.0
	 *
	 * @param string $feed_id The ID of the feed.
	 * @param array  $data    The data to update the feed with.
	 *
	 * @return array
	 * @throws Throwable PHP Exception if there is an error updating the feed.
	 */
	public static function update_feed( string $feed_id, array $data ) {
		$ad_account_id = Pinterest_For_WooCommerce()::get_setting( 'tracking_advertiser' );
		$data          = array_merge(
			$data,
			array(
				'status'                        => 'ACTIVE',
				'preferred_processing_schedule' => array(
					'time'     => gmdate( 'H:i', time() + 5 * MINUTE_IN_SECONDS ),
					'timezone' => 'Etc/UTC',
				),
				'catalog_type'                  => 'RETAIL',
			)
		);

		try {
			return APIV5::update_feed( $feed_id, $data, $ad_account_id );
		} catch ( Throwable $th ) {
			Logger::log( $th->getMessage(), 'error' );
			throw $th;
		}
	}

	/**
	 * Get a specific merchant feed using the given arguments.
	 *
	 * @param string $feed_id     The ID of the feed.
	 *
	 * @return array The feed profile object.
	 *
	 * @throws PinterestApiException Pinterest API Exception.
	 */
	public static function get_feed( $feed_id ) {
		try {
			$ad_account_id = Pinterest_For_WooCommerce()::get_setting( 'tracking_advertiser' );
			$feeds         = APIV5::get_feeds( $ad_account_id );
			foreach ( $feeds['items'] as $feed ) {
				// Get the feed with the requested id if exists.
				if ( $feed_id === $feed['id'] ) {
					return $feed;
				}
			}
			// No feed found.
			return array();
		} catch ( PinterestApiException $e ) {
			Logger::log( $e->getMessage(), 'error' );
			throw $e;
		}
	}

	/**
	 * Get merchant's feeds.
	 *
	 * @return array The feed profile objects.
	 */
	public static function get_feeds(): array {
		try {
			$ad_account_id = Pinterest_For_WooCommerce()::get_setting( 'tracking_advertiser' );
			$feeds         = APIV5::get_feeds( $ad_account_id );
			return $feeds['items'] ?? array();
		} catch ( PinterestApiException $e ) {
			Logger::log( $e->getMessage(), 'error' );
			return array();
		}
	}

	/**
	 * Invalidate the merchant feeds cache.
	 *
	 * @since 1.4.0
	 *
	 * @return bool True if the cache was invalidated, false otherwise.
	 */
	public static function invalidate_feeds_cache() {
		$ad_account_id = Pinterest_For_WooCommerce()::get_setting( 'tracking_advertiser' );
		return APIV5::invalidate_feeds_cache( $ad_account_id );
	}

	/**
	 * Verify if the local feed is already registered to the merchant.
	 * Return its ID if it is.
	 *
	 * @param array $feeds The list of feeds to check against. If not set, the list will be fetched from the API.
	 * @return string Returns the ID of the feed if properly registered or an empty string otherwise.
	 */
	public static function match_local_feed_configuration_to_registered_feeds( array $feeds = array() ): string {
		if ( empty( $feeds ) ) {
			$feeds = static::get_feeds();
		}

		$configs = LocalFeedConfigs::get_instance()->get_configurations();
		$config  = reset( $configs );

		foreach ( $feeds as $feed ) {
			/**
			 * Match feeds created by Pinterest for WooCommerce extension in both API v3 and v5 versions.
			 *
			 * V3 API created feeds have no name, it is set to null instead.
			 * V5 API created feeds have a name that starts with 'Created by Pinterest for WooCommerce'.
			 *
			 * When trying to match remote feed to a local configuration, we need to check both cases
			 * not to create a new feed if the feed was created by the extension in the past.
			 */
			$does_match = self::does_feed_match( $feed ) && ( $feed['location'] ?? '' ) === $config['feed_url'];
			if ( $does_match ) {
				return $feed['id'];
			}
		}

		return '';
	}

	/**
	 * Tests if the feed is a match.
	 *
	 * @param array $feed A feed information array from Pinterest API response.
	 *
	 * @since 1.4.10
	 * @return bool
	 */
	private static function does_feed_match( array $feed ): bool {
		$local_country = Pinterest_For_Woocommerce::get_base_country();
		try {
			$local_locale = LocaleMapper::get_locale_for_api();
		} catch ( PinterestApiLocaleException $e ) {
			$local_locale = LocaleMapper::PINTEREST_DEFAULT_LOCALE;
		}

		$does_match = ( $feed['default_country'] ?? '' ) === $local_country;
		if ( ! $does_match ) {
			return false;
		}

		$does_match = ( $feed['default_locale'] ?? '' ) === $local_locale;
		if ( ! $does_match ) {
			return false;
		}

		return 0 === strpos( $feed['location'] ?? '', get_site_url() );
	}

	/**
	 * Compare remote feeds to local configuration to find a matching feed.
	 *
	 * @since 1.4.10
	 * @return string - Remote feed ID that matches.
	 * @throws FeedNotFoundException When there is no matching feed at Pinterest.
	 */
	public static function maybe_remote_feed(): string {
		$feeds = self::get_feeds();
		foreach ( $feeds as $feed ) {
			if ( self::does_feed_match( $feed ) ) {
				$last_dash_position = strrpos( $feed['location'], '-' ) + 1;
				$last_dot_position  = strrpos( $feed['location'], '.' );
				$length_of_the_id   = $last_dot_position - $last_dash_position;
				return substr( $feed['location'], $last_dash_position, $length_of_the_id );
			}
		}
		throw new FeedNotFoundException();
	}

	/**
	 * Check if the registered feed is enabled.
	 *
	 * @param string $feed_id The ID of the feed.
	 * @return bool True if the feed is active, false otherwise.
	 *
	 * @throws PinterestApiException Pinterest API Exception.
	 * @since 1.2.13
	 * @deprecated
	 */
	public static function is_local_feed_enabled( string $feed_id ): bool {
		if ( empty( $feed_id ) ) {
			return false;
		}

		$feed = static::get_feed( $feed_id );
		return 'ACTIVE' === ( $feed['status'] ?? '' );
	}

	/**
	 * Delete the feed.
	 *
	 * @since 1.4.0
	 *
	 * @param string $feed_id The ID of the feed.
	 *
	 * @return bool
	 */
	public static function delete_feed( string $feed_id ) {
		try {
			$ad_account_id = Pinterest_For_WooCommerce()::get_setting( 'tracking_advertiser' );
			APIV5::delete_feed( $feed_id, $ad_account_id );
			return true;
		} catch ( PinterestApiException $e ) {
			Logger::log( $e->getMessage(), 'error' );
			if ( in_array(
				(int) $e->get_pinterest_code(),
				array(
					PinterestApiException::MERCHANT_DISAPPROVED,
					PinterestApiException::MERCHANT_UNDER_REVIEW,
					PinterestApiException::CATALOGS_FEED_HAS_ACTIVE_PROMOTIONS,
				)
			) ) {
				// Show Admin Notice.
				FeedDeletionFailure::possibly_add_note( $e->get_pinterest_code() );
			}
			return false;
		}
	}

	/**
	 * Get the latest report of the active feed related to the last attempt to process and ingest our feed.
	 *
	 * @since 1.4.0
	 *
	 * @param string $feed_id Pinterest feed ID.
	 *
	 * @return array The feed ingestion and processing report or empty array.
	 */
	public static function get_feed_recent_processing_results( $feed_id ): array {
		try {
			$ad_account_id = Pinterest_For_WooCommerce()::get_setting( 'tracking_advertiser' );
			$feed_report   = APIV5::get_feed_processing_results( $feed_id, $ad_account_id );
		} catch ( PinterestApiException $e ) {
			return array();
		}

		return $feed_report['items'][0] ?? array();
	}

	/**
	 * Get the feed report items issues.
	 *
	 * @since 1.4.0
	 *
	 * @param string $feed_processing_result_id The feed processing result ID.
	 * @param int    $per_page                  The number of items to return per page. Default 25.
	 *
	 * @return array
	 */
	public static function get_feed_processing_result_items_issues( $feed_processing_result_id, $per_page = 25 ): array {
		try {
			$feed_report = APIV5::get_feed_processing_result_items_issues( $feed_processing_result_id, $per_page );
		} catch ( PinterestApiException $e ) {
			return array();
		}

		return $feed_report['items'] ?? array();
	}
}

SILENT KILLER Tool