first commit

This commit is contained in:
User A0264400
2026-04-01 23:20:16 +03:00
commit a766acdc90
23071 changed files with 4933189 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
<?php
/**
* Подключение файлов из категории 3rd-party
*
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @copyright (c) 20.01.2021, CreativeMotion
* @version 1.0
*/
add_filter('wbcr_factory_480_form_items', function ($forms_groups, $name) {
require_once(WCL_PLUGIN_DIR . '/includes/classes/3rd-party/class-base.php');
require_once(WCL_PLUGIN_DIR . '/includes/classes/3rd-party/plugins/class-wp-rocket.php');
require_once(WCL_PLUGIN_DIR . '/includes/classes/3rd-party/class-form-entity.php');
$form_entities = \Clearfy\ThirdParty\Form_Entity::recursive_search_controls($forms_groups);
if( !empty($form_entities) ) {
foreach($form_entities as $control) {
$wp_rocket_no_conflict = new \Clearfy\ThirdParty\Wp_Rocket();
if( $wp_rocket_no_conflict->is_enabled_mapped_option($control->get_name()) ) {
$control->make_control_disabled();
$control->modify_control_hint(__('WARNING! You cannot enable this option as you are using a similar option in the wp rocket plugin. Using the same functionality in both plugins can lead to conflicts. To enable this option, you must disable a similar option in the wp rocket plugin.', 'clearfy'));
}
}
}
return $forms_groups;
}, 10, 2);

View File

@@ -0,0 +1,104 @@
<?php
/**
* Базовый класс для реализации совместимости со сторонними плагинами
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @copyright (c) 12.01.2021, CreativeMotion
* @version 1.0
*/
namespace Clearfy\ThirdParty;
// Exit if accessed directly
if( !defined('ABSPATH') ) {
exit;
}
abstract class Base {
protected $map_options = [];
protected $defualt_disabled_options = [];
private $_disabled_clearfy_options = [];
/**
* Получить значение опции конфликтующего плагина
* @param string $option_name Имя опции
* @return mixed
*/
public abstract function get_3rd_plugin_option($option_name);
public function is_clearfy_option_mapped($option_name)
{
return isset($this->map_options[$option_name]);
}
public function is_3rd_plugin_option_mapped($option_name)
{
return in_array($option_name, $this->map_options);
}
public function is_enabled_mapped_option($option_name)
{
if( $this->is_clearfy_option_mapped($option_name) ) {
return $this->is_enabled_3rd_plugin_option($this->map_options[$option_name]);
}
return in_array($option_name, (array)$this->defualt_disabled_options);
}
public function is_enabled_clearfy_option($option_name)
{
return \WCL_Plugin::app()->getPopulateOption($option_name);
}
/**
* Включена ли опция конфликтующего плагина?
* @param string $option_name Имя опции
* @return bool - true, если включена, false если нет
*/
public function is_enabled_3rd_plugin_option($option_name)
{
$option_value = $this->get_3rd_plugin_option($option_name);
return !is_null($option_value) && $option_value;
}
/**
* Деактивирует опции в клеарфи, соответствующие карте опций
*
* Если к примеру в wp rocket включена опции минификации скриптов, то соотвественно
* в Clearfy мы деактивируем опцию минификации скриптов.
*/
public function disable_clearfy_options()
{
if( !empty($this->map_options) ) {
foreach((array)$this->map_options as $clearfy_option_name => $thirdparty_plugin_option_name) {
if( $this->is_enabled_clearfy_option($clearfy_option_name) && $this->is_enabled_3rd_plugin_option($thirdparty_plugin_option_name) ) {
$this->disable_clearfy_option($clearfy_option_name);
}
}
}
if( !empty($this->defualt_disabled_options) ) {
foreach((array)$this->defualt_disabled_options as $option_name) {
if( $this->is_enabled_clearfy_option($clearfy_option_name) ) {
$this->disable_clearfy_option($option_name);
}
}
}
$this->save_options();
}
private function disable_clearfy_option($option_name)
{
$this->_disabled_clearfy_options[] = $option_name;
}
private function save_options()
{
foreach($this->_disabled_clearfy_options as $option_name) {
\WCL_Plugin::app()->updatePopulateOption($option_name, 0);
}
}
}

View File

