Current File : /home/kelaby89/www/wp/wp-content/plugins/trx_updater/core/update/engine.php |
<?php
namespace TrxUpdater\Core\Update;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Engine extends Base {
/**
* Current theme engine
*
* Version of the engine of the current (active) theme
*
* @since 1.5.0
* @access protected
*
* @var engine
*/
protected $engine;
/**
* Active theme info
*
* Info about active theme
*
* @since 1.5.0
* @access private
*
* @var theme
*/
private $theme;
/**
* Theme parts to save while upgrade
*
* Save theme parts before upgrade and restore its after upgrade
*
* @since 1.5.0
* @access private
*
* @var theme_parts
*/
private $theme_parts;
/**
* Files and folders to exclude from upgrade
*
* Theme files and folders to exclude from upgrade
*
* @since 1.5.0
* @access private
*
* @var theme_exclude
*/
private $theme_exclude;
/**
* Class constructor.
*
* Initializing themes update manager.
*
* @since 1.5.0
* @access public
*/
public function __construct( $manager ) {
parent::__construct( $manager );
add_action( 'init', array( $this, 'init') );
add_filter( 'wp_get_update_data', array( $this, 'add_engine_to_update_counts' ), 10, 2 );
add_action( 'core_upgrade_preamble', array( $this, 'add_engine_to_update_screen' ), 8 );
add_action( 'update-custom_update-engine', array( $this, 'update_engine' ) );
}
/**
* Init object
*
* Get current (active) theme info and the engine version from upgrade server
*
* Fired by `init` action
*
* @since 1.5.0
* @access public
*/
public function init() {
$this->theme_parts = array();
$this->theme_exclude = array();
$this->theme = $this->get_theme_info();
if ( ! empty( $this->theme['engine']['upgrade_allowed'] ) ) {
$this->engine = $this->get_engine_info();
$this->theme_exclude = apply_filters( 'trx_updater_filter_theme_exclude',
array(
'folders' => array(
'.git',
'.idea',
'.vscode',
'templates',
'parts'
),
'files' => array(
'.gitignore',
'changelog.txt',
'readme.txt',
'screenshot.jpg',
'rtl.css',
'style.css',
'style.scss',
'style.css.map',
'theme.json'
)
)
);
if ( ! is_array( $this->theme_exclude['folders'] ) ) {
$this->theme_exclude['folders'] = array();
}
foreach( $this->theme_exclude['folders'] as $k => $v ) {
$v = chop( trx_updater_esc( $v ) );
$v = str_replace( '..', '', $v );
$this->theme_exclude['folders'][ $k ] = $v;
}
if ( ! is_array( $this->theme_exclude['files'] ) ) {
$this->theme_exclude['files'] = array();
}
foreach( $this->theme_exclude['files'] as $k => $v ) {
$v = chop( trx_updater_esc( $v ) );
$v = str_replace( '..', '', $v );
$this->theme_exclude['files'][ $k ] = $v;
}
}
}
/**
* Retrieve info about current theme
*
* Retrieve info about current (active) theme from the updates server
*
* @since 1.5.0
* @access private
*/
private function get_theme_info() {
return apply_filters( 'trx_updater_filter_get_theme_info', array(
'slug' => $this->theme_slug,
'title' => $this->theme_name,
'key' => $this->theme_key,
'version' => $this->theme_version,
'engine' => array(
'name' => '',
'version' => '0.0.1',
'upgrade_allowed' => false
),
'icon' => $this->get_item_icon( 'theme', $this->theme_slug, $this->theme_name ),
) );
}
/**
* Retrieve info about the latest version of the engine
*
* Retrieve info about the latest version of the engine from the updates server
*
* @since 1.5.0
* @access private
*/
private function get_engine_info() {
$data = get_transient( 'trx_updater_engine_info' );
if ( ! is_array( $data ) || ! empty( $_GET['force-check'] ) ) {
$data = array(
$this->theme_slug => array(
'theme_slug' => '',
'theme_name' => '',
'version' => '0.0.1',
'update_from' => '0.0.2',
)
);
$response = trx_updater_fgc( $this->update_url
. '?action=info_engine'
. '&theme_slug=' . urlencode( $this->theme_slug )
. '&theme_name=' . urlencode( $this->theme_name )
. '&key=' . urlencode( $this->theme_key )
);
if ( !empty($response) && is_serialized($response) ) {
$response = unserialize($response);
if ( !empty($response['data']) && substr($response['data'], 0, 1) == '{' ) {
$data[ $this->theme_slug ] = json_decode($response['data'], true);
}
}
set_transient( 'trx_updater_engine_info', $data, 12 * 60 * 60 ); // Store to the cache for 12 hours
}
return apply_filters( 'trx_updater_filter_get_engine_info', array(
'theme_slug' => ! empty( $data[$this->theme_slug]['theme_slug'] ) ? $data[$this->theme_slug]['theme_slug'] : '',
'theme_name' => ! empty( $data[$this->theme_slug]['theme_name'] ) ? $data[$this->theme_slug]['theme_name'] : '',
'version' => ! empty( $data[$this->theme_slug]['version'] ) ? $data[$this->theme_slug]['version'] : '',
'update_from' => ! empty( $data[$this->theme_slug]['update_from'] ) ? $data[$this->theme_slug]['update_from'] : '',
) );
}
/**
* Count engine updates
*
* Return 1 if a new version of the engine is available
*
* @since 1.5.0
* @access private
*/
private function count_engine_updates() {
return ! empty( $this->theme['engine']['upgrade_allowed'] )
&& ! empty( $this->theme['engine']['version'] )
&& ! empty( $this->engine['version'] )
&& version_compare( $this->engine['version'], $this->theme['engine']['version'], '>' )
&& ( empty( $this->engine['update_from'] ) || version_compare( $this->engine['version'], $this->engine['update_from'], '>=' ) )
? 1
: 0;
}
/**
* Add 1 to the WordPress updates count
*
* Add 1 to the WordPress updates count if new engine is available.
*
* Fired by `wp_get_update_data` action.
*
* @since 1.5.0
* @access public
*/
public function add_engine_to_update_counts($update_data, $titles) {
if ( current_user_can( 'update_themes' ) && ! empty( $this->theme['engine']['upgrade_allowed'] ) ) {
$update = $this->count_engine_updates();
if ( $update > 0 ) {
if ( empty( $update_data[ 'counts' ][ 'engine' ] ) ) {
$update_data[ 'counts' ][ 'engine' ] = 0;
}
$update_data[ 'counts' ][ 'engine' ] += $update;
$update_data[ 'counts' ][ 'total' ] += $update;
// Translators: %d: number of updates available to installed skins
$titles['engine'] = sprintf( _n( '%d Theme Core Update', '%d Theme Core Updates', $update_data[ 'counts' ][ 'engine' ], 'trx-updater' ), $update );
$update_data['title'] = esc_attr( implode( ', ', $titles ) );
}
}
return $update_data;
}
/**
* Add new engine version to the WordPress update screen
*
* Add new engine version to the WordPress update screen
*
* Fired by `core_upgrade_preamble` action.
*
* @since 1.5.0
* @access public
*/
public function add_engine_to_update_screen() {
if ( current_user_can( 'update_themes' ) && ! empty( $this->theme['engine']['upgrade_allowed'] ) ) {
$update = $this->count_engine_updates();
if ( $update == 0 ) return;
?>
<h2>
<?php
// Translators: add theme name to the section title
esc_html_e( 'Active theme components: Theme Core files', 'trx-updater' );
?>
</h2>
<p>
<?php esc_html_e( 'Active theme have a new core files available. Check it and then click “Update Theme Core”.', 'trx-updater' ); ?>
</p>
<div class="upgrade trx_updater_upgrade trx_updater_upgrade_engine">
<p><input id="upgrade-engine" class="button trx_updater_upgrade_button trx_updater_upgrade_engine_button" type="button" value="<?php esc_attr_e( 'Update Theme Core', 'trx-updater' ); ?>" /></p>
<table class="widefat updates-table" id="update-engine-table">
<tbody class="plugins engine">
<?php $checkbox_id = 'checkbox_' . md5( $this->theme['slug'] . '_engine' ); ?>
<tr>
<td class="check-column">
<input type="checkbox"
name="checked[]"
id="<?php echo esc_attr( $checkbox_id ); ?>"
data-update-url="<?php echo esc_url( $this->get_iau_link( $this->theme_slug, 'update', 'engine' ) ); ?>"
value="<?php echo esc_attr( $this->theme['slug'] ); ?>"
/>
<label for="<?php echo esc_attr( $checkbox_id ); ?>" class="screen-reader-text">
<?php
// Translators: %s: Theme name
printf( esc_html__( 'Select %s', 'trx-updater' ), $this->theme['title'] );
?>
</label>
</td>
<td class="plugin-title"><p>
<?php echo $this->theme['icon']; ?>
<strong><?php echo esc_html( $this->theme['title'] ); ?></strong>
<?php
// Translators: 1: Theme version, 2: new version
printf(
esc_html__( 'You have theme core version %1$s installed. Update to %2$s.', 'trx-updater' ),
$this->theme['engine']['version'],
$this->engine['version']
);
?>
</p></td>
</tr>
</tbody>
</table>
<p><input id="upgrade-theme-2" class="button trx_updater_upgrade_button trx_updater_upgrade_engine_button" type="button" value="<?php esc_attr_e( 'Update Theme Core', 'trx-updater' ); ?>" /></p>
</div>
<?php
}
}
/**
* Update engine
*
* Download a new engine from the upgrade server and update it
*
* Fired by `update-custom_update-theme` action.
*
* @since 1.5.0
* @access public
*/
public function update_engine() {
$nonce = trx_updater_get_value_gp('_wpnonce');
$engine = trx_updater_get_value_gp('engine');
if ( ! empty( $nonce )
&& $engine == $this->theme_slug
&& wp_verify_nonce( $nonce, "update-engine_{$engine}" )
&& current_user_can( 'update_themes' )
&& ! empty( $this->theme['engine']['upgrade_allowed'] )
) {
// Prepare URL to upgrade server
$theme_url = sprintf( $this->update_url
. '?action=install_engine'
. '&src=%1$s'
. '&key=%2$s'
. '&theme_slug=%3$s'
. '&theme_name=%4$s'
. '&domain=%5$s'
. '&rnd=%6$s',
urlencode( $this->get_theme_market_code() ),
urlencode( $this->theme_key ),
urlencode( $this->theme_slug ),
urlencode( $this->theme_name ),
urlencode( trx_updater_remove_protocol( get_home_url(), true ) ),
mt_rand()
);
// Add theme data to upgrade cache
$v = explode('.', '' . $this->theme_version );
$v_length = count( $v );
if ( $v_length > 3 ) {
$v[ $v_length - 1 ]++;
} else {
$v[] = 1;
}
$v = join( '.', $v );
$this->inject_update_info( 'themes', array(
$this->theme_slug => array(
'theme' => $this->theme_slug,
'new_version' => $v,
'package' => $theme_url,
'requires' => '4.7.0',
'requires_php' => '5.6.0'
)
) );
// Load upgrader
if ( ! class_exists( 'Theme_Upgrader' ) ) {
include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
}
$upgrader = new \Theme_Upgrader(
new \Theme_Upgrader_Skin(
array(
'title' => sprintf( __( 'Updating Theme Core "%s"', 'trx-updater' ), $this->theme_name ),
'nonce' => "update-engine_{$this->theme_slug}",
'url' => add_query_arg( array( 'package' => $theme_url ), 'update.php?action=upgrade-theme' ),
'theme' => $this->theme_slug,
'type' => 'upload',
'package' => $theme_url
)
)
);
$this->before_engine_upgrade();
$upgrader->upgrade( $this->theme_slug );
$this->after_engine_upgrade();
}
}
/**
* Prepare current theme to engine upgrade
*
* Backup skins before upgrade engine
*
* @since 1.5.0
* @access public
*/
public function before_engine_upgrade() {
$theme_dir = get_template_directory();
// Backup skins
$skins_dir = $theme_dir . '/skins/';
$skins_json = $skins_dir . 'skins.json';
if ( file_exists( $skins_json ) ) {
$this->theme_parts['skins-json'] = trx_updater_fgc( $skins_json );
}
$skins_options = $skins_dir . 'skins-options.php';
if ( file_exists( $skins_options ) ) {
$this->theme_parts['skins-options'] = trx_updater_fgc( $skins_options );
}
$skins_list = glob( $skins_dir . '*', GLOB_ONLYDIR);
if ( is_array( $skins_list ) ) {
$this->theme_parts['skins'] = array();
trx_updater_allow_upload_archives();
foreach( $skins_list as $sdir ) {
$sname = basename( $sdir );
$rnd = str_replace('.', '', mt_rand());
$result = wp_upload_bits( "backup-{$this->theme_slug}-skin-{$sname}-{$rnd}.zip", 0, '' );
if ( ! empty( $result['file'] ) ) {
if ( trx_updater_pack_archive( $result['file'], $sdir ) ) {
$this->theme_parts['skins'][$sname] = array(
'backup' => $result['file'],
);
}
}
}
trx_updater_disallow_upload_archives();
}
// Backup plugins list
$plugins_dir = $theme_dir . '/plugins/';
$plugins_list = glob( $plugins_dir . '*', GLOB_ONLYDIR);
if ( array( $plugins_list ) ) {
$this->theme_parts['plugins'] = array();
foreach( $plugins_list as $pdir ) {
$pname = basename( $pdir );
$this->theme_parts['plugins'][$pname] = array(
'slug' => $pname
);
}
}
// Backup exclude files and folders
$this->theme_parts['exclude'] = array();
if ( ! empty( $this->theme_exclude['files'] ) && count( $this->theme_exclude['files'] ) > 0 ) {
$files = array();
foreach( $this->theme_exclude['files'] as $file ) {
if ( ! empty( $file ) && file_exists( $theme_dir . '/' . $file ) ) {
$files[] = $theme_dir . '/' . $file;
}
}
if ( count( $files ) > 0 ) {
trx_updater_allow_upload_archives();
$rnd = str_replace('.', '', mt_rand());
$result = wp_upload_bits( "backup-{$this->theme_slug}-exclude-{$rnd}.zip", 0, '' );
trx_updater_disallow_upload_archives();
if ( ! empty( $result['file'] ) ) {
if ( trx_updater_pack_archive( $result['file'], $theme_dir, $files ) ) {
$this->theme_parts['exclude'][''] = array(
'backup' => $result['file'],
'mode' => 0
);
}
}
}
}
if ( ! empty( $this->theme_exclude['folders'] ) ) {
trx_updater_allow_upload_archives();
foreach( $this->theme_exclude['folders'] as $folder ) {
if ( is_dir( $theme_dir . '/' . $folder ) ) {
$rnd = str_replace('.', '', mt_rand());
$result = wp_upload_bits( "backup-{$this->theme_slug}-exclude-{$rnd}.zip", 0, '' );
if ( ! empty( $result['file'] ) ) {
if ( trx_updater_pack_archive( $result['file'], $theme_dir . '/' . $folder ) ) {
$this->theme_parts['exclude']["/{$folder}"] = array(
'backup' => $result['file'],
'mode' => trx_updater_getmod( $theme_dir . '/' . $folder ),
);
}
}
}
}
trx_updater_disallow_upload_archives();
}
}
/**
* Restore current theme parts after engine is upgraded
*
* Restore skins after theme engine is upgraded
*
* @since 1.5.0
* @access public
*/
public function after_engine_upgrade() {
$theme_dir = get_template_directory();
// Delete excess (not used in the theme) plugins
if ( ! empty( $this->theme_parts['plugins'] ) && is_array( $this->theme_parts['plugins'] ) ) {
$plugins_dir = $theme_dir . '/plugins/';
$plugins_list = glob( $plugins_dir . '*', GLOB_ONLYDIR);
if ( array( $plugins_list ) ) {
foreach( $plugins_list as $pdir ) {
$pname = basename( $pdir );
if ( ! isset( $this->theme_parts['plugins'][$pname] ) ) {
trx_updater_del_folder( $pdir );
}
}
}
}
// Delete skins from engine
// (not need, because skins was removed on the server)
if ( ! empty( $this->theme_parts['skins'] ) && is_array( $this->theme_parts['skins'] ) ) {
$skins_dir = $theme_dir . '/skins/';
if ( is_dir( $skins_dir ) ) {
$skins_list = glob( $skins_dir . '*', GLOB_ONLYDIR);
if ( array( $skins_list ) ) {
foreach( $skins_list as $sdir ) {
if ( is_dir( $sdir ) ) {
trx_updater_del_folder( $sdir );
}
}
}
}
}
// Restore saved skins
if ( ! empty( $this->theme_parts['skins'] ) && is_array( $this->theme_parts['skins'] ) ) {
$skins_dir = $theme_dir . '/skins/';
if ( is_dir( $skins_dir ) ) {
// Restore skins.json
if ( ! empty( $this->theme_parts['skins-json'] ) ) {
trx_updater_fpc( $skins_dir . 'skins.json', $this->theme_parts['skins-json'] );
}
// Restore skins-options.php
if ( ! empty( $this->theme_parts['skins-options'] ) ) {
trx_updater_fpc( $skins_dir . 'skins-options.php', $this->theme_parts['skins-options'] );
}
// Restore skins
foreach( $this->theme_parts['skins'] as $skin_name => $skin_data ) {
$sdir = $skins_dir . trx_updater_esc( $skin_name );
if ( ! empty( $skin_data['backup'] ) && file_exists( $skin_data['backup'] ) ) {
if ( mkdir( $sdir ) && is_dir( $sdir ) ) {
unzip_file( $skin_data['backup'], $sdir );
}
trx_updater_unlink( $skin_data['backup'] );
}
}
}
}
// Restore exclude files and folders
if ( ! empty( $this->theme_parts['exclude'] ) ) {
foreach( $this->theme_parts['exclude'] as $exclude_dir => $exclude_data ) {
if ( ! empty( $exclude_data['backup'] ) && file_exists( $exclude_data['backup'] ) ) {
unzip_file( $exclude_data['backup'], $theme_dir . $exclude_dir );
if ( is_dir( $theme_dir . $exclude_dir ) ) {
if ( ! empty( $exclude_data['mode'] ) ) {
$rez = chmod( $theme_dir . $exclude_dir, $exclude_data['mode'] );
}
if ( $exclude_dir == '/.git' && defined( 'PHP_OS' ) && strtoupper( substr( PHP_OS, 0, 3 ) ) == 'WIN' ) {
@exec( 'attrib ' . $theme_dir . $exclude_dir . ' +H > nul' );
}
}
}
trx_updater_unlink( $exclude_data['backup'] );
}
}
}
}