*/
class Abovethefold_Upgrade
{
/**
* Advanced optimization controller
*/
public $CTRL;
/**
* Initialize the class and set its properties
*/
public function __construct(&$CTRL)
{
$this->CTRL =& $CTRL;
}
/**
* Upgrade plugin
*/
public function upgrade()
{
$current_version = get_option('wpabtf_version');
$update_options = false;
if (!defined('WPABTF_VERSION') || WPABTF_VERSION !== $current_version) {
$options = get_option('abovethefold');
update_option('wpabtf_version', WPABTF_VERSION, false);
/**
* Pre 2.5.0 update
*/
if (version_compare($current_version, '2.5.0', '<')) {
/**
* Disable Google Web Font Optimizer plugin if ABTF Webfont Optimization is enabled
*/
if (isset($options['gwfo']) && $options['gwfo']) {
@deactivate_plugins('google-webfont-optimizer/google-webfont-optimizer.php');
$options['gwfo_loadmethod'] = 'inline';
$options['gwfo_loadposition'] = 'header';
$update_options = true;
}
/**
* Enable external resource proxy if Localize Javascript is enabled
*/
if (isset($options['localizejs_enabled']) && $options['localizejs_enabled']) {
$options['js_proxy'] = true;
$options['css_proxy'] = true;
$update_options = true;
}
}
/**
* Pre 2.5.11 update
*/
if (version_compare($current_version, '2.5.10', '<=')) {
// convert url list to array
$newline_conversion = array(
'gwfo_googlefonts',
'cssdelivery_ignore',
'cssdelivery_remove',
'css_proxy_preload',
'js_proxy_preload',
'css_proxy_include',
'js_proxy_include',
'css_proxy_exclude',
'js_proxy_exclude'
);
foreach ($newline_conversion as $field) {
if (isset($options[$field]) && is_string($options[$field])) {
$options[$field] = $this->newline_array($options[$field]);
$update_options = true;
}
}
/**
* Verify Google WebFontConfig variable
*/
if (isset($options['gwfo_config']) && $options['gwfo_config'] !== '') {
if ($this->CTRL->gwfo->verify_webfontconfig($options['gwfo_config'])) {
$options['gwfo_config_valid'] = true;
} else {
$options['gwfo_config_valid'] = false;
}
$update_options = true;
// Extract Google Fonts
$this->CTRL->gwfo->fonts_from_webfontconfig($options['gwfo_config'], $options['gwfo_googlefonts']);
// modify Google font config in WebFontConfig
$googlefonts_regex = '|google\s*:\s*(\{[^\}]+\})|is';
if (preg_match($googlefonts_regex, $options['gwfo_config'], $out)) {
$config = @json_decode($this->CTRL->gwfo->fixJSON($out[1]), true);
if (is_array($config) && isset($config['families'])) {
$config['families'] = 'GOOGLE-FONTS-FROM-INCLUDE-LIST';
$options['gwfo_config'] = preg_replace($googlefonts_regex, 'google:' . json_encode($config), $options['gwfo_config']);
}
}
} else {
$options['gwfo_config_valid'] = true;
$update_options = true;
}
}
/**
* Pre 2.6.1 update
*/
if (version_compare($current_version, '2.6.4', '<=')) {
if (!isset($options['jsdelivery'])) {
$options['jsdelivery'] = false;
}
if (!isset($options['jsdelivery_position'])) {
$options['jsdelivery_position'] = 'header';
}
if (!isset($options['jsdelivery_jquery'])) {
$options['jsdelivery_jquery'] = true;
}
if (!isset($options['jsdelivery_deps'])) {
$options['jsdelivery_deps'] = true;
}
if (!isset($options['jsdelivery_scriptloader'])) {
$options['jsdelivery_scriptloader'] = 'little-loader';
}
$update_options = true;
}
/**
* Pre 2.7 update
*/
if (version_compare($current_version, '2.7', '<=')) {
$dir = wp_upload_dir();
$old_cachepath = trailingslashit($dir['basedir']) . 'abovethefold/';
if (!is_dir($old_cachepath)) {
$old_cachepath = false;
}
/**
* Move critical CSS to new location (theme directory)
*/
// global css
$inlinecss = '';
if ($old_cachepath) {
$old_cssfile = $old_cachepath . 'criticalcss_global.css';
if (file_exists($old_cssfile)) {
$inlinecss = file_get_contents($old_cssfile);
} else {
$old_cssfile = $old_cachepath . 'inline.min.css';
if (file_exists($old_cssfile)) {
$inlinecss = file_get_contents($old_cssfile);
}
}
}
// save new critical css file
$config = array(
'name' => 'Global Critical CSS'
);
$errors = $this->CTRL->criticalcss->save_file_contents('global.css', $config, $inlinecss);
// remove old critical css file
if (!$errors || empty($errors)) {
@unlink($old_cssfile);
}
// conditional CSS
if ($old_cachepath && isset($options['conditional_css']) && !empty($options['conditional_css'])) {
foreach ($options['conditional_css'] as $conditionhash => $conditional) {
if (empty($conditional['conditions']) || !is_array($conditional['conditions'])) {
continue 1;
}
$inlinecss = '';
$old_cssfile = $old_cachepath . 'criticalcss_'.$conditionhash.'.css';
if (file_exists($old_cssfile)) {
$inlinecss = file_get_contents($old_cssfile);
}
if (trim($inlinecss) === '') {
continue 1;
}
$config = array(
'name' => $conditional['name'],
'weight' => ((is_numeric($conditional['weight'])) ? $conditional['weight'] : 1),
'conditions' => array()
);
$conditions = array();
foreach ($conditional['conditions'] as $condition) {
if ($condition === 'categories') {
$config['conditions'][] = 'is_category()';
} elseif ($condition === 'frontpage') {
$config['conditions'][] = 'is_front_page()';
} elseif (substr($condition, 0, 3) === 'pt_') {
/**
* Page Template Condition
*/
if (substr($condition, 0, 7) === 'pt_tpl_') {
$config['conditions'][] = 'is_page_template():' . substr($condition, 7);
} else {
/**
* Post Type Condition
*/
$pt = substr($condition, 3);
switch ($pt) {
case "page":
case "attachment":
$config['conditions'][] = 'is_'.$pt.'()';
break;
case "post":
$config['conditions'][] = 'is_single()';
$config['conditions'][] = 'is_singular():' . $pt;
break;
default:
$config['conditions'][] = 'is_singular():' . $pt;
break;
}
}
} elseif (class_exists('WooCommerce') && substr($condition, 0, 3) === 'wc_') {
/**
* WooCommerce page type
*/
$wcpage = substr($condition, 3);
$match = false;
switch ($wcpage) {
case "shop":
case "product_category":
case "product_tag":
case "product":
case "cart":
case "checkout":
case "account_page":
$config['conditions'][] = 'is_'.$wcpage.'()';
break;
}
} elseif (substr($condition, 0, 3) === 'tax') {
/**
* Taxonomy page
*/
$tax = substr($condition, 3);
$config['conditions'][] = 'is_tax():' . $tax;
} elseif (substr($condition, 0, 3) === 'cat') {
/**
* Categories
*/
$cat = substr($condition, 3);
$config['conditions'][] = 'is_category():' . $cat;
} elseif (substr($condition, 0, 3) === 'catpost') {
/**
* Posts with categories
*/
$cat = substr($condition, 3);
$config['conditions'][] = 'has_category():' . $cat;
} elseif (substr($condition, 0, 4) === 'page') {
/**
* Individual pages
*/
$pageid = intval(substr($condition, 4));
$config['conditions'][] = 'is_page():' . $pageid;
} elseif (substr($condition, 0, 4) === 'post') {
/**
* Individual posts
*/
$postid = intval(substr($condition, 4));
$config['conditions'][] = 'is_single():' . $pageid;
}
}
$config['matchType'] = 'any';
$newfile_name = trim(preg_replace(array('|\s+|is','|[^a-z0-9\-]+|is'), array('-',''), strtolower($conditional['name']))) . '.css';
$errors = $this->CTRL->criticalcss->save_file_contents($newfile_name, $config, $inlinecss);
// remove old critical css file
if (!$errors || empty($errors)) {
@unlink($old_cssfile);
}
}
}
$update_options = true;
}
/**
* Pre 2.7.6 update
*/
if (version_compare($current_version, '2.7.6', '<=')) {
/**
* Remove plugin directory from /uploads/
*/
$dir = wp_upload_dir();
$old_cachepath = trailingslashit($dir['basedir']) . 'abovethefold/';
if (is_dir($old_cachepath)) {
$this->CTRL->rmdir($old_cachepath);
}
}
/**
* Pre 2.8 update
*/
if (version_compare($current_version, '2.8.0', '<')) {
$update_options = true;
$options['pwa'] = false;
$options['manifest_json_update'] = true;
$options['pwa_offline_class'] = true;
$options['pwa_meta'] = true;
$options['html_minify'] = false;
$options['html_comments'] = false;
$options['html_comments_preserve'] = array();
$options['html_search_replace'] = array();
$options['jsdelivery_idle'] = array();
delete_option('abtf-pageoptions');
delete_option('abtf-conditionoptions');
}
/**
* Pre 2.8.5 update
*/
if (version_compare($current_version, '2.8.5', '<')) {
$update_options = true;
if (!isset($options['pwa'])) {
$options['manifest_json_update'] = true;
$options['pwa_meta'] = true;
}
// update new abtf-pwa-policy.json format
if (isset($options['pwa']) && $options['pwa']) {
// delete old config
$old_sw_config = trailingslashit(ABSPATH) . 'abtf-pwa-policy.json';
if (file_exists($old_sw_config)) {
@unlink($old_sw_config);
}
}
}
/**
* Pre 2.8.7 update
*/
if (version_compare($current_version, '2.8.7', '<')) {
// fix invalid default manifest.json
$manifest_file = trailingslashit(ABSPATH) . 'manifest.json';
if (file_exists($manifest_file)) {
$manifest = file_get_contents($manifest_file);
if ($manifest) {
$json = @json_decode($manifest, true);
$updated_json = false;
// fix invalid default start url
if (is_array($json) && isset($json['start_url']) && $json['start_url'] === '.\\/?utm_source=web_app_manifest') {
$json['start_url'] = '/?utm_source=web_app_manifest';
$updated_json = true;
}
if (isset($options['pwa']) && $options['pwa']) {
// fix invalid service worker src
if (is_array($json) && isset($json['serviceworker']) && isset($json['serviceworker']['src']) && $json['serviceworker']['src'] !== '/abtf-pwa.js') {
$json['start_url'] = '/abtf-pwa.js';
$updated_json = true;
}
}
if ($updated_json) {
try {
// PHP 5.3
if (version_compare(phpversion(), '5.4.0', '<')) {
$json = str_replace('\\/', '/', json_encode($json));
} else {
$json = json_encode($json, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
}
file_put_contents($manifest_file, $json);
} catch (Exception $error) {
}
}
}
}
}
/**
* Pre 2.8.8 update
*/
if (version_compare($current_version, '2.8.8', '<')) {
$update_options = true;
if (isset($options['pwa']) && $options['pwa']) {
$options['pwa_manifest_meta'] = true;
}
// convert meta checkbox to HTML input field
if (isset($options['pwa_meta']) && $options['pwa_meta'] === true) {
$meta = array();
$meta[] = '';
if (isset($options['pwa_meta_name']) && $options['pwa_meta_name']) {
$meta[] = '';
}
// theme color
if (isset($options['pwa_meta_theme_color']) && $options['pwa_meta_theme_color']) {
$meta[] = '';
}
// legacy Web App meta
if (isset($options['pwa_legacy_meta']) && $options['pwa_legacy_meta']) {
$meta[] = '';
$meta[] = '';
// start url
if (isset($options['pwa_meta_starturl']) && $options['pwa_meta_starturl']) {
$meta[] = '';
}
// application name
if (isset($options['pwa_meta_name']) && $options['pwa_meta_name']) {
$meta[] = '';
$meta[] = '';
$meta[] = '';
}
// theme color
if (isset($options['pwa_meta_theme_color']) && $options['pwa_meta_theme_color']) {
$meta[] = '';
}
// icons
if (isset($options['pwa_meta_icons']) && is_array($options['pwa_meta_icons'])) {
$sizes = array();
$ms_tile = false;
$max_size = 0;
$max_size_icon = false;
foreach ($options['pwa_meta_icons'] as $icon) {
if (is_array($icon) && isset($icon['sizes'])) {
$size = explode('x', $icon['sizes']);
if (count($size) === 2 && is_numeric($size[0]) && intval($size[0]) > $max_size) {
$max_size = intval($size[0]);
$max_size_icon = $icon;
}
$meta[] = '';
$meta[] = '';
switch ($icon['sizes']) {
case "144x144":
// microsoft
if (!$ms_tile) {
$meta[] = '';
$ms_tile = true;
}
break;
}
} else {
$meta[] = '';
}
}
if ($max_size_icon) {
$meta[] = '';
}
}
}
$options['pwa_meta'] = implode("\n", $meta);
}
}
/**
* Pre 2.8.19 update
*/
if (version_compare($current_version, '2.8.19', '<')) {
if (isset($options['pwa']) && $options['pwa']) {
$update_options = true;
$manifest = trailingslashit(ABSPATH) . 'manifest.json';
if (file_exists($manifest)) {
try {
$manifestjson = json_decode(trim(file_get_contents($manifest)), true);
} catch (Exception $err) {
$manifestjson = false;
}
if ($manifestjson && is_array($manifestjson)) {
// add start url to options for PWA cache
if (isset($manifestjson['start_url'])) {
$options['pwa_manifest_start_url'] = $manifestjson['start_url'];
}
}
}
}
}
// update new abtf-pwa-policy.json format
if (isset($options['pwa']) && $options['pwa']) {
// update service worker
try {
$this->CTRL->pwa->update_sw();
} catch (Exception $error) {
}
// update abtf-pwa-config.json to latest format
try {
$this->CTRL->pwa->update_sw_config();
} catch (Exception $error) {
}
}
// remove old options
$old_options = array(
'dimensions',
'phantomjs_path',
'cleancss_path',
'remove_datauri',
'urls',
'genurls',
'localizejs_enabled',
'conditionalcss_enabled',
'conditional_css',
'pwa_meta_theme_color',
'pwa_legacy_meta',
'pwa_meta_starturl',
'pwa_meta_name',
'pwa_meta_theme_color',
'pwa_meta_icons'
);
foreach ($old_options as $opt) {
if (isset($options[$opt])) {
unset($options[$opt]);
$update_options = true;
}
}
if ($update_options) {
update_option('abovethefold', $options, true);
}
// restore limited offer
update_user_meta(get_current_user_id(), 'abtf_show_offer', 0);
/**
* Clear full page cache
*/
$this->CTRL->plugins->clear_pagecache();
}
}
}