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,112 @@
<?php
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Disable comments
*
* @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
*
* @copyright (c) 2018 Webraftic Ltd
*/
class WCM_Plugin {
/**
* @see self::app()
* @var WCL_Plugin
*/
private static $app;
/**
* Конструктор
*
* Применяет конструктор родительского класса и записывает экземпляр текущего класса в свойство $app.
* Подробнее о свойстве $app см. self::app()
*
* @param string $plugin_path
* @param array $data
*
* @throws Exception
*/
public function __construct() {
if ( ! class_exists( 'WCL_Plugin' ) ) {
throw new Exception( 'Plugin Clearfy is not installed!' );
}
self::$app = WCL_Plugin::app();
$this->global_scripts();
if ( is_admin() ) {
$this->admin_scripts();
}
add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ] );
// Wordpress 6.7 fix
add_action( 'init', function () {
if ( is_admin() ) {
$this->register_pages();
}
} );
}
/**
* Статический метод для быстрого доступа к интерфейсу плагина.
*
* Позволяет разработчику глобально получить доступ к экземпляру класса плагина в любом месте
* плагина, но при этом разработчик не может вносить изменения в основной класс плагина.
*
* Используется для получения настроек плагина, информации о плагине, для доступа к вспомогательным
* классам.
*
* @return WCL_Plugin
*/
public static function app() {
return self::$app;
}
/**
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @throws \Exception
*/
public function plugins_loaded() {
}
/**
* Регистрирует классы страниц в плагине
*
* Мы указываем плагину, где найти файлы страниц и какое имя у их класса. Чтобы плагин
* выполнил подключение классов страниц. После регистрации, страницы будут доступные по url
* и в меню боковой панели администратора. Регистрируемые страницы будут связаны с текущим плагином
* все операции выполняемые внутри классов страниц, имеют отношение только текущему плагину.
*
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @throws \Exception
*/
private function register_pages() {
$admin_path = WCM_PLUGIN_DIR . '/admin/pages';
self::app()->registerPage( 'WbcrCmp_CommentsPage', $admin_path . '/class-page-comments.php' );
self::app()->registerPage( 'WbcrCmp_DeleteCommentsPage', $admin_path . '/class-page-delete-comments.php' );
}
/**
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
*/
private function admin_scripts() {
require( WCM_PLUGIN_DIR . '/admin/boot.php' );
}
/**
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
*/
private function global_scripts() {
require( WCM_PLUGIN_DIR . '/includes/boot.php' );
require( WCM_PLUGIN_DIR . '/includes/classes/class-configurate-comments.php' );
new WbcrCmp_ConfigComments( self::$app );
}
}

View File

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

View File

@@ -0,0 +1,51 @@
<?php
/**
* Admin boot
*
* @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
*
* @copyright Webcraftic 25.05.2017
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Получает список отключенных типов записей
*
* @return array|bool|mixed|void
*/
function wbcr_cmp_get_disabled_post_types() {
$post_types = WCM_Plugin::app()->getPopulateOption( 'disable_comments_for_post_types' );
if ( WCM_Plugin::app()->getPopulateOption( 'disable_comments', 'enable_comments' ) == 'disable_comments' ) {
$args = [ 'public' => true ];
if ( WCM_Plugin::app()->isNetworkActive() ) {
$args['_builtin'] = true;
}
$all_post_types = get_post_types( $args, 'objects' );
return array_keys( $all_post_types );
}
// Not all extra_post_types might be registered on this particular site
/*if( $this->networkactive ) {
foreach( (array) $this->options['extra_post_types'] as $extra ) {
if( post_type_exists( $extra ) ) {
$types[] = $extra;
}
}
}*/
if ( is_array( $post_types ) ) {
return $post_types;
}
return explode( ',', $post_types );
}

View File