@@ -0,0 +1,103 @@
<?php
/**
* Базовый класс для реализации совместимости со сторонними плагинами
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @copyright (c) 12.01.2021, CreativeMotion
* @version 1.0
*/
namespace Clearfy\ThirdParty;
// Exit if accessed directly
if( !defined('ABSPATH') ) {
exit;
}
class Form_Entity {
private $control = [];
public function __construct(array &$control)
{
$this->control = &$control;
}
/**
* Extracted options from a nested array
* @param array $options
* @return array
* @since 2.2.0
*/
public static function recursive_search_controls(&$options)
{
$extracted_options = [];
foreach($options as &$option) {
if( isset($option['items']) ) {
$extracted_options = array_merge($extracted_options, static::recursive_search_controls($option['items']));
} else {
if( static::is_control($option) ) {
$extracted_options[] = new static($option);
}
}
}
return $extracted_options;
}
public function get_name()
{
if( !isset($this->control['name']) ) {
return null;
}
return $this->control['name'];
}
protected static function is_control(array $item)
{
return isset($item['type']) && isset(\Wbcr_FactoryForms480_Manager::$registered_controls[$item['type']]);
}
/**
* Returns true if a given item is an control holder item.
*
* @param mixed[] $item
* @return bool
* @since 1.0.0
*/
protected static function is_control_holder(array $item)
{
return isset($item['type']) && isset(\Wbcr_FactoryForms480_Manager::$registered_holders[$item['type']]);
}
/**
* Returns true if a given item is html markup.
*
* @param mixed[] $item
* @return bool
* @since 1.0.0
*/
protected static function is_custom_element(array $item)
{
return isset($item['type']) && isset(\Wbcr_FactoryForms480_Manager::$registered_custom_elements[$item['type']]);
}
public function make_control_disabled()
{
$this->control['cssClass'] = ['factory-checkbox-disabled disabled'];
}
public function modify_control_hint($message)
{
unset($this->control['layout']['hint-type']);
unset($this->control['layout']['hint-icon-color']);
$this->control['layout']['column-left'] = '4';
$this->control['layout']['column-right'] = '8';
$old_hint = !empty($this->control['hint']) ? $this->control['hint'] . "<br><br>" : "";
$this->control['hint'] = $old_hint . '<span style="display:block; font-size:12px; color:#d48a6f;">' . $message . '</span>';
}
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* Thirdparty Forms
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @copyright (c) 12.01.2021, CreativeMotion
* @version 1.0
*/
namespace Clearfy\ThirdParty;
// Exit if accessed directly
if( !defined('ABSPATH') ) {
exit;
}
final class Wp_Rocket extends Base {
private $wp_rocket_options;
protected $defualt_disabled_options = [
'disable_emoji',
'remove_js_version',
'remove_style_version',
//todo: Starting WP Rocket V 3.7 (August 2020), HTML Minify has been removed.
//'html_optimize',
'move_js_to_footer',
'dont_move_jquery_to_footer'
];
protected $map_options = [
'css_optimize' => 'minify_css',
'js_optimize' => 'minify_js',
'ajs_enabled' => 'defer_all_js',
'disable_embeds' => 'embeds'
];
public function __construct()
{
$this->wp_rocket_options = get_option('wp_rocket_settings');
}
public function get_3rd_plugin_option($option_name)
{
return isset($this->wp_rocket_options[$option_name]) ? $this->wp_rocket_options[$option_name] : null;
}
}

View File

@@ -0,0 +1,148 @@
<?php
/**
* This class configures the parameters advanced
* @author Webcraftic <wordpress.webraftic@gmail.com>
* @copyright (c) 2017 Webraftic Ltd
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class WCL_ConfigAdvanced extends WBCR\Factory_Templates_134\Configurate {
/**
* @param WCL_Plugin $plugin
*/
public function __construct( WCL_Plugin $plugin ) {
parent::__construct( $plugin );
$this->plugin = $plugin;
}
public function registerActionsAndFilters() {
if ( $this->getPopulateOption( 'disable_heartbeat' ) && $this->getPopulateOption( 'disable_heartbeat' ) != 'default' ) {
add_action( 'init', array( $this, 'disableHeartbeat' ), 1 );
}
if ( $this->getPopulateOption( 'heartbeat_frequency' ) && $this->getPopulateOption( 'heartbeat_frequency' ) != 'default' ) {
add_filter( 'heartbeat_settings', array( $this, 'clearfyHeartbeatFrequency' ) );
}
//============================================================
// ADMINBAR MANAGER COMPONENT
//============================================================
if ( $this->plugin->isActivateComponent( 'adminbar_manager' ) && is_user_logged_in() ) {
if ( $this->getPopulateOption( 'disable_admin_bar' ) == 'for_all_users' ) {
add_filter( 'show_admin_bar', '__return_false', 999999 );
}
if ( $this->getPopulateOption( 'disable_admin_bar' ) == 'for_all_users_except_administrator' ) {
add_filter( 'show_admin_bar', array( $this, 'removeFunctionAdminBar' ) );
}
}
//============================================================
// WIDGETS TOOLS COMPONENT
//============================================================
if ( $this->plugin->isActivateComponent( 'widget_tools' ) ) {
add_action( 'widgets_init', array( $this, 'unregisterDefaultWidgets' ), 11 );
}
}
// unregister all widgets
public function unregisterDefaultWidgets() {
if ( $this->getPopulateOption( 'remove_unneeded_widget_page' ) ) {
unregister_widget( 'WP_Widget_Pages' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_calendar' ) ) {
unregister_widget( 'WP_Widget_Calendar' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_tag_cloud' ) ) {
unregister_widget( 'WP_Widget_Tag_Cloud' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_archives' ) ) {
unregister_widget( 'WP_Widget_Archives' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_links' ) ) {
unregister_widget( 'WP_Widget_Links' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_meta' ) ) {
unregister_widget( 'WP_Widget_Meta' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_search' ) ) {
unregister_widget( 'WP_Widget_Search' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_text' ) ) {
unregister_widget( 'WP_Widget_Text' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_categories' ) ) {
unregister_widget( 'WP_Widget_Categories' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_recent_posts' ) ) {
unregister_widget( 'WP_Widget_Recent_Posts' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_recent_comments' ) ) {
unregister_widget( 'WP_Widget_Recent_Comments' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_rss' ) ) {
unregister_widget( 'WP_Widget_RSS' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_menu' ) ) {
unregister_widget( 'WP_Nav_Menu_Widget' );
}
if ( $this->getPopulateOption( 'remove_unneeded_widget_twenty_eleven_ephemera' ) ) {
unregister_widget( 'Twenty_Eleven_Ephemera_Widget' );
}
}
/**
* Revisions limit
*
* @since 0.9.5
*/
public function clearfyHeartbeatFrequency( $settings ) {
if ( 0 < (int) $this->getPopulateOption( 'heartbeat_frequency' ) ) {
$settings['interval'] = (int) $this->getPopulateOption( 'heartbeat_frequency' );
}
return $settings;
}
public function disableHeartbeat() {
switch ( $this->getPopulateOption( 'disable_heartbeat' ) ) {
case 'everywhere':
wp_deregister_script( 'heartbeat' );
break;
case 'allow_only_on_post_edit_pages':
global $pagenow;
if ( $pagenow != 'post.php' && $pagenow != 'post-new.php' ) {
wp_deregister_script( 'heartbeat' );
}
break;
case 'on_dashboard_page':
if ( is_admin() ) {
wp_deregister_script( 'heartbeat' );
}
break;
}
}
/**
* @param $content
*
* @return bool
*/
public function removeFunctionAdminBar( $content ) {
return ( current_user_can( 'administrator' ) ) ? $content : false;
}
}

View File

@@ -0,0 +1,368 @@
<?php
/**
* This class configures the google performance settings
*
* @author Webcraftic <wordpress.webraftic@gmail.com>
* @copyright (c) 2017 Webraftic Ltd
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class WCL_ConfigGooglePerformance extends WBCR\Factory_Templates_134\Configurate {
/**
* @param WCL_Plugin $plugin
*/
public function __construct( WCL_Plugin $plugin ) {
parent::__construct( $plugin );
$this->plugin = $plugin;
}
public function registerActionsAndFilters() {
if ( $this->getPopulateOption( 'disable_google_fonts' ) ) {
add_action( 'wp_enqueue_scripts', [ $this, 'disableAllGoogleFonts' ], 999 );
}
if ( ! is_admin() ) {
$load_google_fonts = $this->getPopulateOption( 'lazy_load_google_fonts' );
$load_font_awesome = $this->getPopulateOption( 'lazy_load_font_awesome' );
if ( $load_google_fonts || $load_font_awesome ) {
add_action( 'wp_print_styles', [ $this, 'enqueueScripts' ], - 1 );
}
if ( $this->getPopulateOption( 'disable_google_maps' ) ) {
add_action( "wp_loaded", [ $this, 'disableGoogleMapsObStart' ] );
}
}
}
/** ======================================================================== */
// Disable google maps
/** ======================================================================== */
public function disableGoogleMapsObStart() {
ob_start( [ $this, 'disableGoogleMapsObEnd' ] );
}
/**
* @param string $html
*
* @return mixed
*/
public function disableGoogleMapsObEnd( $html ) {
global $post;
$exclude_ids = [];
$exclude_from_disable_google_maps = $this->getPopulateOption( 'exclude_from_disable_google_maps' );
if ( '' !== $exclude_from_disable_google_maps ) {
$exclude_ids = array_map( 'intval', explode( ',', $exclude_from_disable_google_maps ) );
}
if ( $post && ! in_array( $post->ID, $exclude_ids, true ) ) {
$html = preg_replace( '/<script[^<>]*\/\/maps.(googleapis|google|gstatic).com\/[^<>]*><\/script>/i', '', $html );
if ( $this->getPopulateOption( 'remove_iframe_google_maps' ) ) {
$html = preg_replace( '/<iframe[^<>]*\/\/(www\.)?google\.com(\.\w*)?\/maps\/[^<>]*><\/iframe>/i', '', $html );
}
}
return $html;
}
/** ======================================================================== */
// End disable google maps
/** ======================================================================== */
public function disableAllGoogleFonts() {
global $wp_styles;
// multiple patterns hook
$regex = '/fonts\.googleapis\.com\/css\?family/i';
if ( ! empty( $wp_styles->registered ) && is_array( $wp_styles->registered ) ) {
foreach ( $wp_styles->registered as $registered ) {
if ( preg_match( $regex, $registered->src ) ) {
wp_dequeue_style( $registered->handle );
}
}
}
}
/** ======================================================================== */
// Lazy load fonts
/** ======================================================================== */
public function enqueueScripts() {
$async_links = $this->checkGooglefontsFontawesomeStyles();
if ( ! empty( $async_links ) ) {
wp_enqueue_script( $this->plugin->getPluginName() . '-css-lazy-load', WCL_PLUGIN_URL . '/assets/js/css-lazy-load.min.js', [ 'jquery' ], $this->plugin->getPluginVersion() );
wp_localize_script( $this->plugin->getPluginName() . '-css-lazy-load', 'wbcr_clearfy_async_links', $async_links );
}
}
private function checkGooglefontsFontawesomeStyles() {
global $wp_styles;
$ret = [];
if ( isset( $wp_styles ) && ! empty( $wp_styles ) ) {
$load_google_fonts = $this->getPopulateOption( 'lazy_load_google_fonts', false );
$load_font_awesome = $this->getPopulateOption( 'lazy_load_font_awesome', false );
if ( $load_google_fonts || $load_font_awesome ) {
$gfonts_base_url = 'fonts.googleapis.com/css';
$gfonts_links = [];
$font_awesome_slug = 'font-awesome';
$font_awesome_slug_alt = 'fontawesome';
$font_awesome_links = [
'external' => [],
'internal' => [],
];
foreach ( $wp_styles->queue as $handle ) {
if ( ! isset( $wp_styles->registered[ $handle ] ) ) {
continue;
}
$style = $wp_styles->registered[ $handle ];
$style_src = isset( $style ) ? $style->src : null;
$style_ver = isset( $style ) ? $style->ver : false;
if ( $load_google_fonts && false !== strpos( $style_src, $gfonts_base_url ) ) {
$gfonts_links[] = urldecode( str_replace( [ '&amp;' ], [ '&' ], $style_src ) );
wp_dequeue_style( $handle );
} else if ( $load_font_awesome && ( false !== strpos( $style_src, $font_awesome_slug ) || false !== strpos( $style_src, $font_awesome_slug_alt ) ) ) {
wp_dequeue_style( $handle );
$font_awesome_links[ false !== strpos( $style_src, site_url() ) ? 'internal' : 'external' ][] = [
'ver' => $style_ver,
'link' => $style_src,
];
}
}
if ( $load_font_awesome && ( ! empty( $font_awesome_links['internal'] ) || ! empty( $font_awesome_links['external'] ) ) ) {
// @note: Prioritize external links.
$fa_links = ! empty( $font_awesome_links['external'] ) ? $font_awesome_links['external'] : $font_awesome_links['internal'];
$selected_fa_link = $fa_links[0];
$links_count = count( $fa_links );
if ( 1 < $links_count ) {
for ( $i = 1; $i < $links_count; $i ++ ) {
if ( false !== $fa_links[ $i ]['ver'] && ( false === $selected_fa_link['ver'] || version_compare( $selected_fa_link['ver'], $fa_links[ $i ]['ver'], '<' ) ) ) {
$selected_fa_link = $fa_links[ $i ];
}
}
}
$ret[ $this->plugin->getPluginName() . '-font-awesome' ] = esc_url( $selected_fa_link['link'] );
$this->updateSavedFontAwesomeRequests( count( $font_awesome_links['internal'] ) + count( $font_awesome_links['external'] ) );
} else {
$this->updateSavedFontAwesomeRequests( 0 );
}
if ( $load_google_fonts && ! empty( $gfonts_links ) ) {
$ret[ $this->plugin->getPluginName() . '-google-fonts' ] = esc_url( $this->combineGoogleFontsLinks( $gfonts_links ) );
$this->updateSavedGoogleFontsRequest( count( $gfonts_links ) );
} else {
$this->updateSavedGoogleFontsRequest( 0 );
}
} else {
$this->updateSavedFontAwesomeRequests( 0 );
$this->updateSavedGoogleFontsRequest( 0 );
}
}
return $ret;
}
private function updateSavedGoogleFontsRequest( $count ) {
$count = ! isset( $count ) ? 0 : (int) $count;
$old_val = $this->getPopulateOption( 'combined_font_awesome_requests_number' );
if ( false === $old_val || ( false !== $old_val && $count > (int) $old_val ) ) {
$this->updatePopulateOption( 'combined_font_awesome_requests_number', $count );
}
}
private function updateSavedFontAwesomeRequests( $count ) {
$count = ! isset( $count ) ? 0 : (int) $count;
$old_val = $this->getPopulateOption( 'combined_google_fonts_requests_number' );
if ( false === $old_val || ( false !== $old_val && $count > (int) $old_val ) ) {
$this->updatePopulateOption( 'combined_google_fonts_requests_number', $count );
}
}
public static function saved_external_requests() {
$google_fonts = (int) WCL_Plugin::app()->getPopulateOption( 'combined_google_fonts_requests_number' );
$font_awesome = (int) WCL_Plugin::app()->getPopulateOption( 'combined_font_awesome_requests_number' );
$google_fonts_saved = 1 < $google_fonts ? $google_fonts - 1 : 0;
$font_awesome_saved = 1 < $font_awesome ? $font_awesome - 1 : 0;
return $google_fonts_saved + $font_awesome_saved;
}
/**
* Combine multiple Google Fonts links into one.
*
* @param array $links An array of the different Google Fonts links. Default array().
*
* @return string|array The compined Google Fonts link.
*/
private function combineGoogleFontsLinks( $links = [] ) {
if ( ! is_array( $links ) ) {
return $links;
}
$links = array_unique( $links );
if ( 1 === count( $links ) ) {
return $links[0];
}
$protocol = 'https';
$base_url = '//fonts.googleapis.com/css';
$family_arg = 'family';
$subset_arg = 'subset';
$base_url_len = strlen( $base_url );
$family_arg_len = strlen( $family_arg );
$fonts = [];
$cnt = 0;
$clean_links = [];
foreach ( $links as $k => $v ) {
$base_url_pos = strrpos( $v, $base_url );
$args_str = trim( substr( $v, ( $base_url_len + $base_url_pos ), strlen( $v ) ) );
if ( substr( $args_str, 0, $family_arg_len + 2 ) === '?' . $family_arg . '=' ) {
$args_str = substr( $args_str, $family_arg_len + 2, strlen( $args_str ) );
}
$tmp = explode( '|', $args_str );
$tmp_count = count( $tmp );
for ( $i = 0; $i < $tmp_count; $i ++ ) {
$clean_links[] = $tmp[ $i ];
}
}
foreach ( $clean_links as $k => $v ) {
$expl = explode( '&' . $subset_arg, $v );
if ( isset( $expl[0] ) && ! empty( $expl[0] ) ) {
$tmp = explode( ':', $expl[0] );
if ( isset( $tmp[0] ) && ! empty( $tmp[0] ) ) {
// Has font family name.
$font_name = str_replace( ' ', '+', $tmp[0] );
if ( ! isset( $fonts[ $font_name ] ) ) {
$fonts[ $font_name ] = [
'sizes' => [],
'subsets' => [],
];
}
if ( isset( $tmp[1] ) && ! empty( $tmp[1] ) ) {
// Has font sizes.
$x = explode( ',', $tmp[1] );
$xc = count( $x );
foreach ( $x as $xk => $xv ) {
if ( ! in_array( $xv, $fonts[ $font_name ]['sizes'], true ) && ( 400 !== (int) $xv || $xc > 1 ) ) {
$fonts[ $font_name ]['sizes'][] = $xv;
}
}
}
if ( isset( $expl[1] ) && ! empty( $expl[1] ) ) {
// Has subsets.
$y = explode( ',', $expl[1] );
$yc = count( $y );
foreach ( $y as $yk => $yv ) {
if ( '=' === substr( $yv, 0, 1 ) ) {
$yv = substr( $yv, 1, strlen( $yv ) );
}
if ( ! in_array( $yv, $fonts[ $font_name ]['subsets'], true ) && ( 'latin' !== $yv || $yc > 1 ) ) {
$fonts[ $font_name ]['subsets'][] = $yv;
}
}
}
}// End if().
}// End if().
}// End foreach().
$ret = '';
if ( ! empty( $fonts ) ) {
$ret .= $protocol . ':' . $base_url;
$i = 0;
$subsets = [];
foreach ( $fonts as $key => $val ) {
if ( 0 === $i ) {
$ret .= '?' . $family_arg . '=';
} else {
$ret .= '|';
}
$ret .= $key;
if ( ! empty( $val['sizes'] ) ) {
$ret .= ':' . implode( ',', $val['sizes'] );
}
if ( ! empty( $val['subsets'] ) ) {
$subsets = array_merge( $subsets, $val['subsets'] );
}
$i ++;
}
if ( ! empty( $subsets ) ) {
$ret .= '&' . $subset_arg . '=' . implode( ',', $subsets );
}
}
return $ret;
}
/** ======================================================================== */
// End Lazy load fonts
/** ======================================================================== */
}

View File

@@ -0,0 +1,576 @@
<?php
/**
* This class configures the code cleanup settings
*
* @author Webcraftic <wordpress.webraftic@gmail.com>
* @copyright (c) 2017 Webraftic Ltd
* @version 1.0
*/
// Exit if accessed directly
if( !defined('ABSPATH') ) {
exit;
}
class WCL_ConfigPerformance extends WBCR\Factory_Templates_134\Configurate {
/**
* @param WCL_Plugin $plugin
*/
public function __construct(WCL_Plugin $plugin)
{
parent::__construct($plugin);
$this->plugin = $plugin;
}
public function registerActionsAndFilters()
{
if( $this->getPopulateOption('disable_emoji') ) {
add_action('init', [$this, 'disableEmojis']);
}
if( $this->getPopulateOption('disable_embeds') ) {
add_action('init', [$this, 'disableEmbeds']);
}
if( ($this->getPopulateOption('revision_limit') || $this->getPopulateOption('revisions_disable')) ) {
add_filter('wp_revisions_to_keep', [$this, 'revisions_to_keep'], 10, 2);
if( $this->getPopulateOption('revisions_disable') ) {
add_action('admin_init', [$this, 'disable_revision_support']);
}
}
if( !is_admin() ) {
if( $this->getPopulateOption('remove_jquery_migrate') ) {
add_filter('wp_default_scripts', [$this, 'removeJqueryMigrate']);
}
if( $this->getPopulateOption('disable_feed') ) {
$this->disableFeed();
}
if( $this->getPopulateOption('disable_dashicons') ) {
add_action('wp_print_styles', [$this, 'disableDashicons'], -1);
}
if( $this->getPopulateOption('remove_xfn_link') ) {
add_action('wp_loaded', [$this, 'htmlCompressor']);
}
if( $this->getPopulateOption('remove_recent_comments_style') ) {
add_action('widgets_init', [$this, 'removeRecentCommentsStyle']);
}
$this->remove_tags_from_head();
} else {
if( $this->getPopulateOption('disable_post_autosave') ) {
add_action('wp_print_scripts', [$this, 'disable_posts_autosave']);
}
}
if( $this->getPopulateOption('gutenberg_autosave_control') ) {
add_action('admin_init', [$this, 'register_gutenberg_autosave_settings']);
add_action('rest_api_init', [$this, 'gutenberg_autosave_rest_mapping']);
add_action('enqueue_block_editor_assets', [$this, 'enqueue_gutenberg_autosave_assets']);
}
}
/**
* Gutenberg assets.
*/
public function enqueue_gutenberg_autosave_assets()
{
/**
* Styles.
*/
wp_enqueue_style('wbcr-clearfy-gutenberg-autosave', WCL_PLUGIN_URL . '/admin/assets/css/gutenberg-autosave-control.css', [], $this->plugin->getPluginVersion(), 'all');
/**
* Scripts.
*/
wp_enqueue_script('wbcr-clearfy-gutenberg-autosave', WCL_PLUGIN_URL . '/admin/assets/gutenberg/build/index.build.js', [
'react',
'wp-api-fetch',
'wp-components',
'wp-compose',
'wp-data',
'wp-edit-post',
'wp-i18n',
'wp-plugins',
], $this->plugin->getPluginVersion(), true);
// todo: It is necessary to cteate the localization for the Gutenberg widget, which is responsible for the selection of AutoSave intveraval.
}
/**
* Register settings for Gutenberg
*/
public function register_gutenberg_autosave_settings()
{
register_setting('clearfy-gutenberg-autosave', $this->plugin->getPrefix() . 'autosave_interval', ['default' => 99999]);
}
/**
* Get interval option.
*
* @return int
*/
public function get_gutenberg_autosave_interval()
{
return (int)$this->getOption('gutenberg_autosave_interval', 99999);
}
/**
* Set interval option.
*
* @param \WP_REST_Request $request
*
* @return mixed
*/
public function set_get_gutenberg_autosave_interval(\WP_REST_Request $request)
{
if( !isset($request['interval']) ) {
return new \WP_Error('no_interval', __('No interval specified', 'clearfy'), ['status' => 400]);
}
$this->updateOption('gutenberg_autosave_interval', (int)$request['interval']);
return [];
}
/**
* Setup REST API for managing interval option. Сreates an endpoint
* for working with autosave in gutenberg editor.
*/
public function gutenberg_autosave_rest_mapping()
{
register_rest_route('clearfy-gutenberg-autosave/v1', '/interval', [
[
'methods' => \WP_REST_Server::READABLE,
'callback' => [$this, 'get_gutenberg_autosave_interval'],
'permission_callback' => function () {
return WCL_Plugin::app()->currentUserCan();
}
],
[
'methods' => \WP_REST_Server::CREATABLE,
'callback' => [$this, 'set_get_gutenberg_autosave_interval'],
'args' => [
'interval' => [
'validate_callback' => function ($param, $request, $key) {
return is_numeric($param);
},
]
],
'permission_callback' => function () {
return WCL_Plugin::app()->currentUserCan();
}
],
]);
}
/**
* Disables automatic saving drafts.
*/
public function disable_posts_autosave()
{
wp_deregister_script('autosave');
}
/**
* Full disable revision support in Wordpress
*
* @since 1.5.1
*/
public function disable_revision_support()
{
$post_types = get_post_types();
if( !is_array($post_types) || empty($post_types) ) {
return;
}
foreach($post_types as $post_type) {
remove_post_type_support($post_type, 'revisions');
}
}
/**
* Revisions limit
*
* @since 0.9.5
*/
public function revisions_to_keep($num, $post)
{
$revision_limit = $this->getPopulateOption('revision_limit', null);
if( $revision_limit ) {
$num = (int)$revision_limit;
}
if( 'default' == $revision_limit ) {
$num = true;
}
if( $this->getPopulateOption('revisions_disable') ) {
$num = 0;
}
return $num;
}
/**
* Disable dashicons for all but the auth user
*/
public function disableDashicons()
{
if( !is_admin_bar_showing() && !is_customize_preview() ) {
wp_deregister_style('dashicons');
}
}
/**
* Disable the emoji's
*/
public function disableEmojis()
{
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('admin_print_scripts', 'print_emoji_detection_script');
remove_action('wp_print_styles', 'print_emoji_styles');
remove_action('admin_print_styles', 'print_emoji_styles');
remove_filter('the_content_feed', 'wp_staticize_emoji');
remove_filter('comment_text_rss', 'wp_staticize_emoji');
remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
add_filter('emoji_svg_url', '__return_false');
add_filter('tiny_mce_plugins', [$this, 'disableEmojisTinymce']);
add_filter('wp_resource_hints', [$this, 'disableEmojisRemoveDnsPrefetch'], 10, 2);
}
/**
* Filter function used to remove the tinymce emoji plugin.
*
* @param array $plugins
*
* @return array Difference betwen the two arrays
*/
function disableEmojisTinymce($plugins)
{
if( is_array($plugins) ) {
return array_diff($plugins, ['wpemoji']);
}
return [];
}
/**
* Remove emoji CDN hostname from DNS prefetching hints.
*
* @param array $urls URLs to print for resource hints.
* @param string $relation_type The relation type the URLs are printed for.
*
* @return array Difference betwen the two arrays.
*/
function disableEmojisRemoveDnsPrefetch($urls, $relation_type)
{
if( 'dns-prefetch' == $relation_type ) {
// Strip out any URLs referencing the WordPress.org emoji location
$emoji_svg_url_bit = 'https://s.w.org/images/core/emoji/';
foreach($urls as $key => $url) {
if( strpos($url, $emoji_svg_url_bit) !== false ) {
unset($urls[$key]);
}
}
}
return $urls;
}
// todo: не работает должным образом, проверить
public function removeRecentCommentsStyle()
{
global $wp_widget_factory;
$widget_recent_comments = isset($wp_widget_factory->widgets['WP_Widget_Recent_Comments']) ? $wp_widget_factory->widgets['WP_Widget_Recent_Comments'] : null;
if( !empty($widget_recent_comments) ) {
remove_action('wp_head', [
$wp_widget_factory->widgets['WP_Widget_Recent_Comments'],
'recent_comments_style'
]);
}
}
/**
* Disable feeds
*/
public function disableFeed()
{
add_action('wp_loaded', [$this, 'removeFeedLinks']);
add_action('template_redirect', [$this, 'filterFeeds'], 1);
add_filter('bbp_request', [$this, 'filterBbpFeeds'], 9);
}
public function removeFeedLinks()
{
remove_action('wp_head', 'feed_links', 2);
remove_action('wp_head', 'feed_links_extra', 3);
}
public function filterFeeds()
{
if( !is_feed() || is_404() ) {
return;
}
$this->disabled_feed_behaviour();
}
public function disabled_feed_behaviour()
{
global $wp_rewrite, $wp_query;
if( $this->getPopulateOption('disabled_feed_behaviour', 'redirect_301') == 'redirect_404' ) {
$wp_query->is_feed = false;
$wp_query->set_404();
status_header(404);
// Override the xml+rss header set by WP in send_headers
header('Content-Type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
} else {
if( isset($_GET['feed']) ) {
wp_redirect(esc_url_raw(remove_query_arg('feed')), 301);
exit;
}
if( 'old' !== get_query_var('feed') ) { // WP redirects these anyway, and removing the query var will confuse it thoroughly
set_query_var('feed', '');
}
redirect_canonical(); // Let WP figure out the appropriate redirect URL.
// Still here? redirect_canonical failed to redirect, probably because of a filter. Try the hard way.
$struct = (!is_singular() && is_comment_feed()) ? $wp_rewrite->get_comment_feed_permastruct() : $wp_rewrite->get_feed_permastruct();
$struct = preg_quote($struct, '#');
$struct = str_replace('%feed%', '(\w+)?', $struct);
$struct = preg_replace('#/+#', '/', $struct);
$requested_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$new_url = preg_replace('#' . $struct . '/?$#', '', $requested_url);
if( $new_url !== $requested_url ) {
wp_redirect($new_url, 301);
exit;
}
}
}
/**
* BBPress feed detection sourced from bbp_request_feed_trap() in BBPress Core.
*
* @param array $query_vars
*
* @return array
*/
public function filterBbpFeeds($query_vars)
{
// Looking at a feed
if( isset($query_vars['feed']) ) {
// Forum/Topic/Reply Feed
if( isset($query_vars['post_type']) ) {
// Matched post type
$post_type = false;
$post_types = [];
if( function_exists('bbp_get_forum_post_type') && function_exists('bbp_get_topic_post_type') && function_exists('bbp_get_reply_post_type') ) // Post types to check
{
$post_types = [
bbp_get_forum_post_type(),
bbp_get_topic_post_type(),
bbp_get_reply_post_type(),
];
}
// Cast query vars as array outside of foreach loop
$qv_array = (array)$query_vars['post_type'];
// Check if this query is for a bbPress post type
foreach($post_types as $bbp_pt) {
if( in_array($bbp_pt, $qv_array, true) ) {
$post_type = $bbp_pt;
break;
}
}
// Looking at a bbPress post type
if( !empty($post_type) ) {
$this->disabled_feed_behaviour();
}
}
}
// No feed so continue on
return $query_vars;
}
/**
* Remove unused tags from head
*/
public function remove_tags_from_head()
{
if( $this->getPopulateOption('remove_rsd_link') ) {
remove_action('wp_head', 'rsd_link');
}
if( $this->getPopulateOption('remove_wlw_link') ) {
remove_action('wp_head', 'wlwmanifest_link');
}
if( $this->getPopulateOption('remove_adjacent_posts_link') ) {
remove_action('wp_head', 'adjacent_posts_rel_link');
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
}
if( $this->getPopulateOption('remove_shortlink_link') ) {
remove_action('wp_head', 'wp_shortlink_wp_head');
remove_action('template_redirect', 'wp_shortlink_header', 11);
}
if( $this->getPopulateOption('remove_xfn_link') ) {
add_filter('avf_profile_head_tag', [$this, 'removeXfnLink']);
}
}
/**
* For more information about XFN relationships and examples concerning their use, see the
*
* http://gmpg.org/xfn/
* @return bool
*/
public function removeXfnLink()
{
return false;
}
/**
* Remove jQuery Migrate
*
* @param WP_Scripts $scripts
*/
public function removeJqueryMigrate(&$scripts)
{
$scripts->remove('jquery');
$scripts->add('jquery', false, ['jquery-core'], '1.12.4');
}
// Disable Embeds
public function disableEmbeds()
{
global $wp, $wp_embed;
$wp->public_query_vars = array_diff($wp->public_query_vars, ['embed']);
remove_filter('the_content', [$wp_embed, 'autoembed'], 8);
// Remove content feed filter
remove_filter('the_content_feed', '_oembed_filter_feed_content');
// Abort embed libraries loading
remove_action('plugins_loaded', 'wp_maybe_load_embeds', 0);
// No auto-embedding support
add_filter('pre_option_embed_autourls', '__return_false');
// Avoid oEmbed auto discovery
add_filter('embed_oembed_discover', '__return_false');
// Remove REST API related hooks
remove_action('rest_api_init', 'wp_oembed_register_route');
remove_filter('rest_pre_serve_request', '_oembed_rest_pre_serve_request', 10);
// Remove header actions
remove_action('wp_head', 'wp_oembed_add_discovery_links');
remove_action('wp_head', 'wp_oembed_add_host_js');
remove_action('embed_head', 'enqueue_embed_scripts', 1);
remove_action('embed_head', 'print_emoji_detection_script');
remove_action('embed_head', 'print_embed_styles');
remove_action('embed_head', 'wp_print_head_scripts', 20);
remove_action('embed_head', 'wp_print_styles', 20);
remove_action('embed_head', 'wp_no_robots');
remove_action('embed_head', 'rel_canonical');
remove_action('embed_head', 'locale_stylesheet', 30);
remove_action('embed_content_meta', 'print_embed_comments_button');
remove_action('embed_content_meta', 'print_embed_sharing_button');
remove_action('embed_footer', 'print_embed_sharing_dialog');
remove_action('embed_footer', 'print_embed_scripts');
remove_action('embed_footer', 'wp_print_footer_scripts', 20);
remove_filter('excerpt_more', 'wp_embed_excerpt_more', 20);
remove_filter('the_excerpt_embed', 'wptexturize');
remove_filter('the_excerpt_embed', 'convert_chars');
remove_filter('the_excerpt_embed', 'wpautop');
remove_filter('the_excerpt_embed', 'shortcode_unautop');
remove_filter('the_excerpt_embed', 'wp_embed_excerpt_attachment');
// Remove data and results filters
remove_filter('oembed_dataparse', 'wp_filter_oembed_result', 10);
remove_filter('oembed_response_data', 'get_oembed_response_data_rich', 10);
remove_filter('pre_oembed_result', 'wp_filter_pre_oembed_result', 10);
// WooCommerce embeds in short description
remove_filter('woocommerce_short_description', 'wc_do_oembeds');
add_filter('tiny_mce_plugins', [$this, 'disableEmbedsTinyMcePlugin']);
add_filter('rewrite_rules_array', [$this, 'disableEmbedsRewrites']);
}
public function disableEmbedsTinyMcePlugin($plugins)
{
return array_diff($plugins, ['wpembed', 'wpview']);
}
public function disableEmbedsRewrites($rules)
{
$new_rules = [];
foreach($rules as $rule => $rewrite) {
if( false !== ($pos = strpos($rewrite, '?')) ) {
$params = explode('&', substr($rewrite, $pos + 1));
if( in_array('embed=true', $params) ) {
continue;
}
}
$new_rules[$rule] = $rewrite;
}
return $new_rules;
}
public function htmlCompressor()
{
ob_start([$this, 'htmlCompressorMain']);
}
public function htmlCompressorMain($content)
{
$old_content = $content;
if( $this->getPopulateOption('remove_xfn_link') ) {
$content = preg_replace('/<link[^>]+href=(?:\'|")https?:\/\/gmpg.org\/xfn\/11(?:\'|")(?:[^>]+)?>/', '', $content);
if( empty($content) ) {
$content = $old_content;
}
}
return $content;
}
}

View File

@@ -0,0 +1,126 @@
<?php
/**
* This class configures the code cleanup settings
*
* @author Webcraftic <wordpress.webraftic@gmail.com>
* @copyright (c) 2017 Webraftic Ltd
* @version 1.0
*/
// Exit if accessed directly
if( !defined('ABSPATH') ) {
exit;
}
class WCL_ConfigPrivacy extends WBCR\Factory_Templates_134\Configurate {
/**
* @param WCL_Plugin $plugin
*/
public function __construct(WCL_Plugin $plugin)
{
parent::__construct($plugin);
$this->plugin = $plugin;
}
public function registerActionsAndFilters()
{
if( !is_admin() ) {
if( $this->getPopulateOption('remove_meta_generator') ) {
// Clean meta generator for Woocommerce
if( class_exists('WooCommerce') ) {
remove_action('wp_head', 'woo_version');
}
// Clean meta generator for SitePress
if( class_exists('SitePress') ) {
global $sitepress;
remove_action('wp_head', [$sitepress, 'meta_generator_tag']);
}
// Clean meta generator for Wordpress core
remove_action('wp_head', 'wp_generator');
add_filter('the_generator', '__return_empty_string');
// Clean all meta generators
add_action('wp_head', [$this, 'clean_meta_generators'], 100);
}
if( $this->getPopulateOption('remove_html_comments') ) {
add_action('wp_loaded', [$this, 'clean_html_comments']);
}
}
}
/**
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @since 1.5.3
*/
public function clean_meta_generators()
{
ob_start([$this, 'replace_meta_generators']);
}
/**
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @since 1.0.0
*/
public function clean_html_comments()
{
if( !WCL_Helper::doing_rest_api() ) {
ob_start([$this, 'replace_html_comments']);
}
}
/**
* Replace <meta .* name="generator"> like tags
* which may contain versioning of
*
* @param $html
*
* @return string|string[]|null
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @since 1.5.3
*
*/
public function replace_meta_generators($html)
{
$raw_html = $html;
$pattern = '/<meta[^>]+name=["\']generator["\'][^>]+>/i';
$html = preg_replace($pattern, '', $html);
// If replacement is completed with an error, user will receive a white screen.
// We have to prevent it.
if( empty($html) ) {
return $raw_html;
}
return $html;
}
/**
* !ngg_resource - can not be deleted, otherwise the plugin nextgen gallery will not work
*
* @param string $data
*
* @return mixed
*/
public function replace_html_comments($html)
{
$raw_html = $html;
//CLRF-166 issue fix bug with noindex (\s?\/?noindex)
$html = preg_replace('#<!--(?!<!|\s?ngg_resource|\s?\/?noindex|\s?\/?wp:)[^\[>].*?-->#s', '', $html);
// If replacement is completed with an error, user will receive a white screen.
// We have to prevent it.
if( empty($html) ) {
return $raw_html;
}
return $html;
}
}

View File

@@ -0,0 +1,229 @@
<?php
/**
* This class configures security settings
* @author Webcraftic <wordpress.webraftic@gmail.com>
* @copyright (c) 2017 Webraftic Ltd
* @version 1.0
*/
// Exit if accessed directly
if( !defined('ABSPATH') ) {
exit;
}
class WCL_ConfigSecurity extends WBCR\Factory_Templates_134\Configurate {
/**
* @param WCL_Plugin $plugin
*/
public function __construct(WCL_Plugin $plugin)
{
parent::__construct($plugin);
$this->plugin = $plugin;
}
public function registerActionsAndFilters()
{
if( !is_admin() ) {
if( $this->getPopulateOption('change_login_errors') ) {
add_filter('login_errors', array($this, 'changeLoginErrors'));
}
if( $this->getPopulateOption('protect_author_get') ) {
add_action('wp', array($this, 'protectAuthorGet'));
}
// Removes the server responses a reference to the xmlrpc file.
if( $this->getPopulateOption('remove_x_pingback') ) {
add_filter('template_redirect', array($this, 'removeXmlRpcPingbackHeaders'));
add_filter('wp_headers', array($this, 'disableXmlRpcPingback'));
// Remove <link rel="pingback" href>
add_action('template_redirect', array($this, 'removeXmlRpcTagBufferStart'), -1);
add_action('get_header', array($this, 'removeXmlRpcTagBufferStart'));
add_action('wp_head', array($this, 'removeXmlRpcTagBufferEnd'), 999);
// Remove RSD link from head
remove_action('wp_head', 'rsd_link');
// Disable xmlrcp/pingback
add_filter('xmlrpc_enabled', '__return_false');
add_filter('pre_update_option_enable_xmlrpc', '__return_false');
add_filter('pre_option_enable_xmlrpc', '__return_zero');
add_filter('pings_open', '__return_false');
// Force to uncheck pingbck and trackback options
add_filter('pre_option_default_ping_status', '__return_zero');
add_filter('pre_option_default_pingback_flag', '__return_zero');
add_filter('xmlrpc_methods', array($this, 'removeXmlRpcMethods'));
add_action('xmlrpc_call', array($this, 'disableXmlRpcCall'));
// Hide options on Discussion page
add_action('admin_enqueue_scripts', array($this, 'removeXmlRpcHideOptions'));
$this->xmlRpcSetDisabledHeader();
}
}
}
/**
* Just disable pingback.ping functionality while leaving XMLRPC intact?
*
* @param $method
*/
public function disableXmlRpcCall($method)
{
if( $method != 'pingback.ping' ) {
return;
}
wp_die('This site does not have pingback.', 'Pingback not Enabled!', array('response' => 403));
}
public function removeXmlRpcMethods($methods)
{
unset($methods['pingback.ping']);
unset($methods['pingback.extensions.getPingbacks']);
unset($methods['wp.getUsersBlogs']); // Block brute force discovery of existing users
unset($methods['system.multicall']);
unset($methods['system.listMethods']);
unset($methods['system.getCapabilities']);
return $methods;
}
/**
* Disable X-Pingback HTTP Header.
*
* @param array $headers
* @return mixed
*/
public function disableXmlRpcPingback($headers)
{
unset($headers['X-Pingback']);
return $headers;
}
/**
* Disable X-Pingback HTTP Header.
*
* @param array $headers
* @return mixed
*/
public function removeXmlRpcPingbackHeaders()
{
if( function_exists('header_remove') ) {
header_remove('X-Pingback');
header_remove('Server');
}
}
/**
* Start buffer for remove <link rel="pingback" href>
*/
public function removeXmlRpcTagBufferStart()
{
ob_start(array($this, "removeXmlRpcTag"));
}
/**
* End buffer
*/
public function removeXmlRpcTagBufferEnd()
{
ob_flush();
}
/**
* @param $buffer
* @return mixed
*/
function removeXmlRpcTag($buffer)
{
preg_match_all('/(<link([^>]+)rel=("|\')pingback("|\')([^>]+)?\/?>)/im', $buffer, $founds);
if( !isset($founds[0]) || count($founds[0]) < 1 ) {
return $buffer;
}
if( count($founds[0]) > 0 ) {
foreach($founds[0] as $found) {
if( empty($found) ) {
continue;
}
$buffer = str_replace($found, "", $buffer);
}
}
return $buffer;
}
/**
* Hide Discussion options with CSS
*
* @return null
*/
public function removeXmlRpcHideOptions($hook)
{
if( 'options-discussion.php' !== $hook ) {
return;
}
wp_add_inline_style('dashboard', '.form-table td label[for="default_pingback_flag"], .form-table td label[for="default_pingback_flag"] + br, .form-table td label[for="default_ping_status"], .form-table td label[for="default_ping_status"] + br { display: none; }');
}
/**
* Set disabled header for any XML-RPC requests
*/
public function xmlRpcSetDisabledHeader()
{
// Return immediately if SCRIPT_FILENAME not set
if( !isset($_SERVER['SCRIPT_FILENAME']) ) {
return;
}
$file = basename($_SERVER['SCRIPT_FILENAME']);
// Break only if xmlrpc.php file was requested.
if( 'xmlrpc.php' !== $file ) {
return;
}
$header = 'HTTP/1.1 403 Forbidden';
header($header);
echo $header;
die();
}
/**
* Change login error message
*
* @return string
*/
public function changeLoginErrors($errors)
{
if( !in_array($GLOBALS['pagenow'], array('wp-login.php')) ) {
return $errors;
}
return __('<strong>ERROR</strong>: Wrong login or password', 'clearfy');
}
/**
* Protect author get
*/
public function protectAuthorGet()
{
if( isset($_GET['author']) ) {
wp_redirect(home_url(), 301);
die();
}
}
}

View File

@@ -0,0 +1,478 @@
<?php
/**
* This class configures the parameters seo
*
* @author Webcraftic <wordpress.webraftic@gmail.com>
* @copyright (c) 2017 Webraftic Ltd
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class WCL_ConfigSeo extends WBCR\Factory_Templates_134\Configurate {
/**
* @param WCL_Plugin $plugin
*/
public function __construct( WCL_Plugin $plugin ) {
parent::__construct( $plugin );
$this->plugin = $plugin;
}
public function registerActionsAndFilters() {
if ( ! is_admin() ) {
if ( $this->getPopulateOption( 'content_image_auto_alt' ) ) {
add_filter( 'the_content', [ $this, 'images_alt_autocomplete' ], 9999 );
add_filter( 'wp_get_attachment_image_attributes', [
$this,
'change_attachement_image_attributes'
], 20, 2 );
}
if ( $this->getPopulateOption( 'right_robots_txt' ) ) {
add_filter( 'robots_txt', [ $this, 'rightRobotsTxt' ], 9999 );
}
if ( $this->getPopulateOption( 'remove_last_item_breadcrumb_yoast' ) ) {
add_filter( 'wpseo_breadcrumb_single_link', [ $this, 'remove_yoast_breadcrumb_last' ] );
}
if ( $this->getPopulateOption( 'attachment_pages_redirect' ) ) {
add_action( 'template_redirect', [ $this, 'attachmentPagesRedirect' ] );
}
if ( $this->getPopulateOption( 'remove_single_pagination_duplicate' ) ) {
add_action( 'template_redirect', [ $this, 'removeSinglePaginationDuplicate' ] );
}
if ( $this->getPopulateOption( 'remove_replytocom' ) ) {
add_action( 'template_redirect', [ $this, 'removeReplytocomRedirect' ], 1 );
add_filter( 'comment_reply_link', [ $this, 'removeReplytocomLink' ] );
}
add_action( 'wp', [ $this, 'redirectArchives' ] );
}
if ( $this->getPopulateOption( 'set_last_modified_headers' ) ) {
if ( ! is_admin() ) {
add_action( 'template_redirect', [ $this, 'setLastModifiedHeaders' ] );
}
add_action( 'wp_logout', [ $this, 'lastModifedFlushCookie' ] );
}
if ( $this->plugin->isActivateComponent( 'yoast_seo' ) && defined( 'WPSEO_VERSION' ) ) {
if ( ! is_admin() ) {
if ( $this->getPopulateOption( 'yoast_remove_json_ld_search' ) ) {
add_filter( 'disable_wpseo_json_ld_search', '__return_true' );
}
if ( $this->getPopulateOption( 'yoast_remove_json_ld_output' ) ) {
add_filter( 'wpseo_json_ld_output', [ $this, 'removeYoastJson' ], 10, 1 );
}
if ( $this->getPopulateOption( 'yoast_remove_head_comment' ) ) {
add_action( 'init', [ $this, 'yoastRemoveHeadComment' ] );
}
/*if( $this->getPopulateOption('yoast_canonical_pagination') ) {
add_filter('wpseo_canonical', array($this, 'yoastCanonicalPagination'));
}*/
}
if ( $this->getPopulateOption( 'yoast_remove_image_from_xml_sitemap' ) ) {
$this->yoastRemoveImageFromXmlSitemap();
}
}
}
/**
* @param $data
*
* @return array
*/
public function removeYoastJson( $data ) {
$data = [];
return $data;
}
/**
* Add post title in image alt attribute
*
* @param $content
*
* @return mixed
*/
public function images_alt_autocomplete( $content ) {
global $post;
if ( empty( $post ) ) {
return $content;
}
$old_content = $content;
preg_match_all( '/<img[^>]+>/', $content, $images );
if ( ! is_null( $images ) ) {
foreach ( $images[0] as $index => $value ) {
if ( ! preg_match( '/alt=/', $value ) ) {
$new_img = str_replace( '<img', '<img alt="' . esc_attr( $post->post_title ) . '"', $images[0][ $index ] );
$content = str_replace( $images[0][ $index ], $new_img, $content );
} else if ( preg_match( '/alt=["\']\s?["\']/', $value ) ) {
$new_img = preg_replace( '/alt=["\']\s?["\']/', 'alt="' . esc_attr( $post->post_title ) . '"', $images[0][ $index ] );
$content = str_replace( $images[0][ $index ], $new_img, $content );
}
}
}
if ( empty( $content ) ) {
return $old_content;
}
return $content;
}
/**
* Setting attributes for post thumnails
*
* @param $attr
* @param $attachment
*
* @return mixed
*/
public function change_attachement_image_attributes( $attr, $attachment ) {
// Get post parent
$parent = get_post_field( 'post_parent', $attachment );
// Get post type to check if it's product
//$type = get_post_field('post_type', $parent);
/*if( $type != 'product' ) {
return $attr;
}*/
/// Get title
$title = get_post_field( 'post_title', $parent );
if ( '' === $attr['alt'] ) {
$attr['alt'] = $title;
}
$attr['title'] = $title;
return $attr;
}
/**
* Add directories to virtual robots.txt file
*
* @param string $output
*
* @return mixed|string|void
*/
public function rightRobotsTxt( $output ) {
if ( $this->getPopulateOption( 'robots_txt_text' ) ) {
return $this->getPopulateOption( 'robots_txt_text' );
}
return WCL_Helper::getRightRobotTxt();
}
/**
* Attachment pages redirect
*/
public function attachmentPagesRedirect() {
global $post;
if ( is_attachment() ) {
if ( isset( $post->post_parent ) && ( $post->post_parent != 0 ) ) {
wp_redirect( get_permalink( $post->post_parent ), 301 );
} else {
wp_redirect( home_url(), 301 );
}
exit;
}
}
/**
* Remove single pagination duplicate
*/
public function removeSinglePaginationDuplicate() {
global $post, $page;
if ( is_singular() && ! is_front_page() ) {
// #CLRF-125 issue fix bug for buddy press
if ( function_exists( 'bp_is_my_profile' ) ) {
if ( bp_is_my_profile() ) {
return;
}
}
// if woocommerce just return
if ( class_exists( 'woocommerce' ) && function_exists( 'is_cart' ) && function_exists( 'is_checkout' ) && function_exists( 'is_woocommerce' ) && function_exists( 'is_account_page' ) && ( is_cart() || is_checkout() || is_woocommerce() || is_account_page() ) ) {
return;
}
$num_pages = substr_count( $post->post_content, '<!--nextpage-->' ) + 1;
if ( $page > $num_pages ) {
wp_safe_redirect( get_permalink( $post->ID ), 301 );
exit();
}
}
}
/**
* Remove last item from breadcrumbs SEO by YOAST
*
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @since 1.5.4
*
* @param string $link_output Html string example: <span><a href="http://clearfy.loc/" >Home</a>
*
* @return string
*/
public function remove_yoast_breadcrumb_last( $link_output ) {
if ( strpos( $link_output, 'breadcrumb_last' ) !== false ) {
return "";
}
return $link_output;
}
/**
* Remove yoast comment
*/
public function yoastRemoveHeadComment() {
add_action( 'get_header', [ $this, 'yoastRemoveHeadCommentStart' ] );
add_action( 'wp_head', [ $this, 'yoastRemoveHeadCommentEnd' ], 999 );
}
public function yoastRemoveHeadCommentStart() {
ob_start( [ $this, 'yoastRemoveHeadCommentRemove' ] );
}
public function yoastRemoveHeadCommentEnd() {
ob_end_flush();
}
public function yoastRemoveHeadCommentRemove( $html ) {
return preg_replace( '/^<!--.*?[Yy]oast.*?-->$/mi', '', $html );
}
/**
* Remove <image:image> from sitemap
*/
public function yoastRemoveImageFromXmlSitemap() {
add_filter( 'wpseo_xml_sitemap_img', '__return_false' );
add_filter( 'wpseo_sitemap_url', [ $this, 'yoastRemoveImageFromXmlClean' ], 10, 2 );
}
public function yoastRemoveImageFromXmlClean( $output, $url ) {
$output = preg_replace( '/<image:image[^>]*?>.*?<\/image:image>/si', '', $output );
return $output;
}
/**
* Canonical link in pagination Yoast
*
* @param $canonical
*
* @return string
*/
/*public function yoastCanonicalPagination( $canonical ) {
if ( is_category() && is_paged() ) {
$cat = get_category( get_query_var( 'cat' ) );
$cat_id = $cat->cat_ID;
return get_category_link( $cat_id );
}
if ( is_home() && is_paged() ) {
return home_url('/');
}
return $canonical;
}*/
/**
* Redirect archives author, date, tags
*/
public function redirectArchives() {
if ( $this->getPopulateOption( 'redirect_archives_author' ) ) {
if ( is_author() ) {
wp_redirect( home_url(), 301 );
die();
}
}
if ( $this->getPopulateOption( 'redirect_archives_date' ) ) {
if ( is_date() ) {
wp_redirect( home_url(), 301 );
die();
}
}
if ( $this->getPopulateOption( 'redirect_archives_tag' ) ) {
if ( is_tag() ) {
wp_redirect( home_url(), 301 );
die();
}
}
}
/**
* Remove replytocom
*/
public function removeReplytocomRedirect() {
global $post;
if ( ! empty( $post ) && isset( $_GET['replytocom'] ) && is_singular() ) {
$post_url = get_permalink( $post->ID );
$comment_id = sanitize_text_field( $_GET['replytocom'] );
$query_string = remove_query_arg( 'replytocom', sanitize_text_field( $_SERVER['QUERY_STRING'] ) );
if ( ! empty( $query_string ) ) {
$post_url .= '?' . $query_string;
}
$post_url .= '#comment-' . $comment_id;
wp_safe_redirect( esc_url_raw($post_url), 301 );
die();
}
return false;
}
public function removeReplytocomLink( $link ) {
return preg_replace( '`href=(["\'])(?:.*(?:\?|&|&#038;)replytocom=(\d+)#respond)`', 'href=$1#comment-$2', $link );
}
public function setLastModifiedHeaders() {
if ( is_user_logged_in() && ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
return;
}
if ( class_exists( 'woocommerce' ) && function_exists( 'is_cart' ) && function_exists( 'is_checkout' ) && function_exists( 'is_account_page' ) && ( is_cart() || is_checkout() || is_account_page() ) ) {
return;
}
if ( is_front_page() ) {
$last_modified_exclude_frontpage = $this->getPopulateOption( 'disable_frontpage_last_modified_headers' );
if ( $last_modified_exclude_frontpage ) {
return;
}
}
$last_modified_flush = isset( $_COOKIE['wbcr_lastmodifed_flush'] );
global $wp;
$last_modified_exclude = $this->getPopulateOption( 'last_modified_exclude' );
$last_modified_exclude_exp = explode( PHP_EOL, $last_modified_exclude );
$current_url = home_url( add_query_arg( [], $wp->request ) );
foreach ( $last_modified_exclude_exp as $expr ) {
if ( ! empty( $expr ) && strpos( urldecode( $current_url ), $expr ) !== false ) {
return;
}
}
/**
* if Search - just return
*/
if ( is_search() ) {
return;
}
$last_modified = '';
/**
* If posts, pages, custom post types
*/
if ( is_singular() ) {
global $post;
if ( ! isset( $post->post_modified_gmt ) ) {
return;
}
$post_time = strtotime( $post->post_modified_gmt );
$modified_time = $post_time;
/**
* If we have comment set new modified date
*/
if ( (int) $post->comment_count > 0 ) {
$comments = get_comments( [
'post_id' => $post->ID,
'number' => '1',
'status' => 'approve',
'orderby' => 'comment_date_gmt',
] );
if ( ! empty( $comments ) && isset( $comments[0] ) ) {
$comment_time = strtotime( $comments[0]->comment_date_gmt );
if ( $comment_time > $post_time ) {
$modified_time = $comment_time;
}
}
}
$last_modified = str_replace( '+0000', 'GMT', gmdate( 'r', $modified_time ) );
}
/**
* If any archives: categories, tags, taxonomy terms, post type archives
*/
if ( is_archive() || is_home() ) {
global $posts;
if ( empty( $posts ) ) {
return;
}
$post = $posts[0];
if ( ! isset( $post->post_modified_gmt ) ) {
return;
}
$post_time = strtotime( $post->post_modified_gmt );
$modified_time = $post_time;
$last_modified = str_replace( '+0000', 'GMT', gmdate( 'r', $modified_time ) );
}
/**
* If headers already sent - do nothing
*/
if ( headers_sent() ) {
return;
}
if ( ! empty( $last_modified ) && ! empty( $modified_time ) ) {
//todo: Fix bug, admin bar is not hidden after logout
if ( $last_modified_flush ) {
$modified_time += rand( 1, 99 );
}
header( 'Last-Modified: ' . $last_modified );
if ( $this->getPopulateOption( 'if_modified_since_headers' ) && ! is_user_logged_in() ) {
if ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) && strtotime( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) >= $modified_time ) {
$protocol = ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' );
header( $protocol . ' 304 Not Modified' );
}
}
}
}
function lastModifedFlushCookie() {
if ( ! isset( $_COOKIE['wbcr_lastmodifed_flush'] ) ) {
setcookie( "wbcr_lastmodifed_flush", 1, time() + 3600 );
}
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* Class for working with the licensing system
*
* @author Alex Kovalev <alex.kovalevv@gmail.com>
* @copyright (c) 2018 Webraftic Ltd
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class WCL_Licensing {
public $id;
public $secret_key;
/**
* @since 1.0
* @var WCL_Licensing
*/
private static $instance;
/**
* Initialization of the licensing system
*
*/
private function __construct() {
if ( WCL_Plugin::app()->premium->is_activate() ) {
$this->id = 1;
$this->secret_key = WCL_Plugin::app()->premium->get_license()->get_key();
}
}
/**
* Getting a licensing system
*
* @return WCL_Licensing
*/
public static function instance() {
if ( self::$instance ) {
return self::$instance;
}
self::$instance = new self();
return self::$instance;
}
/**
* Returns a storage object
*
* @return WCL_Licensing
*/
public function getStorage() {
return self::instance();
}
/**
* @return \WCL_Licensing
* @since 1.1
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
*/
public function getLicense() {
return self::instance();
}
/**
* Checks if current license has expired
*
* @return bool
*/
public function isLicenseValid() {
return WCL_Plugin::app()->premium->is_activate();
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* A class for packing files into an archive.
* @author Webcraftic <wordpress.webraftic@gmail.com>
* @copyright (c) 2017 Webraftic Ltd
* @version 1.0
*/
// Exit if accessed directly
if( !defined('ABSPATH') ) {
exit;
}
if( !class_exists('ZipArchive') ) {
wp_die(__('The ZipArchive class does not exist in this version of php.'));
}
class Wbcr_ExtendedZip extends ZipArchive {
// Member function to add a whole file system subtree to the archive
public function addTree($dirname, $localname = '')
{
if( $localname ) {
$this->addEmptyDir($localname);
}
$this->_addTree($dirname, $localname);
}
// Internal function, to recurse
protected function _addTree($dirname, $localname)
{
$dir = opendir($dirname);
while( $filename = readdir($dir) ) {
// Discard . and ..
if( $filename == '.' || $filename == '..' ) {
continue;
}
// Proceed according to type
$path = $dirname . '/' . $filename;
$localpath = $localname
? ($localname . '/' . $filename)
: $filename;
if( is_dir($path) ) {
// Directory: add & recurse
$this->addEmptyDir($localpath);
$this->_addTree($path, $localpath);
} else if( is_file($path) ) {
// File: just add
$this->addFile($path, $localpath);
}
}
closedir($dir);
}
// Helper function
public static function zipTree($dirname, $zipFilename, $flags = 0, $localname = '')
{
$zip = new self();
$zip->open($zipFilename, $flags);
$zip->addTree($dirname, $localname);
$zip->close();
}
}

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.