@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A helper class for Filesystem checks.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Filesystem
|
||||
*/
|
||||
class Ai1ec_Filesystem_Checker {
|
||||
|
||||
|
||||
public function __construct() {
|
||||
include_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
}
|
||||
/**
|
||||
* check if the path is writable. To make the check .
|
||||
*
|
||||
* @param string $path
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_writable( $path ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
// try without credentials
|
||||
$writable = WP_Filesystem( false, $path );
|
||||
// We consider the directory as writable if it uses the direct transport,
|
||||
// otherwise credentials would be needed
|
||||
if ( true === $writable ) {
|
||||
return true;
|
||||
}
|
||||
// if the user has FTP and sockets defined
|
||||
if (
|
||||
$this->is_ftp_or_sockets( $wp_filesystem->method ) &&
|
||||
$this->are_ftp_constants_defined()
|
||||
) {
|
||||
$creds = request_filesystem_credentials( '', $wp_filesystem->method, false, $path );
|
||||
$writable = WP_Filesystem( $creds, $path );
|
||||
if ( true === $writable ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
$this->is_ssh( $wp_filesystem->method ) &&
|
||||
$this->are_ssh_constants_defined()
|
||||
) {
|
||||
$creds = request_filesystem_credentials( '', $wp_filesystem->method, false, $path );
|
||||
$writable = WP_Filesystem( $creds, $path );
|
||||
if ( true === $writable ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if method is ssh
|
||||
*
|
||||
* @param strin $method
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_ssh( $method ) {
|
||||
return 'ssh2' === $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if method is ftp or sockets
|
||||
*
|
||||
* @param string $method
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_ftp_or_sockets( $method ) {
|
||||
return 'ftpext' === $method ||
|
||||
'ftpsockets' === $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if credentials for ssh are defined
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function are_ssh_constants_defined() {
|
||||
return defined('FTP_HOST') &&
|
||||
defined('FTP_PUBKEY') &&
|
||||
defined('FTP_PRIKEY');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if credentials for ftp are defined
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function are_ftp_constants_defined() {
|
||||
return defined('FTP_HOST') &&
|
||||
defined('FTP_USER') &&
|
||||
defined('FTP_PASS');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file using $wp_filesystem.
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $content
|
||||
*/
|
||||
public function put_contents( $file, $content ) {
|
||||
global $wp_filesystem;
|
||||
return $wp_filesystem->put_contents(
|
||||
$file,
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content folder from Wordpress if available
|
||||
*
|
||||
* @return string the folder to use or ''
|
||||
*/
|
||||
public function get_ai1ec_static_dir_if_available() {
|
||||
global $wp_filesystem;
|
||||
// reset the filesystem to it's standard.
|
||||
WP_Filesystem();
|
||||
$content_dir = $wp_filesystem->wp_content_dir() . DIRECTORY_SEPARATOR
|
||||
. 'uploads' . DIRECTORY_SEPARATOR;
|
||||
$static_dir = trailingslashit( $content_dir . 'ai1ec_static' );
|
||||
if (
|
||||
! $wp_filesystem->is_dir( $static_dir ) &&
|
||||
! $wp_filesystem->mkdir( $static_dir )
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
return $static_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if specified file exists
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function check_file_exists( $file, $check_is_empty ) {
|
||||
try {
|
||||
if ( ! file_exists( $file ) ) {
|
||||
return false;
|
||||
} else {
|
||||
if ( $check_is_empty && 0 == filesize( $file ) ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Miscellaneous file system related functions.
|
||||
*
|
||||
* @author Time.ly Network Inc.
|
||||
* @since 2.2
|
||||
*
|
||||
* @package AI1EC
|
||||
* @subpackage AI1EC.Lib.Filesystem
|
||||
*/
|
||||
class Ai1ec_Filesystem_Misc extends Ai1ec_Base {
|
||||
|
||||
/**
|
||||
* Builds directory hashmap.
|
||||
*
|
||||
* @param array|string $paths Paths for hashmap generation. It accepts
|
||||
* string or array of paths. Elements in
|
||||
* hashmaps are not overwritten.
|
||||
* @param array $exclusions List of excluded file names.
|
||||
*
|
||||
* @return array Hashmap.
|
||||
*/
|
||||
public function build_dirs_hashmap( $paths, $exclusions = array() ) {
|
||||
if ( ! is_array( $paths ) ) {
|
||||
$paths = array( $paths );
|
||||
}
|
||||
$hashmap = array();
|
||||
foreach ( $paths as $path ) {
|
||||
if ( file_exists( $path ) ) {
|
||||
$hashmap += $this->build_dir_hashmap( $path, $exclusions );
|
||||
}
|
||||
}
|
||||
|
||||
ksort( $hashmap );
|
||||
|
||||
return $hashmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds hashmap for given directory.
|
||||
*
|
||||
* @param string $directory Directory for hashmap creation.
|
||||
* @param array $exclusions List of excluded file names.
|
||||
*
|
||||
* @return array Hashmap.
|
||||
*/
|
||||
public function build_dir_hashmap( $directory, $exclusions = array() ) {
|
||||
$directory_iterator = new RecursiveDirectoryIterator(
|
||||
$directory
|
||||
);
|
||||
$recursive_iterator = new RecursiveIteratorIterator(
|
||||
$directory_iterator
|
||||
);
|
||||
$files = new RegexIterator(
|
||||
$recursive_iterator,
|
||||
'/^.+\.(less|css|php)$/i',
|
||||
RegexIterator::GET_MATCH
|
||||
);
|
||||
$hashmap = array();
|
||||
foreach ( $files as $file ) {
|
||||
$file_info = new SplFileInfo( $file[0] );
|
||||
$file_path = $file_info->getPathname();
|
||||
if ( in_array( $file_info->getFilename(), $exclusions ) ) {
|
||||
continue;
|
||||
}
|
||||
$key = str_replace(
|
||||
array( $directory, '/' ),
|
||||
array( '', '\\' ),
|
||||
$file_path
|
||||
);
|
||||
|
||||
$hashmap[ $key ] = array(
|
||||
'size' => $file_info->getSize(),
|
||||
'sha1' => sha1_file( $file_path ),
|
||||
);
|
||||
}
|
||||
ksort( $hashmap );
|
||||
|
||||
return $hashmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns hashmap for current theme.
|
||||
*
|
||||
* @return mixed|null Hashmap or null if none.
|
||||
*
|
||||
* @throws Ai1ec_Bootstrap_Exception
|
||||
*/
|
||||
public function get_current_theme_hashmap() {
|
||||
$cur_theme = $this->_registry->get( 'model.option' )->get( 'ai1ec_current_theme' );
|
||||
|
||||
if ( ! $cur_theme || ( isset( $cur_theme['stylesheet'] ) && 'saas' === $cur_theme['stylesheet'] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$file_location = $cur_theme['theme_dir'] . DIRECTORY_SEPARATOR . 'less.sha1.map.php';
|
||||
if ( ! file_exists( $file_location ) || ! is_readable( $file_location ) || ! @file_get_contents( $file_location ) ) {
|
||||
// Delete theme options
|
||||
$this->_registry->get( 'model.option' )->delete( 'ai1ec_current_theme' );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return require $file_location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds file hashmap for current theme.
|
||||
*
|
||||
* @return array Hashmap.
|
||||
*
|
||||
* @throws Ai1ec_Bootstrap_Exception
|
||||
* @throws Ai1ec_Invalid_Argument_Exception
|
||||
*/
|
||||
public function build_current_theme_hashmap() {
|
||||
$paths = $this->_registry->get( 'theme.loader' )->get_paths();
|
||||
|
||||
return $this->build_dirs_hashmap(
|
||||
array_keys(
|
||||
$paths['theme']
|
||||
),
|
||||
array(
|
||||
'ai1ec_parsed_css.css',
|
||||
'less.sha1.map.php',
|
||||
'index.php',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns theme structrure for one of core themes.
|
||||
*
|
||||
* @param string $stylesheet Theme stylesheet. Expected one of
|
||||
* ['plana','vortex','umbra','gamma'].
|
||||
*
|
||||
* @return array Theme structure
|
||||
*
|
||||
* @throws Ai1ec_Invalid_Argument_Exception
|
||||
*/
|
||||
public function build_theme_structure( $stylesheet ) {
|
||||
$themes = array( 'plana', 'vortex', 'umbra', 'gamma' );
|
||||
if ( ! in_array( $stylesheet, $themes ) ) {
|
||||
throw new Ai1ec_Invalid_Argument_Exception(
|
||||
'Theme ' . $stylesheet . ' compilation is not supported.'
|
||||
);
|
||||
}
|
||||
$root = AI1EC_PATH . DIRECTORY_SEPARATOR . 'public' .
|
||||
DIRECTORY_SEPARATOR . AI1EC_THEME_FOLDER;
|
||||
|
||||
return array(
|
||||
'theme_root' => $root,
|
||||
'theme_dir' => $root . DIRECTORY_SEPARATOR . $stylesheet,
|
||||
'theme_url' => AI1EC_URL . '/public/' . AI1EC_THEME_FOLDER . '/' . $stylesheet,
|
||||
'stylesheet' => $stylesheet,
|
||||
'legacy' => false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares files hashmaps. If $src key doesn't exist in $dst, it's just
|
||||
* ommited. This is intended for LESS compilation check. Current theme
|
||||
* may contain more LESS files than base one, what does not matter as
|
||||
* other files should be changed accordingly.
|
||||
*
|
||||
* @param array $src Source hashmap. Should be computed from current
|
||||
* theme contents.
|
||||
* @param array $dst Base hashmap. Should be taken from less.sha1.map.php
|
||||
* file.
|
||||
*
|
||||
* @return bool Comparision result. True if they are equal.
|
||||
*/
|
||||
public function compare_hashmaps( array $src, array $dst ) {
|
||||
foreach ( $src as $key => $value ) {
|
||||
if ( ! isset( $dst[ $key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
$dst_value = $dst[ $key ];
|
||||
if ( $dst_value !== $value ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user