@@ -0,0 +1,119 @@
<?php
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Plugin class
*
* @author Alex Kovalev <alex.kovalevv@gmail.com>
* @copyright (c) 19.02.2018, Webcraftic
*/
class WCM_Plugin extends Wbcr_Factory480_Plugin {
/**
* @see self::app()
* @var Wbcr_Factory480_Plugin
*/
private static $app;
/**
* @since 3.1.0
* @var array
*/
private $plugin_data;
/**
* Конструктор
*
* Применяет конструктор родительского класса и записывает экземпляр текущего класса в свойство $app.
* Подробнее о свойстве $app см. self::app()
*
* @param string $plugin_path
* @param array $data
*
* @throws Exception
*/
public function __construct( $plugin_path, $data ) {
parent::__construct( $plugin_path, $data );
self::$app = $this;
$this->plugin_data = $data;
$this->global_scripts();
if ( is_admin() ) {
$this->admin_scripts();
}
add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ] );
// Wordpress 6.7 fix
add_action( 'init', function () {
if ( is_admin() ) {
$this->register_pages();
}
} );
}
/**
* Статический метод для быстрого доступа к интерфейсу плагина.
*
* Позволяет разработчику глобально получить доступ к экземпляру класса плагина в любом месте
* плагина, но при этом разработчик не может вносить изменения в основной класс плагина.
*
* Используется для получения настроек плагина, информации о плагине, для доступа к вспомогательным
* классам.
*
* @return \Wbcr_Factory480_Plugin|\WCM_Plugin
*/
public static function app() {
return self::$app;
}
/**
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @throws \Exception
*/
public function plugins_loaded() {
}
/**
* Регистрирует классы страниц в плагине
*
* Мы указываем плагину, где найти файлы страниц и какое имя у их класса. Чтобы плагин
* выполнил подключение классов страниц. После регистрации, страницы будут доступные по url
* и в меню боковой панели администратора. Регистрируемые страницы будут связаны с текущим плагином
* все операции выполняемые внутри классов страниц, имеют отношение только текущему плагину.
*
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
* @throws \Exception
*/
private function register_pages() {
$admin_path = WCM_PLUGIN_DIR . '/admin/pages';
self::app()->registerPage( 'WbcrCmp_CommentsPage', $admin_path . '/class-page-comments.php' );
self::app()->registerPage( 'WbcrCmp_DeleteCommentsPage', $admin_path . '/class-page-delete-comments.php' );
self::app()->registerPage( 'WbcrCmp_MoreFeaturesPage', $admin_path . '/class-page-more-features.php' );
}
/**
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
*/
private function admin_scripts() {
require( WCM_PLUGIN_DIR . '/admin/boot.php' );
}
/**
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
*/
private function global_scripts() {
require( WCM_PLUGIN_DIR . '/includes/boot.php' );
require( WCM_PLUGIN_DIR . '/includes/classes/class-configurate-comments.php' );
new WbcrCmp_ConfigComments( self::$app );
}
}

View File

