slug = basename( WTWP_PLUGIN_DIR );
$this->_htaccess_path = trailingslashit( ABSPATH ) . '.htaccess';
$this->_web_config_path = trailingslashit( ABSPATH ) . 'web.config';
if ( defined('WP_ADMIN') && WP_ADMIN && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) ) {
$this->hooks();
// Manage our own upgrades
require_once( WTWP_PLUGIN_DIR . '/resources/class.wtwp-upgrader.php');
$plugin_slug = plugin_basename( __FILE__ );
$wtwp_upgrader = new WTWP_Upgrader( $plugin_slug );
}
$this->preview_dns_hooks();
}
/**
* Add all of our admnin hooks
* @return void
*/
public function hooks() {
add_action( 'admin_init', array( $this, 'upgrade' ) );
add_action( 'admin_init', array( $this, 'first_login' ) );
add_action( 'admin_init', array( $this, 'register_settings' ) );
add_action( 'admin_menu' , array( $this, 'admin_menu' ) );
add_action( 'admin_menu', array( $this, 'settings_page' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'load_scripts' ) );
add_action( 'admin_footer', array( $this, 'show_pointer') );
add_filter( 'gd_quick_setup_reactivate_plugins', array( $this, 'reactivate_me' ) );
add_action( 'gd_quicksetup_installed_plugin-welcome-to-wordpress', array( $this, 'restore_options' ) );
}
/**
* Work with the Go Daddy Quick Setup plugin
* @param array $active_plugins
* @return array
*/
public function reactivate_me( $active_plugins ) {
$this->_options_backup = get_option( 'wtwp_options' );
$active_plugins[] = plugin_basename( __FILE__ );
return $active_plugins;
}
/**
* Restore the options after Go Daddy Quick Setup
* has reset the database
*/
public function restore_options() {
update_option( 'wtwp_options', $this->_options_backup );
}
/**
* Upgrade between versions
* @return void
*/
public function upgrade() {
// Get the current version
$version = get_option( 'wtwp_version' );
// Set default options
if ( empty( $version ) || version_compare( $version, '1.0' ) < 0 ) {
update_option( 'wtwp_show_help', 'Y' );
update_option( 'wtwp_use_hardening_rules', '' );
update_option( 'wtwp_version', '1.0' );
update_option( 'wtwp_use_object_cache', '' );
update_option( 'wtwp_use_caching_rules', '' );
$options = array(
'key' => 'uaojhXaIVRbWk2E8zyInIU0ILUXJ9GHOeA3CXODDW',
'first_login' => false,
'plid' => 1592,
'isc' => 'WPHosting1',
'api_url' => 'https://wpqs.secureserver.net/v1/',
'help_url' => 'https://help.securepaynet.net',
'control_panel_url' => 'https://hostingmanager.secureserver.net/Login.aspx',
);
if ( !get_option( 'wtwp_options' ) ) {
update_option( 'wtwp_options', $options );
}
}
}
/**
* Hook into the admin menu
* @return void
*/
public function settings_page() {
add_options_page( __( 'Welcome Plugin', 'welcome-to-wordpress' ), __( 'Welcome Plugin', 'welcome-to-wordpress' ), 'manage_options', $this->slug . '-settings', array( $this, 'plugin_options' ) );
}
/**
* Set options
* @return void
*/
public function plugin_options() {
// Check permissions
if ( !current_user_can( 'manage_options' ) ) {
wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
}
// Show settings page
include_once( WTWP_PLUGIN_DIR . '/resources/settings.php' );
}
/**
* Load jQuery UI
* @return void
*/
public function load_scripts() {
wp_enqueue_script( 'jquery-ui-core' );
}
/**
* Add our menu into the admin menu
* @return void
*/
public function admin_menu() {
if ( 'Y' !== get_option( 'wtwp_show_help' ) ) {
return;
}
add_menu_page( __( 'Welcome', 'welcome-to-wordpress' ), __( 'Welcome', 'welcome-to-wordpress' ), 'manage_options' , $this->slug , array( $this, 'welcome_page' ) , '' , -99999 );
add_submenu_page( $this->slug , __( 'Welcome', 'welcome-to-wordpress' ) , __( 'Welcome', 'welcome-to-wordpress' ), 'manage_options' , $this->slug , array( $this, 'welcome_page' ) );
add_submenu_page( $this->slug , __( 'Help', 'welcome-to-wordpress' ), __( 'Help', 'welcome-to-wordpress' ), 'manage_options' , $this->slug . '-help' , array( $this, 'help_page' ) );
add_submenu_page( $this->slug , __( 'Security', 'welcome-to-wordpress' ), __( 'Security', 'welcome-to-wordpress' ), 'manage_options' , $this->slug . '-security' , array( $this, 'security_page' ) );
add_submenu_page( $this->slug , __( 'Hosting Control Center', 'welcome-to-wordpress' ), __( 'Hosting Control Center', 'welcome-to-wordpress' ), 'manage_options' , $this->slug . '-control-panel' , array( $this, 'control_panel' ) );
}
/**
* Display the welcome page
* @return void
*/
public function welcome_page() {
$label = __( 'Welcome', 'welcome-to-wordpress' );
require_once( WTWP_PLUGIN_DIR . '/resources/header.php' );
require_once( WTWP_PLUGIN_DIR . '/resources/welcome.php' );
require_once( WTWP_PLUGIN_DIR . '/resources/footer.php' );
}
/**
* Display the help page
* @return void
*/
public function help_page() {
$label = __( 'Help', 'welcome-to-wordpress' );
require_once( WTWP_PLUGIN_DIR . '/resources/header.php' );
require_once( WTWP_PLUGIN_DIR . '/resources/help.php' );
require_once( WTWP_PLUGIN_DIR . '/resources/footer.php' );
}
/**
* Display the security page
* @return void
*/
public function security_page() {
$label = __( 'Security', 'welcome-to-wordpress' );
require_once( WTWP_PLUGIN_DIR . '/resources/header.php' );
require_once( WTWP_PLUGIN_DIR . '/resources/security.php' );
require_once( WTWP_PLUGIN_DIR . '/resources/footer.php' );
}
/**
* Open the host's control panel
* @return void
*/
public function control_panel () {
$label = __( 'Hosting Control Center', 'welcome-to-wordpress' );
require_once( WTWP_PLUGIN_DIR . '/resources/header.php' );
require_once( WTWP_PLUGIN_DIR . '/resources/control-panel.php' );
require_once( WTWP_PLUGIN_DIR . '/resources/footer.php' );
}
public function register_settings() {
$_section = 'wtwp_settings_main';
$group = 'wtwp_settings_group';
add_settings_section( $_section, __( 'Settings', 'welcome-to-wordpress' ), '__return_null', $this->slug . '-settings' );
add_settings_field(
$id = 'wtwp_use_hardening_rules',
$title = __( 'Secure .htaccess rules', 'welcome-to-wordpress' ),
$callback = array( $this, 'show_secure_htaccess_field' ),
$page = $this->slug . '-settings',
$section = $_section
);
register_setting( $option_group = $group, $option_name = $id, array( $this, 'save_secure_htaccess_field' ) );
add_settings_field(
$id = 'wtwp_use_caching_rules',
$title = __( 'Browser caching rules', 'welcome-to-wordpress' ),
$callback = array( $this, 'show_browser_caching_field' ),
$page = $this->slug . '-settings',
$section = $_section
);
register_setting( $option_group = $group, $option_name = $id, array( $this, 'save_browser_caching_field' ) );
add_settings_field(
$id = 'wtwp_use_object_cache',
$title = __( 'Object cache', 'welcome-to-wordpress' ),
$callback = array( $this, 'show_object_cache_field' ),
$page = $this->slug . '-settings',
$section = $_section
);
register_setting( $option_group = $group, $option_name = $id, array( $this, 'save_object_cache_field' ) );
add_settings_field(
$id = 'wtwp_show_help',
$title = __( 'Show help', 'welcome-to-wordpress' ),
$callback = array( $this, 'show_help_field' ),
$page = $this->slug . '-settings',
$section = $_section
);
register_setting( $option_group = $group, $option_name = $id, array( $this, 'save_help_field' ) );
}
/**
* Check if it's the admin's first login.
* If so, set up W3 Total Cache and flag so this function doesn't run again.
* @return void
*/
public function first_login() {
$options = get_option( 'wtwp_options' );
if ( empty( $options['first_login'] ) ) {
// Set the first_login flag so this code doesn't run again
$options['first_login'] = time();
update_option( 'wtwp_options', $options );
$this->load_environment_settings();
wp_redirect( get_admin_url() );
exit();
}
}
/**
* Load environment optimizations
* @return void
*/
public function load_environment_settings() {
global $is_iis7, $is_apache;
// Update the htaccess rules
if ( $is_apache ) {
$this->_apply_htaccess_caching();
$this->_apply_htaccess_security();
}
// Otherwise, add windows config options
elseif ( version_compare( PHP_VERSION, '5.3.0' ) >= 0 && $is_iis7 && extension_loaded( 'wincache' ) && function_exists( 'wincache_ucache_add' ) ) {
// Enable wincache's opcode cache
$this->_enable_wincache_ocache();
}
// Add in web.config optimizations
if ( $is_iis7 ) {
$this->_apply_web_config_caching();
}
}
/**
* Show a pointer that highlights the Welcome plugin
*/
public function show_pointer() {
// Dismiss any pointers from the query string
if ( isset( $_REQUEST['clear_pointer'] ) && !empty( $_REQUEST['clear_pointer'] ) ) {
$dismissed = array_filter( explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) ) );
if ( !in_array( $_REQUEST['clear_pointer'], $dismissed ) ) {
$dismissed[] = $_REQUEST['clear_pointer'];
$dismissed = implode( ',', $dismissed );
update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $dismissed );
}
}
// Show any pointers we have that aren't already dismissed
$dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
$options = get_option( 'wtwp_options' );
if ( $options['first_login'] && !in_array( 'wtwp-intro-pointer', $dismissed ) ) {
wp_enqueue_script( 'wp-pointer' );
wp_enqueue_style( 'wp-pointer' );
include_once( WTWP_PLUGIN_DIR . '/resources/pointer.php' );
}
}
/**
* Clean up
*/
public function deactivate() {
global $is_apache, $is_iis7;
// Remove config changes
if ( $is_apache ) {
$this->_remove_htaccess_caching();
$this->_remove_htaccess_security();
} elseif ( $is_iis7 ) {
$this->_rollback_web_config();
}
// Remove object cache
$this->_remove_object_cache();
// Disable wincache's opcode cache
$this->_disable_wincache_ocache();
}
/**************************************************************************/
/** .htaccess methods
/**************************************************************************/
/**
* Add caching rules to .htaccess
* @return void
*/
protected function _apply_htaccess_caching() {
if ( !insert_with_markers( $this->_htaccess_path, 'wtwp_cache', $this->parse_htaccess( trailingslashit( WTWP_PLUGIN_DIR ) . 'resources/htaccess/wtwp_cache.txt' ) ) ) {
return new WP_Error( 'generic', sprintf( __( 'Failed to update %s', 'welcome-to-wordpress' ), $this->_htaccess_path ) );
}
return true;
}
/**
* Add security rules to .htaccess
* @return void
*/
protected function _apply_htaccess_security() {
if ( !insert_with_markers( $this->_htaccess_path, 'wtwp_security', $this->parse_htaccess( trailingslashit( WTWP_PLUGIN_DIR ) . 'resources/htaccess/wtwp_security.txt' ) ) ) {
return new WP_Error( 'generic', sprintf( __( 'Failed to update %s', 'welcome-to-wordpress' ), $this->_htaccess_path ) );
}
return true;
}
/**
* Remove caching rules from .htaccess
* @return void
*/
protected function _remove_htaccess_caching() {
if ( !insert_with_markers( $this->_htaccess_path, 'wtwp_cache', array() ) ) {
return new WP_Error( 'generic', sprintf( __( 'Failed to update %s', 'welcome-to-wordpress' ), $this->_htaccess_path ) );
}
return true;
}
/**
* Remove security rules from .htaccess
* @return void
*/
protected function _remove_htaccess_security() {
if ( !insert_with_markers( $this->_htaccess_path, 'wtwp_security', array() ) ) {
return new WP_Error( 'generic', sprintf( __( 'Failed to update %s', 'welcome-to-wordpress' ), $this->_htaccess_path ) );
}
return true;
}
/**
* Customize our local .htaccess rules
* @param strin $filename
* @return array
*/
public function parse_htaccess( $filename ) {
if ( !file_exists( $filename ) ) {
return array();
}
$lines = file( $filename, FILE_IGNORE_NEW_LINES );
array_shift( $lines ); // remove copyright notice
foreach ( $lines as &$line ) {
$line = str_replace(
array( '$$HOME_PATH$$' ),
array( trailingslashit( parse_url( home_url(), PHP_URL_PATH ) ) ),
$line );
}
return $lines;
}
/**************************************************************************/
/** web.config methods
/**************************************************************************/
/**
* Add caching rules to web.config
* @return void
*/
protected function _apply_web_config_caching() {
if ( !file_exists( $this->_web_config_path ) ) {
@touch( $this->_web_config_path );
}
if ( !file_exists( $this->_web_config_path ) || !win_is_writable( $this->_web_config_path ) ) {
return new WP_Error( 'generic', sprintf( __( 'Failed to update %s', 'welcome-to-wordpress' ), $this->_web_config_path ) );
}
$flag = $this->_merge_xml( $this->_web_config_path, trailingslashit( WTWP_PLUGIN_DIR ) . 'resources/web.config/browser_caching.xml' );
$flag = $flag & $this->_merge_xml( $this->_web_config_path, trailingslashit( WTWP_PLUGIN_DIR ) . 'resources/web.config/compression.xml' );
$flag = $flag & $this->_merge_xml( $this->_web_config_path, trailingslashit( WTWP_PLUGIN_DIR ) . 'resources/web.config/iis_caching.xml' );
if ( !$flag ) {
return new WP_Error( 'generic', sprintf( __( 'Failed to update %s', 'welcome-to-wordpress' ), $this->_web_config_path ) );
}
return true;
}
/**
* Rollback *all* web.config settings
* This removes the specific xpaths we added.
* Unmerging XML docs is ugly and complex. We don't have the ability to ermove "chunks"
* like in the .htaccess files. It's all or nothing.
* @return void
*/
protected function _rollback_web_config() {
if ( !file_exists( $this->_web_config_path ) ) {
return true;
}
if ( file_exists( $this->_web_config_path) && !win_is_writable( $this->_web_config_path ) ) {
return false;
}
// Get the parent doc
libxml_use_internal_errors( true );
$DOMParent = new DOMDocument();
$DOMParent->formatOutput = true;
try {
$DOMParent->load( $this->_web_config_path );
} catch ( Exception $e ) {
return false;
}
// Remove any matching nodes in the parent
$xpath = new DOMXPath( $DOMParent );
$paths = array(
"//*/caching/profiles/add[@duration='00:01:00']",
"//*/urlCompression[@doDynamicCompression='true']",
"//*/clientCache[@cacheControlMaxAge='14.00:00:00']"
);
foreach ( $paths as $path ) {
$query = $xpath->query( $path );
if ( $query->length > 0 ) {
for ( $i = 0 ; $i < $query->length ; $i++ ) {
$query->item( $i )->parentNode->removeChild( $query->item( $i ) );
}
}
}
// Remove empty nodes
$paths = array(
"//configuration/system.webServer/caching/profiles",
"//configuration/system.webServer/caching",
"//configuration/system.webServer/staticContent",
"//configuration/system.webServer",
"//configuration"
);
foreach ( $paths as $path ) {
$query = $xpath->query( $path );
if ( $query->length > 0 ) {
for ( $i = 0 ; $i < $query->length ; $i++ ) {
$node = $query->item( $i );
$nodeHasEmptyText = true;
for ( $i = 0 ; $i < $node->childNodes->length ; $i++ ) {
if ( ! ( $node->childNodes->item( $i ) instanceof DOMText ) || '' !== trim( $node->childNodes->item( $i )->nodeValue ) ) {
$nodeHasEmptyText = false;
break;
}
}
if ( !$node->hasAttributes() && ( !$node->hasChildNodes() || $nodeHasEmptyText ) ) {
$node->parentNode->removeChild( $node );
}
}
}
}
// If there is no root element, then save a dummy web.config
if ( !$DOMParent->hasChildNodes() ) {
if ( 0 === @file_put_contents( $this->_web_config_path, '<' . '?xml version="1.0"?' . ">\n