HEX
Server: nginx
System: Linux pool195-106-36.bur.atomicsites.net 6.12.57+deb12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.57-1~bpo12+1 (2025-11-17) x86_64
User: (0)
PHP: 8.3.32
Disabled: pcntl_fork
Upload Files
File: /wordpress/plugins/wp-cloud-client/1.1.7/src/BusinessProfile/LegacyShortcodeCompat.php
<?php

declare(strict_types=1);

namespace VPlugins\WPCloudClient\BusinessProfile;

/**
 * Backward-compatible shortcodes from business-profile-render v1.2.0–v1.4.0.
 *
 * Registers legacy shortcodes with both 'business-profile-data-*' and
 * 'business-profile-render-*' prefixes, delegating all rendering to FieldRenderer.
 */
final class LegacyShortcodeCompat {

	private const PREFIXES = [ 'business-profile-data', 'business-profile-render' ];

	/**
	 * Simple shortcodes that map directly to a profile attribute.
	 */
	private const SIMPLE_MAP = [
		'company-name'              => 'company_name',
		'address'                   => 'address',
		'city'                      => 'city',
		'state'                     => 'state',
		'zip-code'                  => 'zip',
		'country'                   => 'country',
		'work-number'               => 'work_number',
		'toll-free-number'          => 'toll_free_number',
		'company-description'       => 'description',
		'company-short-description' => 'short_description',
		'booking-url'               => 'booking_url',
	];

	/**
	 * Social icon shortcodes that map to a social URL attribute.
	 */
	private const SOCIAL_ICON_MAP = [
		'image-link-facebook-url'   => 'facebook_url',
		'image-link-twitter-url'    => 'twitter_url',
		'image-link-instagram-url'  => 'instagram_url',
		'image-link-linkedin-url'   => 'linkedin_url',
		'image-link-pinterest-url'  => 'pinterest_url',
		'image-link-foursquare-url' => 'foursquare_url',
		'image-link-youtube-url'    => 'youtube_url',
		'image-link-rss-url'        => 'rss_url',
	];

	/**
	 * Special shortcodes that need dedicated rendering methods.
	 */
	private const SPECIAL_MAP = [
		'full-address'       => 'renderFullAddressList',
		'services'           => 'renderServices',
		'hours-of-operation' => 'renderHoursOfOperation',
		'logo'               => 'renderLogo',
		'primary'            => 'renderPrimary',
	];

	/**
	 * Constructor.
	 *
	 * @param ProfileRepository $repository The profile data repository.
	 * @param FieldRenderer     $renderer   The field renderer.
	 */
	public function __construct(
		private readonly ProfileRepository $repository,
		private readonly FieldRenderer $renderer,
	) {}

	/**
	 * Register all legacy shortcodes.
	 *
	 * @return void
	 */
	public function register(): void {
		foreach ( self::PREFIXES as $prefix ) {
			$this->registerSimpleShortcodes( $prefix );
			$this->registerSpecialShortcodes( $prefix );
			$this->registerSocialIconShortcodes( $prefix );
		}
	}

	/**
	 * Register simple field shortcodes for a given prefix.
	 *
	 * @param string $prefix The shortcode prefix.
	 */
	private function registerSimpleShortcodes( string $prefix ): void {
		foreach ( self::SIMPLE_MAP as $slug => $attr ) {
			$tag      = $prefix . '-' . $slug;
			$callback = function () use ( $attr, $tag ): string {
				return $this->safeRender(
					$tag,
					fn () => $this->renderer->renderField( $this->repository->get() ?? [], $attr )
				);
			};
			add_shortcode( $tag, $callback );
		}
	}

	/**
	 * Register special shortcodes that use dedicated renderer methods.
	 *
	 * @param string $prefix The shortcode prefix.
	 */
	private function registerSpecialShortcodes( string $prefix ): void {
		foreach ( self::SPECIAL_MAP as $slug => $method ) {
			$tag      = $prefix . '-' . $slug;
			$callback = function () use ( $method, $prefix, $tag ): string {
				return $this->safeRender(
					$tag,
					function () use ( $method, $prefix ): string {
						$profile = $this->repository->get();

						if ( null === $profile ) {
							return '';
						}

						return match ( $method ) {
							'renderFullAddressList'  => $this->renderer->renderFullAddressList( $profile, $prefix ),
							'renderServices'         => $this->renderer->renderServices( $profile, $prefix ),
							'renderHoursOfOperation' => $this->renderer->renderHoursOfOperation( $profile, $prefix ),
							'renderLogo'             => $this->renderer->renderLogo( $profile ),
							'renderPrimary'          => $this->renderer->renderPrimary( $profile ),
							default                  => '',
						};
					}
				);
			};
			add_shortcode( $tag, $callback );
		}
	}

	/**
	 * Register social icon shortcodes for a given prefix.
	 *
	 * @param string $prefix The shortcode prefix.
	 */
	private function registerSocialIconShortcodes( string $prefix ): void {
		foreach ( self::SOCIAL_ICON_MAP as $slug => $attr ) {
			$tag      = $prefix . '-' . $slug;
			$callback = function () use ( $attr, $tag ): string {
				return $this->safeRender(
					$tag,
					function () use ( $attr ): string {
						$profile = $this->repository->get();

						if ( null === $profile ) {
							return '';
						}

						$url = (string) ( $profile[ $attr ] ?? '' );

						return '' !== $url ? $this->renderer->renderSocialIcon( $attr, $url ) : '';
					}
				);
			};
			add_shortcode( $tag, $callback );
		}
	}

	/**
	 * Execute a render callback safely, catching any throwable.
	 *
	 * @param string   $tag      The shortcode tag (for logging).
	 * @param callable $callback The render callback.
	 * @return string Rendered output or empty string on failure.
	 */
	private function safeRender( string $tag, callable $callback ): string {
		try {
			return $callback();
		} catch ( \Throwable $e ) {
			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
				error_log( sprintf( 'wpcc legacy shortcode [%s] error: %s', $tag, $e->getMessage() ) );
			}
			return '';
		}
	}
}