Files
doitinpoland.com/wp-content/plugins/sitepress-multilingual-cms/classes/language-switcher/class-wpml-ls-templates.php
2023-09-12 21:41:04 +02:00

327 lines
9.4 KiB
PHP

<?php
class WPML_LS_Templates {
const CONFIG_FILE = 'config.json';
const OPTION_NAME = 'wpml_language_switcher_template_objects';
/** @var string $uploads_path */
private $uploads_path;
/**
* @var WPML_File
*/
private $wpml_file;
/* @var array $templates Collection of WPML_LS_Template */
private $templates = false;
/* @var string $ds */
private $ds = DIRECTORY_SEPARATOR;
public function __construct( WPML_File $wpml_file = null ) {
if ( ! $wpml_file ) {
$wpml_file = new WPML_File();
}
$this->wpml_file = $wpml_file;
}
public function init_hooks() {
add_action( 'after_setup_theme', array( $this, 'after_setup_theme_action' ) );
add_action( 'activated_plugin', array( $this, 'activated_plugin_action' ) );
add_action( 'deactivated_plugin', array( $this, 'activated_plugin_action' ) );
add_action( 'switch_theme', array( $this, 'activated_plugin_action' ) );
}
/**
* @return array
*/
public function after_setup_theme_action() {
return $this->init_available_templates();
}
public function activated_plugin_action() {
delete_option( self::OPTION_NAME );
}
/**
* @param null|array $in_array
*
* @return array
*/
public function get_templates( $in_array = null ) {
if ( null === $in_array ) {
$ret = $this->templates;
} else {
// PHP 5.3 Bug https://bugs.php.net/bug.php?id=34857
$in_array = $in_array ? array_combine( $in_array, $in_array ) : $in_array;
$ret = array_intersect_key( $this->templates, $in_array );
}
return $ret;
}
/**
* @param string $template_slug
*
* @return WPML_LS_Template
*/
public function get_template( $template_slug ) {
$ret = new WPML_LS_Template( array() );
if ( array_key_exists( $template_slug, $this->templates ) ) {
$ret = $this->templates[ $template_slug ];
}
return $ret;
}
public function get_all_templates_data() {
$ret = array();
foreach ( $this->get_templates() as $slug => $template ) {
/* @var WPML_LS_Template $template */
$ret[ $slug ] = $template->get_template_data();
}
return $ret;
}
/**
* @return array
*/
private function init_available_templates() {
$is_admin_ui_page = isset( $_GET['page'] ) && WPML_LS_Admin_UI::get_page_hook() === $_GET['page'];
if ( ! $is_admin_ui_page ) {
$this->templates = $this->get_templates_from_transient();
}
if ( $this->templates === false ) {
$this->templates = array();
$dirs_to_scan = array();
/**
* Filter the directories to scan
*
* @param array $dirs_to_scan
*/
$dirs_to_scan = apply_filters( 'wpml_ls_directories_to_scan', $dirs_to_scan );
$sub_dir = $this->ds . 'templates' . $this->ds . 'language-switchers';
$wpml_core_path = WPML_PLUGIN_PATH . $sub_dir;
$theme_path = get_template_directory() . $this->ds . 'wpml' . $sub_dir;
$child_theme_path = get_stylesheet_directory() . $this->ds . 'wpml' . $sub_dir;
$uploads_path = $this->get_uploads_path() . $this->ds . 'wpml' . $sub_dir;
array_unshift( $dirs_to_scan, $wpml_core_path, $theme_path, $child_theme_path, $uploads_path );
$templates_paths = $this->scan_template_paths( $dirs_to_scan );
foreach ( $templates_paths as $template_path ) {
$template_path = $this->wpml_file->fix_dir_separator( $template_path );
if ( file_exists( $template_path . $this->ds . WPML_LS_Template::FILENAME ) ) {
$tpl = array();
$config = $this->parse_template_config( $template_path );
$tpl['path'] = [ $wpml_core_path, $template_path ];
$tpl['version'] = isset( $config['version'] ) ? $config['version'] : '1';
$tpl['name'] = isset( $config['name'] ) ? $config['name'] : null;
$tpl['name'] = $this->get_unique_name( $tpl['name'], $template_path );
$tpl['slug'] = sanitize_title_with_dashes( $tpl['name'] );
$tpl['base_uri'] = trailingslashit( $this->wpml_file->get_uri_from_path( $template_path ) );
$tpl['css'] = $this->get_files( 'css', $template_path, $config );
$tpl['js'] = $this->get_files( 'js', $template_path, $config );
$tpl['flags_base_uri'] = isset( $config['flags_dir'] ) // todo: check with ../
? $this->wpml_file->get_uri_from_path( $template_path . $this->ds . $config['flags_dir'] ) : null;
$tpl['flags_base_uri'] = ! isset( $tpl['flags_base_uri'] ) && file_exists( $template_path . $this->ds . 'flags' )
? $this->wpml_file->get_uri_from_path( $template_path . $this->ds . 'flags' ) : $tpl['flags_base_uri'];
$tpl['flag_extension'] = isset( $config['flag_extension'] )
? $config['flag_extension'] : null;
if ( $this->is_core_template( $template_path ) ) {
$tpl['is_core'] = true;
$tpl['slug'] = isset( $config['slug'] ) ? $config['slug'] : $tpl['slug'];
}
$tpl['for'] = isset( $config['for'] )
? $config['for'] : array( 'menus', 'sidebars', 'footer', 'post_translations', 'shortcode_actions' );
$tpl['force_settings'] = isset( $config['settings'] )
? $config['settings'] : array();
$this->templates[ $tpl['slug'] ] = new WPML_LS_Template( $tpl );
}
}
update_option( self::OPTION_NAME, $this->templates );
}
return $this->templates;
}
/**
* @param array $dirs_to_scan
*
* @return array
*/
private function scan_template_paths( $dirs_to_scan ) {
$templates_paths = array();
foreach ( $dirs_to_scan as $dir ) {
if ( ! is_dir( $dir ) ) {
continue;
}
$files = scandir( $dir );
$files = array_diff( $files, array( '..', '.' ) );
if ( count( $files ) > 0 ) {
foreach ( $files as $file ) {
$template_path = $dir . '/' . $file;
if ( is_dir( $template_path )
&& file_exists( $template_path . $this->ds . WPML_LS_Template::FILENAME )
&& file_exists( $template_path . $this->ds . self::CONFIG_FILE )
) {
$templates_paths[] = $template_path;
}
}
}
}
return $templates_paths;
}
/**
* @param string $template_path
*
* @return array
*/
private function parse_template_config( $template_path ) {
$config = array();
$configuration_file = $template_path . $this->ds . self::CONFIG_FILE;
if ( file_exists( $configuration_file ) ) {
$json_content = file_get_contents( $configuration_file );
$config = json_decode( $json_content, true );
}
return $config;
}
/**
* @param string $ext
* @param string $template_path
* @param array $config
*
* @return array|null
*/
private function get_files( $ext, $template_path, $config ) {
$resources = array();
if ( isset( $config[ $ext ] ) ) {
$config[ $ext ] = is_array( $config[ $ext ] ) ? $config[ $ext ] : array( $config[ $ext ] );
foreach ( $config[ $ext ] as $file ) {
$file = untrailingslashit( $template_path ) . $this->ds . $file;
$resources[] = $this->wpml_file->get_uri_from_path( $file );
}
} else {
$search_path = $template_path . $this->ds . '*.' . $ext;
if ( glob( $search_path ) ) {
foreach ( glob( $search_path ) as $file ) {
$resources[] = $this->wpml_file->get_uri_from_path( $file );
}
}
}
return $resources;
}
/**
* @param mixed|string|null $name
* @param string $path
*
* @return string
*/
private function get_unique_name( $name, $path ) {
if ( is_null( $name ) ) {
$name = basename( $path );
}
if ( strpos( $path, $this->wpml_file->fix_dir_separator( get_template_directory() ) ) === 0 ) {
$theme = wp_get_theme();
$name = $theme . ' - ' . $name;
} elseif ( strpos( $path, $this->wpml_file->fix_dir_separator( $this->get_uploads_path() ) ) === 0 ) {
$name = __( 'Uploads', 'sitepress' ) . ' - ' . $name;
} elseif (
strpos( $path, $this->wpml_file->fix_dir_separator( WPML_PLUGINS_DIR ) ) === 0
&& ! $this->is_core_template( $path )
) {
$plugin_dir = $this->wpml_file->fix_dir_separator( WPML_PLUGINS_DIR );
$plugin_dir = preg_replace( '#' . preg_quote( $plugin_dir ) . '#', '', $path, 1 );
$plugin_dir = ltrim( $plugin_dir, $this->ds );
$plugin_dir = explode( $this->ds, $plugin_dir );
if ( isset( $plugin_dir[0] ) ) {
$require = ABSPATH . 'wp-admin' . $this->ds . 'includes' . $this->ds . 'plugin.php';
require_once $require;
foreach ( get_plugins() as $slug => $plugin ) {
if ( strpos( $slug, $plugin_dir[0] ) === 0 ) {
$name = $plugin['Name'] . ' - ' . $name;
break;
}
}
} else {
$name = substr( md5( $path ), 0, 8 ) . ' - ' . $name;
}
}
return $name;
}
/**
* @param string $path
*
* @return bool
*/
private function is_core_template( $path ) {
return strpos( $path, $this->wpml_file->fix_dir_separator( WPML_PLUGIN_PATH ) ) === 0;
}
private function get_templates_from_transient() {
$templates = get_option( self::OPTION_NAME );
if ( $templates && ! $this->are_template_paths_valid( $templates ) ) {
$templates = false;
}
return $templates;
}
/**
* @param WPML_LS_Template[] $templates
*
* @return bool
*/
private function are_template_paths_valid( $templates ) {
$paths_are_valid = true;
foreach ( $templates as $template ) {
if ( ! method_exists( $template, 'is_path_valid' ) || ! $template->is_path_valid() ) {
$paths_are_valid = false;
break;
}
}
return $paths_are_valid;
}
/**
* @return null|string
*/
private function get_uploads_path() {
if ( ! $this->uploads_path ) {
$uploads = wp_upload_dir( null, false );
if ( isset( $uploads['basedir'] ) ) {
$this->uploads_path = $uploads['basedir'];
}
}
return $this->uploads_path;
}
}