aristath/kirki

View on GitHub
packages/kirki-framework/url-getter/src/URL.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php
/**
 * Get the URL of any file in WordPress.
 *
 * @package   kirki-framework/url-getter
 * @author    Ari Stathopoulos (@aristath)
 * @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
 * @license   https://opensource.org/licenses/MIT
 * @since     1.0
 */

namespace Kirki;

/**
 * A collection of methods to get the URL of files.
 *
 * @since 1.0
 */
class URL {

    /**
     * An array of instances.
     *
     * Used for performance reasons in case we need
     * the same url over and over again.
     *
     * @static
     * @access private
     * @since 1.0.2
     * @var array
     */
    private static $instances = [];

    /**
     * The file path.
     *
     * @access private
     * @since 1.0
     * @var string
     */
    private $path;

    /**
     * The content path.
     *
     * @static
     * @access private
     * @since 1.0
     * @var string
     */
    private static $content_path;

    /**
     * The content RL.
     *
     * @static
     * @access private
     * @since 1.0
     * @var string
     */
    private static $content_url;

    /**
     * The file URL.
     *
     * @access private
     * @since 1.0
     * @var string
     */
    private $url;

    /**
     * Gets an instance based on the path.
     *
     * @static
     * @access public
     * @since 1.0.2
     * @param string $path Absolute path to a file.
     * @return URL         An instance of this object.
     */
    public static function get_instance( $path ) {
        $path = \wp_normalize_path( $path );
        if ( ! isset( self::$instances[ $path ] ) ) {
            self::$instances[ $path ] = new self( $path );
        }
        return self::$instances[ $path ];
    }

    /**
     * Constructor.
     *
     * @access private
     * @since 1.0
     * @param string $path Absolute path to a file.
     */
    private function __construct( $path ) {
        $this->path = ( $path );
        $this->set_content_url();
        $this->set_content_path();
    }

    /**
     * Get a URL from a path.
     *
     * @static
     * @access public
     * @since 1.0.2
     * @param string $path The file path.
     * @return string
     */
    public static function get_from_path( $path ) {
        return self::get_instance( $path )->get_url();
    }

    /**
     * Get the file URL.
     *
     * @access public
     * @since 1.0
     * @return string
     */
    public function get_url() {

        /**
         * Start by replacing ABSPATH with site_url.
         * This is not accurate at all and only serves as a fallback in case everything else fails.
         */
        $this->url = \str_replace( ABSPATH, \trailingslashit( \site_url() ), $this->path );

        /**
         * If the file-path is inside wp-content replace the content-path with the content-url.
         * This serves as a fallback in case the other tests below fail.
         */
        if ( false !== \strpos( $this->path, self::$content_path ) ) {
            $this->url = \str_replace( self::$content_path, self::$content_url, $this->path );
        }

        /**
         * If the file is in a parent theme use the template directory.
         */
        if ( $this->in_parent_theme() ) {
            $this->url = \get_template_directory_uri() . \str_replace( \get_template_directory(), '', $this->path );
        }

        /**
         * If the file is in a child-theme use the stylesheet directory.
         */
        if ( ! $this->in_parent_theme() && $this->in_child_theme() ) {
            $this->url = \get_stylesheet_directory_uri() . \str_replace( \get_stylesheet_directory(), '', $this->path );
        }

        $this->url = \set_url_scheme( $this->url );
        return \apply_filters( 'kirki_path_url', $this->url, $this->path );
    }

    /**
     * Check if the path is inside a parent theme.
     *
     * @access public
     * @since 1.0
     * @return bool
     */
    public function in_parent_theme() {
        return ( 0 === \strpos( $this->path, \get_template_directory() ) );
    }

    /**
     * Check if the path is inside a child theme.
     *
     * @access public
     * @since 1.0
     * @return bool
     */
    public function in_child_theme() {
        return ( 0 === \strpos( $this->path, \get_stylesheet_directory() ) );
    }

    /**
     * Set the $content_url.
     *
     * @access private
     * @since 1.0
     * @return void
     */
    private function set_content_url() {
        if ( ! self::$content_url ) {
            self::$content_url = \untrailingslashit( \content_url() );
        }
    }

    /**
     * Set the $content_path.
     *
     * @access private
     * @since 1.0
     * @return void
     */
    private function set_content_path() {
        if ( ! self::$content_path ) {
            self::$content_path = \wp_normalize_path( \untrailingslashit( WP_CONTENT_DIR ) );
        }
    }
}