@@ -0,0 +1,338 @@
<?php
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* This class configures the parameters advanced
*
* @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
*
* @copyright (c) 2017 Webraftic Ltd
*/
class WbcrCmp_ConfigComments extends WBCR\Factory_Templates_134\Configurate {
private $modified_types = [];
/**
* @param Wbcr_Factory480_Plugin $plugin
*/
public function __construct( Wbcr_Factory480_Plugin $plugin ) {
parent::__construct( $plugin );
$this->plugin = $plugin;
}
public function registerActionsAndFilters() {
// These need to happen now
if ( $this->isDisabledAllPosts() ) {
add_action( 'widgets_init', [ $this, 'disableRcWidget' ] );
add_action( 'template_redirect', [ $this, 'filterQuery' ], 9 ); // before redirect_canonical
// Admin bar filtering has to happen here since WP 3.6
add_action( 'template_redirect', [ $this, 'filterAdminBar' ] );
add_action( 'admin_init', [ $this, 'filterAdminBar' ] );
} else {
if ( $this->getPopulateOption( 'comment_text_convert_links_pseudo' ) || $this->getPopulateOption( 'pseudo_comment_author_link' ) ) {
add_action( 'wp_enqueue_scripts', [ $this, 'assetsUrlSpanScripts' ] );
}
if ( $this->getPopulateOption( 'comment_text_convert_links_pseudo' ) ) {
add_filter( 'comment_text', [ $this, 'commentTextConvertLinksPseudo' ] );
}
if ( $this->getPopulateOption( 'pseudo_comment_author_link' ) ) {
add_filter( 'get_comment_author_link', [ $this, 'pseudoCommentAuthorLink' ], 100, 3 );
}
if ( $this->getPopulateOption( 'remove_url_from_comment_form' ) ) {
add_filter( 'comment_form_default_fields', [ $this, 'removeUrlFromCommentForm' ] );
}
}
// These can happen later
//add_action('plugins_loaded', array($this, 'register_text_domain'));
add_action( 'wp_loaded', [ $this, 'initWploadedFilters' ] );
}
/*
* Remove comment links from the admin bar in a multisite network.
*/
public function removeNetworkCommentLinks( $wp_admin_bar ) {
if ( $this->plugin->isNetworkActive() && is_user_logged_in() ) {
foreach ( (array) $wp_admin_bar->user->blogs as $blog ) {
$wp_admin_bar->remove_menu( 'blog-' . $blog->userblog_id . '-c' );
}
} else {
// We have no way to know whether the plugin is active on other sites, so only remove this one
$wp_admin_bar->remove_menu( 'blog-' . get_current_blog_id() . '-c' );
}
}
private function isDisabledAllPosts() {
return $this->getPopulateOption( 'disable_comments', 'enable_comments' ) == 'disable_comments';
}
private function isDisabledCertainPostTypes() {
return $this->getPopulateOption( 'disable_comments', 'enable_comments' ) == 'disable_certain_post_types_comments';
}
private function isEnabledComments() {
return $this->getPopulateOption( 'disable_comments', 'enable_comments' ) == 'enable_comments';
}
/*
* Get an array of disabled post type.
*/
private function getDisabledPostTypes() {
return wbcr_cmp_get_disabled_post_types();
}
/*
* Check whether comments have been disabled on a given post type.
*/
private function isPostTypeDisabled( $type ) {
return $this->isDisabledCertainPostTypes() && in_array( $type, $this->getDisabledPostTypes() );
}
public function initWploadedFilters() {
$disabled_post_types = $this->getDisabledPostTypes();
if ( ! empty( $disabled_post_types ) && ! $this->isEnabledComments() ) {
foreach ( $disabled_post_types as $type ) {
// we need to know what native support was for later
if ( post_type_supports( $type, 'comments' ) ) {
$this->modified_types[] = $type;
remove_post_type_support( $type, 'comments' );
remove_post_type_support( $type, 'trackbacks' );
}
}
add_filter( 'comments_array', [ $this, 'filterExistingComments' ], 20, 2 );
add_filter( 'comments_open', [ $this, 'filterCommentStatus' ], 20, 2 );
add_filter( 'pings_open', [ $this, 'filterCommentStatus' ], 20, 2 );
}
// Filters for the admin only
if ( is_admin() ) {
add_action( 'admin_print_footer_scripts', [ $this, 'discussionNotice' ] );
// if only certain types are disabled, remember the original post status
if ( ! $this->isDisabledAllPosts() ) {
add_action( 'edit_form_advanced', [ $this, 'editFormInputs' ] );
add_action( 'edit_page_form', [ $this, 'editFormInputs' ] );
} else {
add_action( 'admin_menu', [ $this, 'filterAdminMenu' ], 9999 ); // do this as late as possible
add_action( 'admin_print_footer_scripts-index.php', [ $this, 'dashboardJs' ] );
add_action( 'wp_dashboard_setup', [ $this, 'filterDashboard' ] );
add_filter( 'pre_option_default_pingback_flag', '__return_zero' );
}
} // Filters for front end only
else {
add_action( 'template_redirect', [ $this, 'checkCommentTemplate' ] );
if ( $this->isDisabledAllPosts() ) {
add_filter( 'feed_links_show_comments_feed', '__return_false' );
}
}
}
/*
* Replace the theme's comment template with a blank one.
* To prevent this, define DISABLE_COMMENTS_REMOVE_COMMENTS_TEMPLATE
* and set it to True
*/
public function checkCommentTemplate() {
if ( is_singular() && ( $this->isDisabledAllPosts() || $this->isPostTypeDisabled( get_post_type() ) ) ) {
if ( ! defined( 'DISABLE_COMMENTS_REMOVE_COMMENTS_TEMPLATE' ) || DISABLE_COMMENTS_REMOVE_COMMENTS_TEMPLATE == true ) {
// Kill the comments template.
add_filter( 'comments_template', [ $this, 'dummyCommentsTemplate' ], 20 );
}
// Remove comment-reply script for themes that include it indiscriminately
wp_deregister_script( 'comment-reply' );
// feed_links_extra inserts a comments RSS link
remove_action( 'wp_head', 'feed_links_extra', 3 );
}
}
public function dummyCommentsTemplate() {
return WCM_PLUGIN_DIR . '/includes/comments-template.php';
}
/*
* Issue a 403 for all comment feed requests.
*/
public function filterQuery() {
if ( is_comment_feed() ) {
wp_die( __( 'Comments are closed.' ), '', [ 'response' => 403 ] );
}
}
/*
* Remove comment links from the admin bar.
*/
public function filterAdminBar() {
if ( is_admin_bar_showing() ) {
// Remove comments links from admin bar
remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 60 );
}
if ( is_multisite() ) {
add_action( 'admin_bar_menu', [ $this, 'removeNetworkCommentLinks' ], 500 );
}
}
public function editFormInputs() {
global $post;
// Without a dicussion meta box, comment_status will be set to closed on new/updated posts
if ( in_array( $post->post_type, $this->modified_types ) ) {
echo '<input type="hidden" name="comment_status" value="' . $post->comment_status . '" /><input type="hidden" name="ping_status" value="' . $post->ping_status . '" />';
}
}
public function discussionNotice() {
$disabled_post_types = $this->getDisabledPostTypes();
if ( get_current_screen()->id == 'options-discussion' && ! empty( $disabled_post_types ) ) {
$names = [];
foreach ( $disabled_post_types as $type ) {
$type_object = get_post_type_object( $type );
if ( empty( $type_object ) ) {
continue;
}
$names[ $type ] = $type_object->labels->name;
}
?>
<script>
jQuery(document).ready(function($) {
$(".wrap h2").first().after(<?php echo json_encode( '<div style="color: #900"><p>' . sprintf( __( 'Note: The <em>%s</em> plugin is currently active, and comments are completely disabled on: %s. Many of the settings below will not be applicable for those post types.', 'comments-plus' ), $this->plugin->getPluginTitle(), implode( ', ', $names ) ) . '</p></div>' );?>);
});
</script>
<?php
}
}
public function filterAdminMenu() {
global $pagenow;
if ( $pagenow == 'comment.php' || $pagenow == 'edit-comments.php' || $pagenow == 'options-discussion.php' ) {
wp_die( __( 'Comments are closed.' ), '', [ 'response' => 403 ] );
}
remove_menu_page( 'edit-comments.php' );
remove_submenu_page( 'options-general.php', 'options-discussion.php' );
}
public function filterDashboard() {
remove_meta_box( 'dashboard_recent_comments', 'dashboard', 'normal' );
}
public function dashboardJs() {
echo '<script>
jQuery(function($){
$("#dashboard_right_now .comment-count, #latest-comments").hide();
$("#welcome-panel .welcome-comments").parent().hide();
});
</script>';
}
public function filterExistingComments( $comments, $post_id ) {
$post = get_post( $post_id );
return ( $this->isDisabledAllPosts() || $this->isPostTypeDisabled( $post->post_type ) ) ? [] : $comments;
}
public function filterCommentStatus( $open, $post_id ) {
$post = get_post( $post_id );
return ( $this->isDisabledAllPosts() || $this->isPostTypeDisabled( $post->post_type ) ) ? false : $open;
}
public function disableRcWidget() {
unregister_widget( 'WP_Widget_Recent_Comments' );
}
/**
* Convert links in comment text into span pseudo links
*
* @param $comment_text
*
* @return mixed
*/
public function commentTextConvertLinksPseudo( $comment_text ) {
return $this->convertLinksPseudo( $comment_text );
}
/**
* Convert links into span pseudo links
*
* @param $text
*
* @return mixed
*/
public function convertLinksPseudo( $text ) {
return preg_replace_callback( '/<a[^>]+href=[\'"](https?:\/\/[^"\']+)[\'"][^>]+>(.*?)<\/a>/i', [
$this,
'replaceLinks'
], $text );
}
public function replaceLinks( $matches ) {
if ( $matches[1] == get_home_url() ) {
return $matches[0];
}
return '<span class="wbcr-clearfy-pseudo-link" data-uri="' . $matches[1] . '" > ' . $matches[2] . '</span>';
}
/**
* Convert author link to pseudo link
*
* @return string
*/
public function pseudoCommentAuthorLink( $return, $author, $comment_ID ) {
$url = get_comment_author_url( $comment_ID );
$author = get_comment_author( $comment_ID );
if ( empty( $url ) || 'http://' == $url ) {
$return = $author;
} else {
$return = '<span class="wbcr-clearfy-pseudo-link" data-uri="' . $url . '">' . $author . '</span>';
}
return $return;
}
/**
* Remove url field from comment form
*
* @param $fields
*
* @return mixed
*/
public function removeUrlFromCommentForm( $fields ) {
if ( isset( $fields['url'] ) ) {
unset( $fields['url'] );
}
return $fields;
}
// todo: Убрать это грязное решение со скриптами.
public function assetsUrlSpanScripts() {
if ( ! is_singular() ) {
return;
}
wp_enqueue_style( 'wbcr-comments-plus-url-span', WCM_PLUGIN_URL . '/assets/css/url-span.css', [], $this->plugin->getPluginVersion() );
wp_enqueue_script( 'wbcr-comments-plus-url-span', WCM_PLUGIN_URL . '/assets/js/url-span.js', [ 'jquery' ], $this->plugin->getPluginVersion(), true );
}
}

View File

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

View File

@@ -0,0 +1,4 @@
<?php
/* Dummy comments template file.
* This replaces the theme's comment template when comments are disabled everywhere
*/

View File

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