file_extension = $file_extension; $this->handle = $handle; $this->uri = $this->get_uri_from_path( $uri ); $this->dependencies = $dependencies; $this->version = $version ?: $this->get_version(); $this->enqueue_condition_callback = $enqueue_condition_callback; } /** * Get the handle of the asset. The handle serves as the ID within WordPress. * * @return string */ public function get_handle(): string { return $this->handle; } /** * Get the URI for the asset. * * @return string */ public function get_uri(): string { return $this->uri; } /** * Get the condition callback to run when enqueuing the asset. * * The asset will only be enqueued if the callback returns true. * * @return bool */ public function can_enqueue(): bool { if ( is_null( $this->enqueue_condition_callback ) ) { return true; } return (bool) call_user_func( $this->enqueue_condition_callback, $this ); } /** * Enqueue the asset within WordPress. */ public function enqueue(): void { if ( ! $this->can_enqueue() ) { return; } $this->defer_action( $this->get_enqueue_action(), $this->get_enqueue_callback(), $this->enqueue_priority ); } /** * Dequeue the asset within WordPress. */ public function dequeue(): void { $this->defer_action( $this->get_dequeue_action(), $this->get_dequeue_callback(), $this->dequeue_priority ); } /** * Register a service. */ public function register(): void { $this->defer_action( $this->get_register_action(), $this->get_register_callback(), $this->registration_priority ); } /** * Get the register action to use. * * @since 0.1.0 * * @return string Register action to use. */ protected function get_register_action(): string { return $this->get_enqueue_action(); } /** * Get the enqueue action to use. * * @return string */ protected function get_enqueue_action(): string { return 'wp_enqueue_scripts'; } /** * Get the dequeue action to use. * * @return string */ protected function get_dequeue_action(): string { return 'wp_print_scripts'; } /** * Add a callable to an action, or run it immediately if the action has already fired. * * @param string $action * @param callable $callback * @param int $priority */ protected function defer_action( string $action, callable $callback, int $priority = 10 ): void { if ( did_action( $action ) ) { try { $callback(); } catch ( InvalidAsset $exception ) { do_action( 'woocommerce_gla_exception', $exception, __METHOD__ ); } return; } add_action( $action, $callback, $priority ); } /** * Convert a file path to a URI for a source. * * @param string $path The source file path. * * @return string */ protected function get_uri_from_path( string $path ): string { $path = $this->normalize_source_path( $path ); $path = str_replace( $this->get_root_dir(), '', $path ); return $this->get_plugin_url( $path ); } /** * Normalize a source path with a given file extension. * * @param string $path The path to normalize. * * @return string */ protected function normalize_source_path( string $path ): string { $path = ltrim( $path, '/' ); $path = $this->maybe_add_extension( $path ); $path = "{$this->get_root_dir()}/{$path}"; return $this->maybe_add_minimized_extension( $path ); } /** * Possibly add an extension to a path. * * @param string $path Path where an extension may be needed. * * @return string */ protected function maybe_add_extension( string $path ): string { $detected_extension = pathinfo( $path, PATHINFO_EXTENSION ); if ( $this->file_extension !== $detected_extension ) { $path .= ".{$this->file_extension}"; } return $path; } /** * Possibly add a minimized extension to a path. * * @param string $path Path where a minimized extension may be needed. * * @return string * @throws InvalidAsset When no asset can be found. */ protected function maybe_add_minimized_extension( string $path ): string { $minimized_path = str_replace( ".{$this->file_extension}", ".min.{$this->file_extension}", $path ); // Validate that at least one version of the file exists. $path_readable = is_readable( $path ); $minimized_readable = is_readable( $minimized_path ); if ( ! $path_readable && ! $minimized_readable ) { throw InvalidAsset::invalid_path( $path ); } // If we only have one available, return the available one no matter what. if ( ! $minimized_readable ) { return $path; } elseif ( ! $path_readable ) { return $minimized_path; } return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? $path : $minimized_path; } /** * Get the register callback to use. * * @return callable */ abstract protected function get_register_callback(): callable; /** * Get the enqueue callback to use. * * @return callable */ abstract protected function get_enqueue_callback(): callable; /** * Get the dequeue callback to use. * * @return callable */ abstract protected function get_dequeue_callback(): callable; }