delete wordpress content
Este commit está contenido en:
@@ -1,227 +0,0 @@
|
||||
# This is the main Apache server configuration file. It contains the
|
||||
# configuration directives that give the server its instructions.
|
||||
# See http://httpd.apache.org/docs/2.4/ for detailed information about
|
||||
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
|
||||
# hints.
|
||||
#
|
||||
#
|
||||
# Summary of how the Apache 2 configuration works in Debian:
|
||||
# The Apache 2 web server configuration in Debian is quite different to
|
||||
# upstream's suggested way to configure the web server. This is because Debian's
|
||||
# default Apache2 installation attempts to make adding and removing modules,
|
||||
# virtual hosts, and extra configuration directives as flexible as possible, in
|
||||
# order to make automating the changes and administering the server as easy as
|
||||
# possible.
|
||||
|
||||
# It is split into several files forming the configuration hierarchy outlined
|
||||
# below, all located in the /etc/apache2/ directory:
|
||||
#
|
||||
# /etc/apache2/
|
||||
# |-- apache2.conf
|
||||
# | `-- ports.conf
|
||||
# |-- mods-enabled
|
||||
# | |-- *.load
|
||||
# | `-- *.conf
|
||||
# |-- conf-enabled
|
||||
# | `-- *.conf
|
||||
# `-- sites-enabled
|
||||
# `-- *.conf
|
||||
#
|
||||
#
|
||||
# * apache2.conf is the main configuration file (this file). It puts the pieces
|
||||
# together by including all remaining configuration files when starting up the
|
||||
# web server.
|
||||
#
|
||||
# * ports.conf is always included from the main configuration file. It is
|
||||
# supposed to determine listening ports for incoming connections which can be
|
||||
# customized anytime.
|
||||
#
|
||||
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
|
||||
# directories contain particular configuration snippets which manage modules,
|
||||
# global configuration fragments, or virtual host configurations,
|
||||
# respectively.
|
||||
#
|
||||
# They are activated by symlinking available configuration files from their
|
||||
# respective *-available/ counterparts. These should be managed by using our
|
||||
# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
|
||||
# their respective man pages for detailed information.
|
||||
#
|
||||
# * The binary is called apache2. Due to the use of environment variables, in
|
||||
# the default configuration, apache2 needs to be started/stopped with
|
||||
# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
|
||||
# work with the default configuration.
|
||||
|
||||
|
||||
# Global configuration
|
||||
#
|
||||
|
||||
#
|
||||
# ServerRoot: The top of the directory tree under which the server's
|
||||
# configuration, error, and log files are kept.
|
||||
#
|
||||
# NOTE! If you intend to place this on an NFS (or otherwise network)
|
||||
# mounted filesystem then please read the Mutex documentation (available
|
||||
# at <URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex>);
|
||||
# you will save yourself a lot of trouble.
|
||||
#
|
||||
# Do NOT add a slash at the end of the directory path.
|
||||
#
|
||||
#ServerRoot "/etc/apache2"
|
||||
|
||||
#
|
||||
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
|
||||
#
|
||||
#Mutex file:${APACHE_LOCK_DIR} default
|
||||
|
||||
#
|
||||
# The directory where shm and other runtime files will be stored.
|
||||
#
|
||||
|
||||
DefaultRuntimeDir ${APACHE_RUN_DIR}
|
||||
|
||||
#
|
||||
# PidFile: The file in which the server should record its process
|
||||
# identification number when it starts.
|
||||
# This needs to be set in /etc/apache2/envvars
|
||||
#
|
||||
PidFile ${APACHE_PID_FILE}
|
||||
|
||||
#
|
||||
# Timeout: The number of seconds before receives and sends time out.
|
||||
#
|
||||
Timeout 300
|
||||
|
||||
#
|
||||
# KeepAlive: Whether or not to allow persistent connections (more than
|
||||
# one request per connection). Set to "Off" to deactivate.
|
||||
#
|
||||
KeepAlive On
|
||||
|
||||
#
|
||||
# MaxKeepAliveRequests: The maximum number of requests to allow
|
||||
# during a persistent connection. Set to 0 to allow an unlimited amount.
|
||||
# We recommend you leave this number high, for maximum performance.
|
||||
#
|
||||
MaxKeepAliveRequests 100
|
||||
|
||||
#
|
||||
# KeepAliveTimeout: Number of seconds to wait for the next request from the
|
||||
# same client on the same connection.
|
||||
#
|
||||
KeepAliveTimeout 5
|
||||
|
||||
|
||||
# These need to be set in /etc/apache2/envvars
|
||||
User ${APACHE_RUN_USER}
|
||||
Group ${APACHE_RUN_GROUP}
|
||||
|
||||
#
|
||||
# HostnameLookups: Log the names of clients or just their IP addresses
|
||||
# e.g., www.apache.org (on) or 204.62.129.132 (off).
|
||||
# The default is off because it'd be overall better for the net if people
|
||||
# had to knowingly turn this feature on, since enabling it means that
|
||||
# each client request will result in AT LEAST one lookup request to the
|
||||
# nameserver.
|
||||
#
|
||||
HostnameLookups Off
|
||||
|
||||
# ErrorLog: The location of the error log file.
|
||||
# If you do not specify an ErrorLog directive within a <VirtualHost>
|
||||
# container, error messages relating to that virtual host will be
|
||||
# logged here. If you *do* define an error logfile for a <VirtualHost>
|
||||
# container, that host's errors will be logged there and not here.
|
||||
#
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
|
||||
#
|
||||
# LogLevel: Control the severity of messages logged to the error_log.
|
||||
# Available values: trace8, ..., trace1, debug, info, notice, warn,
|
||||
# error, crit, alert, emerg.
|
||||
# It is also possible to configure the log level for particular modules, e.g.
|
||||
# "LogLevel info ssl:warn"
|
||||
#
|
||||
LogLevel warn
|
||||
|
||||
# Include module configuration:
|
||||
IncludeOptional mods-enabled/*.load
|
||||
IncludeOptional mods-enabled/*.conf
|
||||
|
||||
# Include list of ports to listen on
|
||||
Include ports.conf
|
||||
|
||||
|
||||
# Sets the default security model of the Apache2 HTTPD server. It does
|
||||
# not allow access to the root filesystem outside of /usr/share and /var/www.
|
||||
# The former is used by web applications packaged in Debian,
|
||||
# the latter may be used for local directories served by the web server. If
|
||||
# your system is serving content from a sub-directory in /srv you must allow
|
||||
# access here, or in any related virtual host.
|
||||
<Directory />
|
||||
Options FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all denied
|
||||
</Directory>
|
||||
|
||||
<Directory /usr/share>
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<Directory /var/www/>
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
#<Directory /srv/>
|
||||
# Options Indexes FollowSymLinks
|
||||
# AllowOverride None
|
||||
# Require all granted
|
||||
#</Directory>
|
||||
|
||||
|
||||
|
||||
|
||||
# AccessFileName: The name of the file to look for in each directory
|
||||
# for additional configuration directives. See also the AllowOverride
|
||||
# directive.
|
||||
#
|
||||
AccessFileName .htaccess
|
||||
|
||||
#
|
||||
# The following lines prevent .htaccess and .htpasswd files from being
|
||||
# viewed by Web clients.
|
||||
#
|
||||
<FilesMatch "^\.ht">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
|
||||
|
||||
#
|
||||
# The following directives define some format nicknames for use with
|
||||
# a CustomLog directive.
|
||||
#
|
||||
# These deviate from the Common Log Format definitions in that they use %O
|
||||
# (the actual bytes sent including headers) instead of %b (the size of the
|
||||
# requested file), because the latter makes it impossible to detect partial
|
||||
# requests.
|
||||
#
|
||||
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
|
||||
# Use mod_remoteip instead.
|
||||
#
|
||||
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
|
||||
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %O" common
|
||||
LogFormat "%{Referer}i -> %U" referer
|
||||
LogFormat "%{User-agent}i" agent
|
||||
|
||||
# Include of directories ignores editors' and dpkg's backup files,
|
||||
# see README.Debian for details.
|
||||
|
||||
# Include generic snippets of statements
|
||||
IncludeOptional conf-enabled/*.conf
|
||||
|
||||
# Include the virtual host configurations:
|
||||
IncludeOptional sites-enabled/*.conf
|
||||
|
||||
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||
@@ -1,28 +0,0 @@
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="300.000000pt" height="300.000000pt" viewBox="0 0 300.000000 300.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,300.000000) scale(0.100000,-0.100000)"
|
||||
fill="#222" stroke="none">
|
||||
<path d="M468 2057 l22 -23 0 -533 c0 -362 -3 -539 -11 -553 -6 -11 -9 -21 -7
|
||||
-23 2 -2 53 36 113 84 61 48 163 128 228 177 l118 91 -1 369 -1 369 -31 32
|
||||
-32 33 -210 0 -209 0 21 -23z m282 -376 l0 -220 -37 -30 c-21 -17 -41 -31 -45
|
||||
-31 -5 0 -8 113 -8 250 l0 250 45 0 45 0 0 -219z"/>
|
||||
<path d="M1012 2047 l-32 -33 0 -352 0 -352 83 -66 c122 -97 112 -96 201 -31
|
||||
42 30 94 70 116 88 l40 33 0 341 0 341 -33 32 -33 32 -155 0 -155 0 -32 -33z
|
||||
m238 -397 c0 -137 -3 -250 -6 -250 -4 0 -27 16 -50 36 l-44 35 0 215 0 214 50
|
||||
0 50 0 0 -250z"/>
|
||||
<path d="M1492 2047 l-32 -33 0 -341 0 -341 109 -86 c60 -47 112 -86 116 -86
|
||||
4 0 50 34 103 76 53 42 102 79 109 81 10 4 13 82 13 357 l0 352 -28 27 -28 27
|
||||
-165 0 -165 0 -32 -33z m238 -366 l0 -219 -32 -24 c-18 -13 -39 -28 -45 -32
|
||||
-10 -6 -13 46 -13 243 l0 251 45 0 45 0 0 -219z"/>
|
||||
<path d="M1938 2057 c22 -23 22 -28 22 -379 0 -253 -3 -357 -11 -360 -10 -3
|
||||
141 -128 155 -128 3 0 6 84 7 188 l1 187 14 -70 c8 -38 19 -79 24 -90 4 -11
|
||||
20 -74 35 -140 14 -66 27 -121 29 -122 3 -3 32 89 72 232 l23 80 0 -200 c1
|
||||
-132 -3 -205 -10 -212 -8 -8 6 -23 46 -54 32 -24 76 -61 98 -82 23 -20 45 -37
|
||||
49 -37 11 0 10 28 -2 35 -6 4 -10 204 -10 567 0 510 1 562 17 573 34 25 4 35
|
||||
-112 35 l-113 0 -16 -42 c-8 -24 -21 -65 -29 -93 l-13 -50 -18 75 c-10 41 -20
|
||||
83 -23 93 -4 15 -19 17 -130 17 l-126 0 21 -23z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Antes Anchura: | Altura: | Tamaño: 1.5 KiB |
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying the footer
|
||||
*
|
||||
* Contains the closing of the #content div and all content after.
|
||||
*
|
||||
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Twenty_Seventeen
|
||||
* @since 1.0
|
||||
* @version 1.2
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
</div><!-- #content -->
|
||||
|
||||
<footer id="colophon" class="site-footer" role="contentinfo">
|
||||
<div class="wrap">
|
||||
<?php
|
||||
get_template_part( 'template-parts/footer/footer', 'widgets' );
|
||||
|
||||
if ( has_nav_menu( 'social' ) ) :
|
||||
?>
|
||||
<nav class="social-navigation" role="navigation" aria-label="<?php esc_attr_e( 'Footer Social Links Menu', 'twentyseventeen' ); ?>">
|
||||
<?php
|
||||
wp_nav_menu(
|
||||
array(
|
||||
'theme_location' => 'social',
|
||||
'menu_class' => 'social-links-menu',
|
||||
'depth' => 1,
|
||||
'link_before' => '<span class="screen-reader-text">',
|
||||
'link_after' => '</span>' . twentyseventeen_get_svg( array( 'icon' => 'chain' ) ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</nav><!-- .social-navigation -->
|
||||
<?php
|
||||
endif;
|
||||
|
||||
get_template_part( 'template-parts/footer/site', 'info' );
|
||||
?>
|
||||
</div><!-- .wrap -->
|
||||
</footer><!-- #colophon -->
|
||||
</div><!-- .site-content-contain -->
|
||||
</div><!-- #page -->
|
||||
<?php wp_footer(); ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The header for our theme
|
||||
*
|
||||
* This is the template that displays all of the <head> section and everything up until <div id="content">
|
||||
*
|
||||
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Twenty_Seventeen
|
||||
* @since 1.0
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html <?php language_attributes(); ?> class="no-js no-svg">
|
||||
<head>
|
||||
<meta charset="<?php bloginfo( 'charset' ); ?>">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="profile" href="http://gmpg.org/xfn/11">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.1.7/css/fork-awesome.min.css" integrity="sha256-gsmEoJAws/Kd3CjuOQzLie5Q3yshhvmo7YNtBG7aaEY=" crossorigin="anonymous">
|
||||
|
||||
<?php wp_head(); ?>
|
||||
</head>
|
||||
|
||||
<body <?php body_class(); ?>>
|
||||
<?php wp_body_open(); ?>
|
||||
<div id="page" class="site">
|
||||
<a class="skip-link screen-reader-text" href="#content"><?php _e( 'Skip to content', 'twentyseventeen' ); ?></a>
|
||||
|
||||
<header id="masthead" class="site-header" role="banner">
|
||||
|
||||
<?php get_template_part( 'template-parts/header/header', 'image' ); ?>
|
||||
|
||||
<?php if ( has_nav_menu( 'top' ) ) : ?>
|
||||
<div class="navigation-top">
|
||||
<div class="wrap">
|
||||
<?php get_template_part( 'template-parts/navigation/navigation', 'top' ); ?>
|
||||
</div><!-- .wrap -->
|
||||
</div><!-- .navigation-top -->
|
||||
<?php endif; ?>
|
||||
|
||||
</header><!-- #masthead -->
|
||||
|
||||
<?php
|
||||
|
||||
/*
|
||||
* If a regular post or page, and not the front page, show the featured image.
|
||||
* Using get_queried_object_id() here since the $post global may not be set before a call to the_post().
|
||||
*/
|
||||
if ( ( is_single() || ( is_page() && ! twentyseventeen_is_frontpage() ) ) && has_post_thumbnail( get_queried_object_id() ) ) :
|
||||
echo '<div class="single-featured-image-header">';
|
||||
echo get_the_post_thumbnail( get_queried_object_id(), 'twentyseventeen-featured-image' );
|
||||
echo '</div><!-- .single-featured-image-header -->';
|
||||
endif;
|
||||
?>
|
||||
|
||||
<div class="site-content-contain">
|
||||
<div id="content" class="site-content">
|
||||
@@ -1,227 +0,0 @@
|
||||
# BEGIN LSCACHE
|
||||
## LITESPEED WP CACHE PLUGIN - Do not edit the contents of this block! ##
|
||||
<IfModule LiteSpeed>
|
||||
RewriteEngine on
|
||||
CacheLookup on
|
||||
RewriteRule .* - [E=Cache-Control:no-autoflush]
|
||||
|
||||
### marker CACHE RESOURCE start ###
|
||||
RewriteRule wp-content/.*/[^/]*(responsive|css|js|dynamic|loader|fonts)\.php - [E=cache-control:max-age=3600]
|
||||
### marker CACHE RESOURCE end ###
|
||||
|
||||
### marker FAVICON start ###
|
||||
RewriteRule favicon\.ico$ - [E=cache-control:max-age=86400]
|
||||
### marker FAVICON end ###
|
||||
|
||||
### marker DROPQS start ###
|
||||
CacheKeyModify -qs:fbclid
|
||||
CacheKeyModify -qs:gclid
|
||||
CacheKeyModify -qs:utm*
|
||||
CacheKeyModify -qs:_ga
|
||||
### marker DROPQS end ###
|
||||
|
||||
</IfModule>
|
||||
## LITESPEED WP CACHE PLUGIN - Do not edit the contents of this block! ##
|
||||
# END LSCACHE
|
||||
# BEGIN NON_LSCACHE
|
||||
## LITESPEED WP CACHE PLUGIN - Do not edit the contents of this block! ##
|
||||
### marker BROWSER CACHE start ###
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive on
|
||||
ExpiresByType application/pdf A31557600
|
||||
ExpiresByType image/x-icon A31557600
|
||||
ExpiresByType image/vnd.microsoft.icon A31557600
|
||||
ExpiresByType image/svg+xml A31557600
|
||||
|
||||
ExpiresByType image/jpg A31557600
|
||||
ExpiresByType image/jpeg A31557600
|
||||
ExpiresByType image/png A31557600
|
||||
ExpiresByType image/gif A31557600
|
||||
ExpiresByType image/webp A31557600
|
||||
|
||||
ExpiresByType video/ogg A31557600
|
||||
ExpiresByType audio/ogg A31557600
|
||||
ExpiresByType video/mp4 A31557600
|
||||
ExpiresByType video/webm A31557600
|
||||
|
||||
ExpiresByType text/css A31557600
|
||||
ExpiresByType text/javascript A31557600
|
||||
ExpiresByType application/javascript A31557600
|
||||
ExpiresByType application/x-javascript A31557600
|
||||
|
||||
ExpiresByType application/x-font-ttf A31557600
|
||||
ExpiresByType application/x-font-woff A31557600
|
||||
ExpiresByType application/font-woff A31557600
|
||||
ExpiresByType application/font-woff2 A31557600
|
||||
ExpiresByType application/vnd.ms-fontobject A31557600
|
||||
ExpiresByType font/ttf A31557600
|
||||
ExpiresByType font/woff A31557600
|
||||
ExpiresByType font/woff2 A31557600
|
||||
|
||||
</IfModule>
|
||||
### marker BROWSER CACHE end ###
|
||||
|
||||
## LITESPEED WP CACHE PLUGIN - Do not edit the contents of this block! ##
|
||||
# END NON_LSCACHE
|
||||
# BEGIN All In One WP Security
|
||||
#AIOWPS_BASIC_HTACCESS_RULES_START
|
||||
<Files .htaccess>
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
</IfModule>
|
||||
</Files>
|
||||
ServerSignature Off
|
||||
LimitRequestBody 10485760
|
||||
<Files wp-config.php>
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
</IfModule>
|
||||
</Files>
|
||||
#AIOWPS_BASIC_HTACCESS_RULES_END
|
||||
#AIOWPS_PINGBACK_HTACCESS_RULES_START
|
||||
<Files xmlrpc.php>
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
</IfModule>
|
||||
</Files>
|
||||
#AIOWPS_PINGBACK_HTACCESS_RULES_END
|
||||
#AIOWPS_DISABLE_INDEX_VIEWS_START
|
||||
Options -Indexes
|
||||
#AIOWPS_DISABLE_INDEX_VIEWS_END
|
||||
#AIOWPS_DENY_BAD_QUERY_STRINGS_START
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteCond %{QUERY_STRING} ftp: [NC,OR]
|
||||
RewriteCond %{QUERY_STRING} http: [NC,OR]
|
||||
RewriteCond %{QUERY_STRING} https: [NC,OR]
|
||||
RewriteCond %{QUERY_STRING} mosConfig [NC,OR]
|
||||
RewriteCond %{QUERY_STRING} ^.*(globals|encode|localhost|loopback).* [NC,OR]
|
||||
RewriteCond %{QUERY_STRING} (\;|'|\"|%22).*(request|insert|union|declare|drop) [NC]
|
||||
RewriteRule ^(.*)$ - [F,L]
|
||||
</IfModule>
|
||||
#AIOWPS_DENY_BAD_QUERY_STRINGS_END
|
||||
#AIOWPS_ADVANCED_CHAR_STRING_FILTER_START
|
||||
<IfModule mod_alias.c>
|
||||
RedirectMatch 403 \,
|
||||
RedirectMatch 403 \:
|
||||
RedirectMatch 403 \;
|
||||
RedirectMatch 403 \=
|
||||
RedirectMatch 403 \[
|
||||
RedirectMatch 403 \]
|
||||
RedirectMatch 403 \^
|
||||
RedirectMatch 403 \`
|
||||
RedirectMatch 403 \{
|
||||
RedirectMatch 403 \}
|
||||
RedirectMatch 403 \~
|
||||
RedirectMatch 403 \"
|
||||
RedirectMatch 403 \$
|
||||
RedirectMatch 403 \<
|
||||
RedirectMatch 403 \>
|
||||
RedirectMatch 403 \|
|
||||
RedirectMatch 403 \.\.
|
||||
RedirectMatch 403 \%0
|
||||
RedirectMatch 403 \%A
|
||||
RedirectMatch 403 \%B
|
||||
RedirectMatch 403 \%C
|
||||
RedirectMatch 403 \%D
|
||||
RedirectMatch 403 \%E
|
||||
RedirectMatch 403 \%F
|
||||
RedirectMatch 403 \%22
|
||||
RedirectMatch 403 \%27
|
||||
RedirectMatch 403 \%28
|
||||
RedirectMatch 403 \%29
|
||||
RedirectMatch 403 \%3C
|
||||
RedirectMatch 403 \%3E
|
||||
RedirectMatch 403 \%3F
|
||||
RedirectMatch 403 \%5B
|
||||
RedirectMatch 403 \%5C
|
||||
RedirectMatch 403 \%5D
|
||||
RedirectMatch 403 \%7B
|
||||
RedirectMatch 403 \%7C
|
||||
RedirectMatch 403 \%7D
|
||||
# COMMON PATTERNS
|
||||
Redirectmatch 403 \_vpi
|
||||
RedirectMatch 403 \.inc
|
||||
Redirectmatch 403 xAou6
|
||||
Redirectmatch 403 db\_name
|
||||
Redirectmatch 403 select\(
|
||||
Redirectmatch 403 convert\(
|
||||
Redirectmatch 403 \/query\/
|
||||
RedirectMatch 403 ImpEvData
|
||||
Redirectmatch 403 \.XMLHTTP
|
||||
Redirectmatch 403 proxydeny
|
||||
RedirectMatch 403 function\.
|
||||
Redirectmatch 403 remoteFile
|
||||
Redirectmatch 403 servername
|
||||
Redirectmatch 403 \&rptmode\=
|
||||
Redirectmatch 403 sys\_cpanel
|
||||
RedirectMatch 403 db\_connect
|
||||
RedirectMatch 403 doeditconfig
|
||||
RedirectMatch 403 check\_proxy
|
||||
Redirectmatch 403 system\_user
|
||||
Redirectmatch 403 \/\(null\)\/
|
||||
Redirectmatch 403 clientrequest
|
||||
Redirectmatch 403 option\_value
|
||||
RedirectMatch 403 ref\.outcontrol
|
||||
# SPECIFIC EXPLOITS
|
||||
RedirectMatch 403 errors\.
|
||||
RedirectMatch 403 config\.
|
||||
RedirectMatch 403 include\.
|
||||
RedirectMatch 403 display\.
|
||||
RedirectMatch 403 register\.
|
||||
Redirectmatch 403 password\.
|
||||
RedirectMatch 403 maincore\.
|
||||
RedirectMatch 403 authorize\.
|
||||
Redirectmatch 403 macromates\.
|
||||
RedirectMatch 403 head\_auth\.
|
||||
RedirectMatch 403 submit\_links\.
|
||||
RedirectMatch 403 change\_action\.
|
||||
Redirectmatch 403 com\_facileforms\/
|
||||
RedirectMatch 403 admin\_db\_utilities\.
|
||||
RedirectMatch 403 admin\.webring\.docs\.
|
||||
Redirectmatch 403 Table\/Latest\/index\.
|
||||
</IfModule>
|
||||
#AIOWPS_ADVANCED_CHAR_STRING_FILTER_END
|
||||
#AIOWPS_BLOCK_SPAMBOTS_START
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_METHOD} POST
|
||||
RewriteCond %{REQUEST_URI} ^(.*)?wp-comments-post\.php(.*)$
|
||||
RewriteCond %{HTTP_REFERER} !^http(s)?://(.*)?\.hatthieves\.es [NC,OR]
|
||||
RewriteCond %{HTTP_USER_AGENT} ^$
|
||||
RewriteRule .* http://127.0.0.1 [L]
|
||||
</IfModule>
|
||||
#AIOWPS_BLOCK_SPAMBOTS_END
|
||||
# END All In One WP Security
|
||||
|
||||
# BEGIN WordPress
|
||||
# Las directivas (líneas) entre `BEGIN WordPress` y `END WordPress` se generan dinámicamente
|
||||
# , y solo se deberían modificar mediante filtros de WordPress.
|
||||
# Cualquier cambio en las directivas que hay entre esos marcadores se sobreescribirán.
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
RewriteRule ^index\.php$ - [L]
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule . /index.php [L]
|
||||
</IfModule>
|
||||
|
||||
# END WordPress
|
||||
php_value upload_max_filesize 64M
|
||||
php_value post_max_size 128M
|
||||
php_value memory_limit 256M
|
||||
php_value max_execution_time 300
|
||||
php_value max_input_time 300
|
||||
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The base configuration for WordPress
|
||||
*
|
||||
* The wp-config.php creation script uses this file during the
|
||||
* installation. You don't have to use the web site, you can
|
||||
* copy this file to "wp-config.php" and fill in the values.
|
||||
*
|
||||
* This file contains the following configurations:
|
||||
*
|
||||
* * MySQL settings
|
||||
* * Secret keys
|
||||
* * Database table prefix
|
||||
* * ABSPATH
|
||||
*
|
||||
* @link https://codex.wordpress.org/Editing_wp-config.php
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
// ** MySQL settings - You can get this info from your web host ** //
|
||||
/** The name of the database for WordPress */
|
||||
define( 'DB_NAME', 'wordpress');
|
||||
|
||||
/** MySQL database username */
|
||||
define( 'DB_USER', 'wordpress');
|
||||
|
||||
/** MySQL database password */
|
||||
define( 'DB_PASSWORD', 'w0rdpr3ss.');
|
||||
|
||||
/** MySQL hostname */
|
||||
define( 'DB_HOST', 'mysql-wordpress:3306');
|
||||
|
||||
/** Database Charset to use in creating database tables. */
|
||||
define( 'DB_CHARSET', 'utf8');
|
||||
|
||||
/** The Database Collate type. Don't change this if in doubt. */
|
||||
define( 'DB_COLLATE', '');
|
||||
|
||||
/**#@+
|
||||
* Authentication Unique Keys and Salts.
|
||||
*
|
||||
* Change these to different unique phrases!
|
||||
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
|
||||
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*/
|
||||
define( 'AUTH_KEY', '93832ac51c3661a9b92173fb73c9b64c02ddf9f5');
|
||||
define( 'SECURE_AUTH_KEY', '9972adea6c141fdc3fb526d08d6086ece0d56b23');
|
||||
define( 'LOGGED_IN_KEY', '5dc8d02eba80bbb43426178a4698c8ec4bcf76ac');
|
||||
define( 'NONCE_KEY', '2147ce2326bd6cc7b9f79cc9ec6637140732346b');
|
||||
define( 'AUTH_SALT', '1fefe96398a39e1e8ec9eafb8aecfe5219735b5a');
|
||||
define( 'SECURE_AUTH_SALT', 'aff244a52b887f067f27fd50f37e9112af0d3ba0');
|
||||
define( 'LOGGED_IN_SALT', 'c6ad50e7b978c1b21d9de6f2d3ac3209eb03d1bb');
|
||||
define( 'NONCE_SALT', '62a17e140d2f5619c548e5c88fe3f98f4d6fb496');
|
||||
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* WordPress Database Table prefix.
|
||||
*
|
||||
* You can have multiple installations in one database if you give each
|
||||
* a unique prefix. Only numbers, letters, and underscores please!
|
||||
*/
|
||||
$table_prefix = 'wp_';
|
||||
|
||||
/**
|
||||
* For developers: WordPress debugging mode.
|
||||
*
|
||||
* Change this to true to enable the display of notices during development.
|
||||
* It is strongly recommended that plugin and theme developers use WP_DEBUG
|
||||
* in their development environments.
|
||||
*
|
||||
* For information on other constants that can be used for debugging,
|
||||
* visit the Codex.
|
||||
*
|
||||
* @link https://codex.wordpress.org/Debugging_in_WordPress
|
||||
*/
|
||||
define( 'WP_DEBUG', false );
|
||||
|
||||
// If we're behind a proxy server and using HTTPS, we need to alert Wordpress of that fact
|
||||
// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
||||
$_SERVER['HTTPS'] = 'on';
|
||||
}
|
||||
|
||||
/* That's all, stop editing! Happy publishing. */
|
||||
|
||||
/** Absolute path to the WordPress directory. */
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
define( 'ABSPATH', dirname( __FILE__ ) . '/' );
|
||||
}
|
||||
|
||||
// Use X-Forwarded-For HTTP Header to Get Visitor's Real IP Address
|
||||
if ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
|
||||
$http_x_headers = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );
|
||||
|
||||
$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
|
||||
}
|
||||
|
||||
/** Sets up WordPress vars and included files. */
|
||||
require_once( ABSPATH . 'wp-settings.php' );
|
||||
@@ -1,2 +0,0 @@
|
||||
order deny,allow
|
||||
deny from all
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
|
||||
# BEGIN WordPress
|
||||
# Las directivas (líneas) entre `BEGIN WordPress` y `END WordPress` se generan dinámicamente
|
||||
# , y solo se deberían modificar mediante filtros de WordPress.
|
||||
# Cualquier cambio en las directivas que hay entre esos marcadores se sobreescribirán.
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
RewriteRule ^index\.php$ - [L]
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule . /index.php [L]
|
||||
</IfModule>
|
||||
|
||||
# END WordPress
|
||||
php_value upload_max_filesize 64M
|
||||
php_value post_max_size 128M
|
||||
php_value memory_limit 256M
|
||||
php_value max_execution_time 300
|
||||
php_value max_input_time 300
|
||||
|
||||
Las diferiencias del archivo han sido suprimidas porque una o mas lineas son muy largas
@@ -1,2 +0,0 @@
|
||||
<?php
|
||||
// Silence is golden.
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
defined( 'WPINC' ) || exit ;
|
||||
/**
|
||||
* LiteSpeed Object Cache
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
|
||||
! defined( 'LSCWP_OBJECT_CACHE' ) && define( 'LSCWP_OBJECT_CACHE', true ) ;
|
||||
|
||||
// Initialize const `LSCWP_DIR` and locate LSCWP plugin foder
|
||||
$lscwp_dir = ( defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins' ) . '/litespeed-cache/' ;
|
||||
// Use plugin as higher priority than MU plugin
|
||||
if ( ! file_exists( $lscwp_dir . 'litespeed-cache.php' ) ) {
|
||||
// Check if is mu plugin or not
|
||||
$lscwp_dir = ( defined( 'WPMU_PLUGIN_DIR' ) ? WPMU_PLUGIN_DIR : WP_CONTENT_DIR . '/mu-plugins' ) . '/litespeed-cache/' ;
|
||||
if ( ! file_exists( $lscwp_dir . 'litespeed-cache.php' ) ) {
|
||||
$lscwp_dir = '' ;
|
||||
}
|
||||
}
|
||||
|
||||
$data_file = WP_CONTENT_DIR . '/.object-cache.ini' ;
|
||||
$lib_file = $lscwp_dir . 'src/object.lib.php' ;
|
||||
|
||||
// Can't find LSCWP location, terminate object cache process
|
||||
if ( ! $lscwp_dir || ! file_exists( $data_file ) || ( ! file_exists( $lib_file ) ) ) {
|
||||
if ( ! is_admin() ) { // Bypass object cache for frontend
|
||||
require_once ABSPATH . WPINC . '/cache.php' ;
|
||||
}
|
||||
else {
|
||||
$err = 'Can NOT find LSCWP path for object cache initialization in ' . __FILE__ ;
|
||||
error_log( $err ) ;
|
||||
echo $err ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Init object cache & LSCWP
|
||||
if ( file_exists( $lib_file ) ) {
|
||||
require_once $lib_file ;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Matthias Pfefferle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,100 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: ActivityPub
|
||||
* Plugin URI: https://github.com/pfefferle/wordpress-activitypub/
|
||||
* Description: The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format.
|
||||
* Version: 0.10.1
|
||||
* Author: Matthias Pfefferle
|
||||
* Author URI: https://notiz.blog/
|
||||
* License: MIT
|
||||
* License URI: http://opensource.org/licenses/MIT
|
||||
* Requires PHP: 5.6
|
||||
* Text Domain: activitypub
|
||||
* Domain Path: /languages
|
||||
*/
|
||||
|
||||
namespace Activitypub;
|
||||
|
||||
/**
|
||||
* Initialize plugin
|
||||
*/
|
||||
function init() {
|
||||
\defined( 'ACTIVITYPUB_HASHTAGS_REGEXP' ) || \define( 'ACTIVITYPUB_HASHTAGS_REGEXP', '(?:(?<=\s)|^)#(\w*[A-Za-z_]+\w*)' );
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/table/followers-list.php';
|
||||
require_once \dirname( __FILE__ ) . '/includes/class-signature.php';
|
||||
require_once \dirname( __FILE__ ) . '/includes/peer/class-followers.php';
|
||||
require_once \dirname( __FILE__ ) . '/includes/functions.php';
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/class-activity-dispatcher.php';
|
||||
\Activitypub\Activity_Dispatcher::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/model/class-activity.php';
|
||||
require_once \dirname( __FILE__ ) . '/includes/model/class-post.php';
|
||||
\Activitypub\Model\Post::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/class-activitypub.php';
|
||||
\Activitypub\Activitypub::init();
|
||||
|
||||
// Configure the REST API route
|
||||
require_once \dirname( __FILE__ ) . '/includes/rest/class-outbox.php';
|
||||
\Activitypub\Rest\Outbox::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/rest/class-inbox.php';
|
||||
\Activitypub\Rest\Inbox::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/rest/class-followers.php';
|
||||
\Activitypub\Rest\Followers::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/rest/class-following.php';
|
||||
\Activitypub\Rest\Following::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/rest/class-webfinger.php';
|
||||
\Activitypub\Rest\Webfinger::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/rest/class-nodeinfo.php';
|
||||
\Activitypub\Rest\NodeInfo::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/class-admin.php';
|
||||
\Activitypub\Admin::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/class-hashtag.php';
|
||||
\Activitypub\Hashtag::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/class-debug.php';
|
||||
\Activitypub\Debug::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/class-health-check.php';
|
||||
\Activitypub\Health_Check::init();
|
||||
|
||||
require_once \dirname( __FILE__ ) . '/includes/rest/class-server.php';
|
||||
\add_filter( 'wp_rest_server_class', function() {
|
||||
return '\Activitypub\Rest\Server';
|
||||
} );
|
||||
}
|
||||
add_action( 'plugins_loaded', '\Activitypub\init' );
|
||||
|
||||
/**
|
||||
* Add rewrite rules
|
||||
*/
|
||||
function add_rewrite_rules() {
|
||||
if ( ! \class_exists( 'Webfinger' ) ) {
|
||||
\add_rewrite_rule( '^.well-known/webfinger', 'index.php?rest_route=/activitypub/1.0/webfinger', 'top' );
|
||||
}
|
||||
|
||||
if ( ! \class_exists( 'Nodeinfo' ) ) {
|
||||
\add_rewrite_rule( '^.well-known/nodeinfo', 'index.php?rest_route=/activitypub/1.0/nodeinfo/discovery', 'top' );
|
||||
\add_rewrite_rule( '^.well-known/x-nodeinfo2', 'index.php?rest_route=/activitypub/1.0/nodeinfo2', 'top' );
|
||||
}
|
||||
}
|
||||
\add_action( 'init', '\Activitypub\add_rewrite_rules', 1 );
|
||||
|
||||
/**
|
||||
* Flush rewrite rules;
|
||||
*/
|
||||
function flush_rewrite_rules() {
|
||||
\Activitypub\add_rewrite_rules();
|
||||
\flush_rewrite_rules();
|
||||
}
|
||||
\register_activation_hook( __FILE__, '\Activitypub\flush_rewrite_rules' );
|
||||
\register_deactivation_hook( __FILE__, '\flush_rewrite_rules' );
|
||||
@@ -1,83 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub;
|
||||
|
||||
/**
|
||||
* ActivityPub Activity_Dispatcher Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://www.w3.org/TR/activitypub/
|
||||
*/
|
||||
class Activity_Dispatcher {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'activitypub_send_post_activity', array( '\Activitypub\Activity_Dispatcher', 'send_post_activity' ) );
|
||||
\add_action( 'activitypub_send_update_activity', array( '\Activitypub\Activity_Dispatcher', 'send_update_activity' ) );
|
||||
// \add_action( 'activitypub_send_delete_activity', array( '\Activitypub\Activity_Dispatcher', 'send_delete_activity' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send "create" activities
|
||||
*
|
||||
* @param int $post_id
|
||||
*/
|
||||
public static function send_post_activity( $post_id ) {
|
||||
$post = \get_post( $post_id );
|
||||
$user_id = $post->post_author;
|
||||
|
||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL );
|
||||
$activitypub_activity->from_post( $activitypub_post->to_array() );
|
||||
|
||||
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
|
||||
$activitypub_activity->set_to( $to );
|
||||
$activity = $activitypub_activity->to_json(); // phpcs:ignore
|
||||
|
||||
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send "update" activities
|
||||
*
|
||||
* @param int $post_id
|
||||
*/
|
||||
public static function send_update_activity( $post_id ) {
|
||||
$post = \get_post( $post_id );
|
||||
$user_id = $post->post_author;
|
||||
|
||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Update', \Activitypub\Model\Activity::TYPE_FULL );
|
||||
$activitypub_activity->from_post( $activitypub_post->to_array() );
|
||||
|
||||
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
|
||||
$activitypub_activity->set_to( $to );
|
||||
$activity = $activitypub_activity->to_json(); // phpcs:ignore
|
||||
|
||||
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send "delete" activities
|
||||
*
|
||||
* @param int $post_id
|
||||
*/
|
||||
public static function send_delete_activity( $post_id ) {
|
||||
$post = \get_post( $post_id );
|
||||
$user_id = $post->post_author;
|
||||
|
||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Delete', \Activitypub\Model\Activity::TYPE_FULL );
|
||||
$activitypub_activity->from_post( $activitypub_post->to_array() );
|
||||
|
||||
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
|
||||
$activitypub_activity->set_to( $to );
|
||||
$activity = $activitypub_activity->to_json(); // phpcs:ignore
|
||||
|
||||
\Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub;
|
||||
|
||||
/**
|
||||
* ActivityPub Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Activitypub {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_filter( 'template_include', array( '\Activitypub\Activitypub', 'render_json_template' ), 99 );
|
||||
\add_filter( 'query_vars', array( '\Activitypub\Activitypub', 'add_query_vars' ) );
|
||||
\add_action( 'init', array( '\Activitypub\Activitypub', 'add_rewrite_endpoint' ) );
|
||||
\add_filter( 'pre_get_avatar_data', array( '\Activitypub\Activitypub', 'pre_get_avatar_data' ), 11, 2 );
|
||||
|
||||
// Add support for ActivityPub to custom post types
|
||||
$post_types = \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) ) ? \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) ) : array();
|
||||
|
||||
foreach ( $post_types as $post_type ) {
|
||||
\add_post_type_support( $post_type, 'activitypub' );
|
||||
}
|
||||
|
||||
\add_action( 'transition_post_status', array( '\Activitypub\Activitypub', 'schedule_post_activity' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AS2 JSON version of an author, post or page
|
||||
*
|
||||
* @param string $template the path to the template object
|
||||
*
|
||||
* @return string the new path to the JSON template
|
||||
*/
|
||||
public static function render_json_template( $template ) {
|
||||
if ( ! \is_author() && ! \is_singular() ) {
|
||||
return $template;
|
||||
}
|
||||
|
||||
if ( \is_author() ) {
|
||||
$json_template = \dirname( __FILE__ ) . '/../templates/json-author.php';
|
||||
} elseif ( \is_singular() ) {
|
||||
$json_template = \dirname( __FILE__ ) . '/../templates/json-post.php';
|
||||
}
|
||||
|
||||
global $wp_query;
|
||||
|
||||
if ( isset( $wp_query->query_vars['activitypub'] ) ) {
|
||||
return $json_template;
|
||||
}
|
||||
|
||||
if ( ! isset( $_SERVER['HTTP_ACCEPT'] ) ) {
|
||||
return $template;
|
||||
}
|
||||
|
||||
$accept_header = $_SERVER['HTTP_ACCEPT'];
|
||||
|
||||
if (
|
||||
\stristr( $accept_header, 'application/activity+json' ) ||
|
||||
\stristr( $accept_header, 'application/ld+json' )
|
||||
) {
|
||||
return $json_template;
|
||||
}
|
||||
|
||||
// accept header as an array
|
||||
$accept = \explode( ',', \trim( $accept_header ) );
|
||||
|
||||
if (
|
||||
\in_array( 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', $accept, true ) ||
|
||||
\in_array( 'application/activity+json', $accept, true ) ||
|
||||
\in_array( 'application/ld+json', $accept, true ) ||
|
||||
\in_array( 'application/json', $accept, true )
|
||||
) {
|
||||
return $json_template;
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the 'photos' query variable so WordPress
|
||||
* won't mangle it.
|
||||
*/
|
||||
public static function add_query_vars( $vars ) {
|
||||
$vars[] = 'activitypub';
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add our rewrite endpoint to permalinks and pages.
|
||||
*/
|
||||
public static function add_rewrite_endpoint() {
|
||||
\add_rewrite_endpoint( 'activitypub', EP_AUTHORS | EP_PERMALINK | EP_PAGES );
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule Activities
|
||||
*
|
||||
* @param int $post_id
|
||||
*/
|
||||
public static function schedule_post_activity( $new_status, $old_status, $post ) {
|
||||
// do not send activities if post is password protected
|
||||
if ( \post_password_required( $post ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check if post-type supports ActivityPub
|
||||
$post_types = \get_post_types_by_support( 'activitypub' );
|
||||
if ( ! \in_array( $post->post_type, $post_types, true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 'publish' === $new_status && 'publish' !== $old_status ) {
|
||||
\wp_schedule_single_event( \time(), 'activitypub_send_post_activity', array( $post->ID ) );
|
||||
} elseif ( 'publish' === $new_status ) {
|
||||
\wp_schedule_single_event( \time(), 'activitypub_send_update_activity', array( $post->ID ) );
|
||||
} elseif ( 'trash' === $new_status ) {
|
||||
\wp_schedule_single_event( \time(), 'activitypub_send_delete_activity', array( get_permalink( $post ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the default avatar
|
||||
*
|
||||
* @param array $args Arguments passed to get_avatar_data(), after processing.
|
||||
* @param int|string|object $id_or_email A user ID, email address, or comment object
|
||||
*
|
||||
* @return array $args
|
||||
*/
|
||||
public static function pre_get_avatar_data( $args, $id_or_email ) {
|
||||
if (
|
||||
! $id_or_email instanceof \WP_Comment ||
|
||||
! isset( $id_or_email->comment_type ) ||
|
||||
$id_or_email->user_id
|
||||
) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$allowed_comment_types = \apply_filters( 'get_avatar_comment_types', array( 'comment' ) );
|
||||
if ( ! empty( $id_or_email->comment_type ) && ! \in_array( $id_or_email->comment_type, (array) $allowed_comment_types, true ) ) {
|
||||
$args['url'] = false;
|
||||
/** This filter is documented in wp-includes/link-template.php */
|
||||
return \apply_filters( 'get_avatar_data', $args, $id_or_email );
|
||||
}
|
||||
|
||||
// check if comment has an avatar
|
||||
$avatar = self::get_avatar_url( $id_or_email->comment_ID );
|
||||
|
||||
if ( $avatar ) {
|
||||
if ( ! isset( $args['class'] ) || ! \is_array( $args['class'] ) ) {
|
||||
$args['class'] = array( 'u-photo' );
|
||||
} else {
|
||||
$args['class'][] = 'u-photo';
|
||||
$args['class'] = \array_unique( $args['class'] );
|
||||
}
|
||||
$args['url'] = $avatar;
|
||||
$args['class'][] = 'avatar-activitypub';
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to retrieve Avatar URL if stored in meta
|
||||
*
|
||||
*
|
||||
* @param int|WP_Comment $comment
|
||||
*
|
||||
* @return string $url
|
||||
*/
|
||||
public static function get_avatar_url( $comment ) {
|
||||
if ( \is_numeric( $comment ) ) {
|
||||
$comment = \get_comment( $comment );
|
||||
}
|
||||
return \get_comment_meta( $comment->comment_ID, 'avatar_url', true );
|
||||
}
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub;
|
||||
|
||||
/**
|
||||
* ActivityPub Admin Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Admin {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'admin_menu', array( '\Activitypub\Admin', 'admin_menu' ) );
|
||||
\add_action( 'admin_init', array( '\Activitypub\Admin', 'register_settings' ) );
|
||||
\add_action( 'show_user_profile', array( '\Activitypub\Admin', 'add_fediverse_profile' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add admin menu entry
|
||||
*/
|
||||
public static function admin_menu() {
|
||||
$settings_page = \add_options_page(
|
||||
'ActivityPub',
|
||||
'ActivityPub',
|
||||
'manage_options',
|
||||
'activitypub',
|
||||
array( '\Activitypub\Admin', 'settings_page' )
|
||||
);
|
||||
|
||||
\add_action( 'load-' . $settings_page, array( '\Activitypub\Admin', 'add_settings_help_tab' ) );
|
||||
|
||||
$followers_list_page = \add_users_page( \__( 'Followers', 'activitypub' ), __( 'Followers (Fediverse)', 'activitypub' ), 'read', 'activitypub-followers-list', array( '\Activitypub\Admin', 'followers_list_page' ) );
|
||||
|
||||
\add_action( 'load-' . $followers_list_page, array( '\Activitypub\Admin', 'add_followers_list_help_tab' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load settings page
|
||||
*/
|
||||
public static function settings_page() {
|
||||
\load_template( \dirname( __FILE__ ) . '/../templates/settings.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load user settings page
|
||||
*/
|
||||
public static function followers_list_page() {
|
||||
\load_template( \dirname( __FILE__ ) . '/../templates/followers-list.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register PubSubHubbub settings
|
||||
*/
|
||||
public static function register_settings() {
|
||||
\register_setting(
|
||||
'activitypub', 'activitypub_post_content_type', array(
|
||||
'type' => 'string',
|
||||
'description' => \__( 'Use title and link, summary or full content', 'activitypub' ),
|
||||
'show_in_rest' => array(
|
||||
'schema' => array(
|
||||
'enum' => array( 'title', 'excerpt', 'content' ),
|
||||
),
|
||||
),
|
||||
'default' => 'content',
|
||||
)
|
||||
);
|
||||
\register_setting(
|
||||
'activitypub', 'activitypub_object_type', array(
|
||||
'type' => 'string',
|
||||
'description' => \__( 'The Activity-Object-Type', 'activitypub' ),
|
||||
'show_in_rest' => array(
|
||||
'schema' => array(
|
||||
'enum' => array( 'note', 'article', 'wordpress-post-format' ),
|
||||
),
|
||||
),
|
||||
'default' => 'note',
|
||||
)
|
||||
);
|
||||
\register_setting(
|
||||
'activitypub', 'activitypub_use_shortlink', array(
|
||||
'type' => 'boolean',
|
||||
'description' => \__( 'Use the Shortlink instead of the permalink', 'activitypub' ),
|
||||
'default' => 0,
|
||||
)
|
||||
);
|
||||
\register_setting(
|
||||
'activitypub', 'activitypub_use_hashtags', array(
|
||||
'type' => 'boolean',
|
||||
'description' => \__( 'Add hashtags in the content as native tags and replace the #tag with the tag-link', 'activitypub' ),
|
||||
'default' => 0,
|
||||
)
|
||||
);
|
||||
\register_setting(
|
||||
'activitypub', 'activitypub_add_tags_as_hashtags', array(
|
||||
'type' => 'boolean',
|
||||
'description' => \__( 'Add all tags as hashtags at the end of each activity', 'activitypub' ),
|
||||
'default' => 0,
|
||||
)
|
||||
);
|
||||
\register_setting(
|
||||
'activitypub', 'activitypub_support_post_types', array(
|
||||
'type' => 'string',
|
||||
'description' => \esc_html__( 'Enable ActivityPub support for post types', 'activitypub' ),
|
||||
'show_in_rest' => true,
|
||||
'default' => array( 'post', 'pages' ),
|
||||
)
|
||||
);
|
||||
\register_setting(
|
||||
'activitypub', 'activitypub_blacklist', array(
|
||||
'type' => 'string',
|
||||
'description' => \esc_html__( 'Block fediverse instances', 'activitypub' ),
|
||||
'show_in_rest' => true,
|
||||
'default' => 'gab.com',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static function add_settings_help_tab() {
|
||||
\get_current_screen()->add_help_tab(
|
||||
array(
|
||||
'id' => 'overview',
|
||||
'title' => \__( 'Overview', 'activitypub' ),
|
||||
'content' =>
|
||||
'<p>' . \__( 'ActivityPub is a decentralized social networking protocol based on the ActivityStreams 2.0 data format. ActivityPub is an official W3C recommended standard published by the W3C Social Web Working Group. It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and subscribing to content.', 'activitypub' ) . '</p>',
|
||||
)
|
||||
);
|
||||
|
||||
\get_current_screen()->set_help_sidebar(
|
||||
'<p><strong>' . \__( 'For more information:', 'activitypub' ) . '</strong></p>' .
|
||||
'<p>' . \__( '<a href="https://activitypub.rocks/">Test Suite</a>', 'activitypub' ) . '</p>' .
|
||||
'<p>' . \__( '<a href="https://www.w3.org/TR/activitypub/">W3C Spec</a>', 'activitypub' ) . '</p>' .
|
||||
'<p>' . \__( '<a href="https://github.com/pfefferle/wordpress-activitypub/issues">Give us feedback</a>', 'activitypub' ) . '</p>' .
|
||||
'<hr />' .
|
||||
'<p>' . \__( '<a href="https://notiz.blog/donate">Donate</a>', 'activitypub' ) . '</p>'
|
||||
);
|
||||
}
|
||||
|
||||
public static function add_followers_list_help_tab() {
|
||||
// todo
|
||||
}
|
||||
|
||||
public static function add_fediverse_profile( $user ) {
|
||||
?>
|
||||
<h2><?php \esc_html_e( 'Fediverse', 'activitypub' ); ?></h2>
|
||||
<?php
|
||||
\Activitypub\get_identifier_settings( $user->ID );
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub;
|
||||
|
||||
/**
|
||||
* ActivityPub Debug Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Debug {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
if ( WP_DEBUG && WP_DEBUG_LOG ) {
|
||||
\add_action( 'activitypub_safe_remote_post_response', array( '\Activitypub\Debug', 'log_remote_post_responses' ), 10, 4 );
|
||||
}
|
||||
}
|
||||
|
||||
public static function log_remote_post_responses( $response, $url, $body, $user_id ) {
|
||||
\error_log( "Request to: {$url} with response: " . \print_r( $response, true ) );
|
||||
}
|
||||
|
||||
public static function write_log( $log ) {
|
||||
if ( \is_array( $log ) || \is_object( $log ) ) {
|
||||
\error_log( \print_r( $log, true ) );
|
||||
} else {
|
||||
\error_log( $log );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub;
|
||||
|
||||
/**
|
||||
* ActivityPub Hashtag Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Hashtag {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
if ( '1' === \get_option( 'activitypub_use_hashtags', '1' ) ) {
|
||||
\add_filter( 'wp_insert_post', array( '\Activitypub\Hashtag', 'insert_post' ), 99, 2 );
|
||||
\add_filter( 'the_content', array( '\Activitypub\Hashtag', 'the_content' ), 99, 2 );
|
||||
}
|
||||
if ( '1' === \get_option( 'activitypub_add_tags_as_hashtags', '0' ) ) {
|
||||
\add_filter( 'activitypub_the_summary', array( '\Activitypub\Hashtag', 'add_hashtags_to_content' ), 10, 2 );
|
||||
\add_filter( 'activitypub_the_content', array( '\Activitypub\Hashtag', 'add_hashtags_to_content' ), 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to save #tags as real WordPress tags
|
||||
*
|
||||
* @param int $id the rev-id
|
||||
* @param array $data the post-data as array
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static function insert_post( $id, $data ) {
|
||||
if ( \preg_match_all( '/' . ACTIVITYPUB_HASHTAGS_REGEXP . '/i', $data->post_content, $match ) ) {
|
||||
$tags = \implode( ', ', $match[1] );
|
||||
|
||||
\wp_add_post_tags( $data->post_parent, $tags );
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to replace the #tags in the content with links
|
||||
*
|
||||
* @param string $the_content the post-content
|
||||
*
|
||||
* @return string the filtered post-content
|
||||
*/
|
||||
public static function the_content( $the_content ) {
|
||||
$the_content = \preg_replace_callback( '/' . ACTIVITYPUB_HASHTAGS_REGEXP . '/i', array( '\Activitypub\Hashtag', 'replace_with_links' ), $the_content );
|
||||
|
||||
return $the_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback for preg_replace to build the term links
|
||||
*
|
||||
* @param array $result the preg_match results
|
||||
* @return string the final string
|
||||
*/
|
||||
public static function replace_with_links( $result ) {
|
||||
$tag = $result[1];
|
||||
$tag_object = \get_term_by( 'name', $tag, 'post_tag' );
|
||||
|
||||
if ( $tag_object ) {
|
||||
$link = \get_term_link( $tag_object, 'post_tag' );
|
||||
return \sprintf( '<a rel="tag" class="u-tag u-category" href="%s">#%s</a>', $link, $tag );
|
||||
}
|
||||
|
||||
return '#' . $tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all tags as hashtags to the post/summary content
|
||||
*
|
||||
* @param string $content
|
||||
* @param WP_Post $post
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function add_hashtags_to_content( $content, $post ) {
|
||||
$tags = \get_the_tags( $post->ID );
|
||||
|
||||
if ( ! $tags ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$hash_tags = array();
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$hash_tags[] = \sprintf( '<a rel="tag" class="u-tag u-category" href="%s">#%s</a>', \get_tag_link( $tag ), $tag->slug );
|
||||
}
|
||||
|
||||
return $content . '<p>' . \implode( ' ', $hash_tags ) . '</p>';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub;
|
||||
|
||||
/**
|
||||
* ActivityPub Health_Check Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Health_Check {
|
||||
public static function init() {
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub;
|
||||
|
||||
/**
|
||||
* ActivityPub Signature Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Signature {
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get_public_key( $user_id, $force = false ) {
|
||||
$key = \get_user_meta( $user_id, 'magic_sig_public_key' );
|
||||
|
||||
if ( $key && ! $force ) {
|
||||
return $key[0];
|
||||
}
|
||||
|
||||
self::generate_key_pair( $user_id );
|
||||
$key = \get_user_meta( $user_id, 'magic_sig_public_key' );
|
||||
|
||||
return $key[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get_private_key( $user_id, $force = false ) {
|
||||
$key = \get_user_meta( $user_id, 'magic_sig_private_key' );
|
||||
|
||||
if ( $key && ! $force ) {
|
||||
return $key[0];
|
||||
}
|
||||
|
||||
self::generate_key_pair( $user_id );
|
||||
$key = \get_user_meta( $user_id, 'magic_sig_private_key' );
|
||||
|
||||
return $key[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the pair keys
|
||||
*
|
||||
* @param int $user_id
|
||||
*/
|
||||
public static function generate_key_pair( $user_id ) {
|
||||
$config = array(
|
||||
'digest_alg' => 'sha512',
|
||||
'private_key_bits' => 2048,
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
);
|
||||
|
||||
$key = \openssl_pkey_new( $config );
|
||||
$priv_key = null;
|
||||
|
||||
\openssl_pkey_export( $key, $priv_key );
|
||||
|
||||
// private key
|
||||
\update_user_meta( $user_id, 'magic_sig_private_key', $priv_key );
|
||||
|
||||
$detail = \openssl_pkey_get_details( $key );
|
||||
|
||||
// public key
|
||||
\update_user_meta( $user_id, 'magic_sig_public_key', $detail['key'] );
|
||||
}
|
||||
|
||||
public static function generate_signature( $user_id, $url, $date ) {
|
||||
$key = self::get_private_key( $user_id );
|
||||
|
||||
$url_parts = \wp_parse_url( $url );
|
||||
|
||||
$host = $url_parts['host'];
|
||||
$path = '/';
|
||||
|
||||
// add path
|
||||
if ( ! empty( $url_parts['path'] ) ) {
|
||||
$path = $url_parts['path'];
|
||||
}
|
||||
|
||||
// add query
|
||||
if ( ! empty( $url_parts['query'] ) ) {
|
||||
$path .= '?' . $url_parts['query'];
|
||||
}
|
||||
|
||||
$signed_string = "(request-target): post $path\nhost: $host\ndate: $date";
|
||||
|
||||
$signature = null;
|
||||
\openssl_sign( $signed_string, $signature, $key, OPENSSL_ALGO_SHA256 );
|
||||
$signature = \base64_encode( $signature ); // phpcs:ignore
|
||||
|
||||
$key_id = \get_author_posts_url( $user_id ) . '#main-key';
|
||||
|
||||
return \sprintf( 'keyId="%s",algorithm="rsa-sha256",headers="(request-target) host date",signature="%s"', $key_id, $signature );
|
||||
}
|
||||
|
||||
public static function verify_signature( $headers, $signature ) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,334 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub;
|
||||
|
||||
/**
|
||||
* Returns the ActivityPub default JSON-context
|
||||
*
|
||||
* @return array the activitypub context
|
||||
*/
|
||||
function get_context() {
|
||||
$context = array(
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
'https://w3id.org/security/v1',
|
||||
array(
|
||||
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
|
||||
'PropertyValue' => 'schema:PropertyValue',
|
||||
'schema' => 'http://schema.org#',
|
||||
'value' => 'schema:value',
|
||||
),
|
||||
);
|
||||
|
||||
return \apply_filters( 'activitypub_json_context', $context );
|
||||
}
|
||||
|
||||
function safe_remote_post( $url, $body, $user_id ) {
|
||||
$date = \gmdate( 'D, d M Y H:i:s T' );
|
||||
$signature = \Activitypub\Signature::generate_signature( $user_id, $url, $date );
|
||||
|
||||
$wp_version = \get_bloginfo( 'version' );
|
||||
$user_agent = \apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . \get_bloginfo( 'url' ) );
|
||||
$args = array(
|
||||
'timeout' => 100,
|
||||
'limit_response_size' => 1048576,
|
||||
'redirection' => 3,
|
||||
'user-agent' => "$user_agent; ActivityPub",
|
||||
'headers' => array(
|
||||
'Accept' => 'application/activity+json',
|
||||
'Content-Type' => 'application/activity+json',
|
||||
'Signature' => $signature,
|
||||
'Date' => $date,
|
||||
),
|
||||
'body' => $body,
|
||||
);
|
||||
|
||||
$response = \wp_safe_remote_post( $url, $args );
|
||||
|
||||
\do_action( 'activitypub_safe_remote_post_response', $response, $url, $body, $user_id );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
function safe_remote_get( $url, $user_id ) {
|
||||
$date = \gmdate( 'D, d M Y H:i:s T' );
|
||||
$signature = \Activitypub\Signature::generate_signature( $user_id, $url, $date );
|
||||
|
||||
$wp_version = \get_bloginfo( 'version' );
|
||||
$user_agent = \apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . \get_bloginfo( 'url' ) );
|
||||
$args = array(
|
||||
'timeout' => 100,
|
||||
'limit_response_size' => 1048576,
|
||||
'redirection' => 3,
|
||||
'user-agent' => "$user_agent; ActivityPub",
|
||||
'headers' => array(
|
||||
'Accept' => 'application/activity+json',
|
||||
'Content-Type' => 'application/activity+json',
|
||||
'Signature' => $signature,
|
||||
'Date' => $date,
|
||||
),
|
||||
);
|
||||
|
||||
$response = \wp_safe_remote_get( $url, $args );
|
||||
|
||||
\do_action( 'activitypub_safe_remote_get_response', $response, $url, $user_id );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a users WebFinger "resource"
|
||||
*
|
||||
* @param int $user_id
|
||||
*
|
||||
* @return string The user-resource
|
||||
*/
|
||||
function get_webfinger_resource( $user_id ) {
|
||||
// use WebFinger plugin if installed
|
||||
if ( \function_exists( '\get_webfinger_resource' ) ) {
|
||||
return \get_webfinger_resource( $user_id, false );
|
||||
}
|
||||
|
||||
$user = \get_user_by( 'id', $user_id );
|
||||
|
||||
return $user->user_login . '@' . \wp_parse_url( \home_url(), PHP_URL_HOST );
|
||||
}
|
||||
|
||||
/**
|
||||
* [get_metadata_by_actor description]
|
||||
*
|
||||
* @param sting $actor
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_remote_metadata_by_actor( $actor ) {
|
||||
$metadata = \get_transient( 'activitypub_' . $actor );
|
||||
|
||||
if ( $metadata ) {
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
if ( ! \wp_http_validate_url( $actor ) ) {
|
||||
return new \WP_Error( 'activitypub_no_valid_actor_url', \__( 'The "actor" is no valid URL', 'activitypub' ), $actor );
|
||||
}
|
||||
|
||||
$user = \get_users( array (
|
||||
'number' => 1,
|
||||
'who' => 'authors',
|
||||
'fields' => 'ID',
|
||||
) );
|
||||
|
||||
// we just need any user to generate a request signature
|
||||
$user_id = \reset( $user );
|
||||
|
||||
$response = \Activitypub\safe_remote_get( $actor, $user_id );
|
||||
|
||||
if ( \is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$metadata = \wp_remote_retrieve_body( $response );
|
||||
$metadata = \json_decode( $metadata, true );
|
||||
|
||||
if ( ! $metadata ) {
|
||||
return new \WP_Error( 'activitypub_invalid_json', \__( 'No valid JSON data', 'activitypub' ), $actor );
|
||||
}
|
||||
|
||||
\set_transient( 'activitypub_' . $actor, $metadata, WEEK_IN_SECONDS );
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* [get_inbox_by_actor description]
|
||||
* @param [type] $actor [description]
|
||||
* @return [type] [description]
|
||||
*/
|
||||
function get_inbox_by_actor( $actor ) {
|
||||
$metadata = \Activitypub\get_remote_metadata_by_actor( $actor );
|
||||
|
||||
if ( \is_wp_error( $metadata ) ) {
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
if ( isset( $metadata['endpoints'] ) && isset( $metadata['endpoints']['sharedInbox'] ) ) {
|
||||
return $metadata['endpoints']['sharedInbox'];
|
||||
}
|
||||
|
||||
if ( \array_key_exists( 'inbox', $metadata ) ) {
|
||||
return $metadata['inbox'];
|
||||
}
|
||||
|
||||
return new \WP_Error( 'activitypub_no_inbox', __( 'No "Inbox" found', 'activitypub' ), $metadata );
|
||||
}
|
||||
|
||||
/**
|
||||
* [get_inbox_by_actor description]
|
||||
* @param [type] $actor [description]
|
||||
* @return [type] [description]
|
||||
*/
|
||||
function get_publickey_by_actor( $actor, $key_id ) {
|
||||
$metadata = \Activitypub\get_remote_metadata_by_actor( $actor );
|
||||
|
||||
if ( \is_wp_error( $metadata ) ) {
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
if (
|
||||
isset( $metadata['publicKey'] ) &&
|
||||
isset( $metadata['publicKey']['id'] ) &&
|
||||
isset( $metadata['publicKey']['owner'] ) &&
|
||||
isset( $metadata['publicKey']['publicKeyPem'] ) &&
|
||||
$key_id === $metadata['publicKey']['id'] &&
|
||||
$actor === $metadata['publicKey']['owner']
|
||||
) {
|
||||
return $metadata['publicKey']['publicKeyPem'];
|
||||
}
|
||||
|
||||
return new \WP_Error( 'activitypub_no_public_key', \__( 'No "Public-Key" found', 'activitypub' ), $metadata );
|
||||
}
|
||||
|
||||
function get_follower_inboxes( $user_id ) {
|
||||
$followers = \Activitypub\Peer\Followers::get_followers( $user_id );
|
||||
$inboxes = array();
|
||||
|
||||
foreach ( $followers as $follower ) {
|
||||
$inbox = \Activitypub\get_inbox_by_actor( $follower );
|
||||
if ( ! $inbox || \is_wp_error( $inbox ) ) {
|
||||
continue;
|
||||
}
|
||||
// init array if empty
|
||||
if ( ! isset( $inboxes[ $inbox ] ) ) {
|
||||
$inboxes[ $inbox ] = array();
|
||||
}
|
||||
$inboxes[ $inbox ][] = $follower;
|
||||
}
|
||||
|
||||
return $inboxes;
|
||||
}
|
||||
|
||||
function get_identifier_settings( $user_id ) {
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label><?php \esc_html_e( 'Profile identifier', 'activitypub' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<p><code><?php echo \esc_html( \Activitypub\get_webfinger_resource( $user_id ) ); ?></code> or <code><?php echo \esc_url( \get_author_posts_url( $user_id ) ); ?></code></p>
|
||||
<?php // translators: the webfinger resource ?>
|
||||
<p class="description"><?php \printf( \esc_html__( 'Try to follow "@%s" in the Mastodon/Friendica search field.', 'activitypub' ), \esc_html( \Activitypub\get_webfinger_resource( $user_id ) ) ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
function get_followers( $user_id ) {
|
||||
$followers = \Activitypub\Peer\Followers::get_followers( $user_id );
|
||||
|
||||
if ( ! $followers ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $followers;
|
||||
}
|
||||
|
||||
function count_followers( $user_id ) {
|
||||
$followers = \Activitypub\get_followers( $user_id );
|
||||
|
||||
return \count( $followers );
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine a url and try to determine the author ID it represents.
|
||||
*
|
||||
* Checks are supposedly from the hosted site blog.
|
||||
*
|
||||
* @param string $url Permalink to check.
|
||||
*
|
||||
* @return int User ID, or 0 on failure.
|
||||
*/
|
||||
function url_to_authorid( $url ) {
|
||||
global $wp_rewrite;
|
||||
|
||||
// check if url hase the same host
|
||||
if ( wp_parse_url( site_url(), PHP_URL_HOST ) !== wp_parse_url( $url, PHP_URL_HOST ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// first, check to see if there is a 'author=N' to match against
|
||||
if ( \preg_match( '/[?&]author=(\d+)/i', $url, $values ) ) {
|
||||
$id = absint( $values[1] );
|
||||
if ( $id ) {
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
// check to see if we are using rewrite rules
|
||||
$rewrite = $wp_rewrite->wp_rewrite_rules();
|
||||
|
||||
// not using rewrite rules, and 'author=N' method failed, so we're out of options
|
||||
if ( empty( $rewrite ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// generate rewrite rule for the author url
|
||||
$author_rewrite = $wp_rewrite->get_author_permastruct();
|
||||
$author_regexp = \str_replace( '%author%', '', $author_rewrite );
|
||||
|
||||
// match the rewrite rule with the passed url
|
||||
if ( \preg_match( '/https?:\/\/(.+)' . \preg_quote( $author_regexp, '/' ) . '([^\/]+)/i', $url, $match ) ) {
|
||||
$user = get_user_by( 'slug', $match[2] );
|
||||
if ( $user ) {
|
||||
return $user->ID;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the blacklist from the WordPress options table
|
||||
*
|
||||
* @return array the list of blacklisted hosts
|
||||
*
|
||||
* @uses apply_filters() Calls 'activitypub_blacklist' filter
|
||||
*/
|
||||
function get_blacklist() {
|
||||
$blacklist = \get_option( 'activitypub_blacklist' );
|
||||
$blacklist_hosts = \explode( PHP_EOL, $blacklist );
|
||||
|
||||
// if no values have been set, revert to the defaults
|
||||
if ( ! $blacklist || ! $blacklist_hosts || ! \is_array( $blacklist_hosts ) ) {
|
||||
$blacklist_hosts = array();
|
||||
}
|
||||
|
||||
// clean out any blank values
|
||||
foreach ( $blacklist_hosts as $key => $value ) {
|
||||
if ( empty( $value ) ) {
|
||||
unset( $blacklist_hosts[ $key ] );
|
||||
} else {
|
||||
$blacklist_hosts[ $key ] = \trim( $blacklist_hosts[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
return \apply_filters( 'activitypub_blacklist', $blacklist_hosts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an URL is blacklisted
|
||||
*
|
||||
* @param string $url an URL to check
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function is_blacklisted( $url ) {
|
||||
foreach ( \ActivityPub\get_blacklist() as $blacklisted_host ) {
|
||||
if ( \strpos( $url, $blacklisted_host ) !== false ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Model;
|
||||
|
||||
/**
|
||||
* ActivityPub Post Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://www.w3.org/TR/activitypub/
|
||||
*/
|
||||
class Activity {
|
||||
private $context = array( 'https://www.w3.org/ns/activitystreams' );
|
||||
private $published = '';
|
||||
private $id = '';
|
||||
private $type = 'Create';
|
||||
private $actor = '';
|
||||
private $to = array( 'https://www.w3.org/ns/activitystreams#Public' );
|
||||
private $cc = array( 'https://www.w3.org/ns/activitystreams#Public' );
|
||||
private $object = null;
|
||||
|
||||
const TYPE_SIMPLE = 'simple';
|
||||
const TYPE_FULL = 'full';
|
||||
const TYPE_NONE = 'none';
|
||||
|
||||
public function __construct( $type = 'Create', $context = self::TYPE_SIMPLE ) {
|
||||
if ( 'none' === $context ) {
|
||||
$this->context = null;
|
||||
} elseif ( 'full' === $context ) {
|
||||
$this->context = \Activitypub\get_context();
|
||||
}
|
||||
|
||||
$this->type = \ucfirst( $type );
|
||||
$this->published = \date( 'Y-m-d\TH:i:s\Z', \strtotime( 'now' ) );
|
||||
}
|
||||
|
||||
public function __call( $method, $params ) {
|
||||
$var = \strtolower( \substr( $method, 4 ) );
|
||||
|
||||
if ( \strncasecmp( $method, 'get', 3 ) === 0 ) {
|
||||
return $this->$var;
|
||||
}
|
||||
|
||||
if ( \strncasecmp( $method, 'set', 3 ) === 0 ) {
|
||||
$this->$var = $params[0];
|
||||
}
|
||||
}
|
||||
|
||||
public function from_post( $object ) {
|
||||
$this->object = $object;
|
||||
$this->published = $object['published'];
|
||||
$this->actor = $object['attributedTo'];
|
||||
$this->id = $object['id'];
|
||||
}
|
||||
|
||||
public function from_comment( $object ) {
|
||||
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
$array = \get_object_vars( $this );
|
||||
|
||||
if ( $this->context ) {
|
||||
$array = array( '@context' => $this->context ) + $array;
|
||||
}
|
||||
|
||||
unset( $array['context'] );
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function to_json() {
|
||||
return \wp_json_encode( $this->to_array(), JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT );
|
||||
}
|
||||
|
||||
public function to_simple_array() {
|
||||
$activity = array(
|
||||
'@context' => $this->context,
|
||||
'type' => $this->type,
|
||||
'actor' => $this->actor,
|
||||
'object' => $this->object,
|
||||
'to' => $this->to,
|
||||
'cc' => $this->cc,
|
||||
);
|
||||
|
||||
if ( $this->id ) {
|
||||
$activity['id'] = $this->id;
|
||||
}
|
||||
|
||||
return $activity;
|
||||
}
|
||||
|
||||
public function to_simple_json() {
|
||||
return \wp_json_encode( $this->to_simple_array(), JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT );
|
||||
}
|
||||
}
|
||||
@@ -1,320 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Model;
|
||||
|
||||
/**
|
||||
* ActivityPub Post Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Post {
|
||||
private $post;
|
||||
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_filter( 'activitypub_the_summary', array( '\Activitypub\Model\Post', 'add_backlink_to_content' ), 15, 2 );
|
||||
\add_filter( 'activitypub_the_content', array( '\Activitypub\Model\Post', 'add_backlink_to_content' ), 15, 2 );
|
||||
}
|
||||
|
||||
public function __construct( $post = null ) {
|
||||
$this->post = \get_post( $post );
|
||||
}
|
||||
|
||||
public function get_post() {
|
||||
return $this->post;
|
||||
}
|
||||
|
||||
public function get_post_author() {
|
||||
return $this->post->post_author;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
$post = $this->post;
|
||||
|
||||
$array = array(
|
||||
'id' => \get_permalink( $post ),
|
||||
'type' => $this->get_object_type(),
|
||||
'published' => \date( 'Y-m-d\TH:i:s\Z', \strtotime( $post->post_date ) ),
|
||||
'attributedTo' => \get_author_posts_url( $post->post_author ),
|
||||
'summary' => $this->get_the_title(),
|
||||
'inReplyTo' => null,
|
||||
'content' => $this->get_the_content(),
|
||||
'contentMap' => array(
|
||||
\strstr( \get_locale(), '_', true ) => $this->get_the_content(),
|
||||
),
|
||||
'to' => array( 'https://www.w3.org/ns/activitystreams#Public' ),
|
||||
'cc' => array( 'https://www.w3.org/ns/activitystreams#Public' ),
|
||||
'attachment' => $this->get_attachments(),
|
||||
'tag' => $this->get_tags(),
|
||||
);
|
||||
|
||||
return \apply_filters( 'activitypub_post', $array );
|
||||
}
|
||||
|
||||
public function to_json() {
|
||||
return \wp_json_encode( $this->to_array(), JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT );
|
||||
}
|
||||
|
||||
public function get_attachments() {
|
||||
$max_images = \apply_filters( 'activitypub_max_images', 3 );
|
||||
|
||||
$images = array();
|
||||
|
||||
// max images can't be negative or zero
|
||||
if ( $max_images <= 0 ) {
|
||||
$max_images = 1;
|
||||
}
|
||||
|
||||
$id = $this->post->ID;
|
||||
|
||||
$image_ids = array();
|
||||
// list post thumbnail first if this post has one
|
||||
if ( \function_exists( 'has_post_thumbnail' ) && \has_post_thumbnail( $id ) ) {
|
||||
$image_ids[] = \get_post_thumbnail_id( $id );
|
||||
$max_images--;
|
||||
}
|
||||
// then list any image attachments
|
||||
$query = new \WP_Query(
|
||||
array(
|
||||
'post_parent' => $id,
|
||||
'post_status' => 'inherit',
|
||||
'post_type' => 'attachment',
|
||||
'post_mime_type' => 'image',
|
||||
'order' => 'ASC',
|
||||
'orderby' => 'menu_order ID',
|
||||
'posts_per_page' => $max_images,
|
||||
)
|
||||
);
|
||||
foreach ( $query->get_posts() as $attachment ) {
|
||||
if ( ! \in_array( $attachment->ID, $image_ids, true ) ) {
|
||||
$image_ids[] = $attachment->ID;
|
||||
}
|
||||
}
|
||||
|
||||
$image_ids = \array_unique( $image_ids );
|
||||
|
||||
// get URLs for each image
|
||||
foreach ( $image_ids as $id ) {
|
||||
$alt = \get_post_meta( $id, '_wp_attachment_image_alt', true );
|
||||
$thumbnail = \wp_get_attachment_image_src( $id, 'full' );
|
||||
$mimetype = \get_post_mime_type( $id );
|
||||
|
||||
if ( $thumbnail ) {
|
||||
$image = array(
|
||||
'type' => 'Image',
|
||||
'url' => $thumbnail[0],
|
||||
'mediaType' => $mimetype
|
||||
);
|
||||
if ( $alt ) {
|
||||
$image['name'] = $alt;
|
||||
}
|
||||
$images[] = $image;
|
||||
}
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
public function get_tags() {
|
||||
$tags = array();
|
||||
|
||||
$post_tags = \get_the_tags( $this->post->ID );
|
||||
if ( $post_tags ) {
|
||||
foreach ( $post_tags as $post_tag ) {
|
||||
$tag = array(
|
||||
'type' => 'Hashtag',
|
||||
'href' => \get_tag_link( $post_tag->term_id ),
|
||||
'name' => '#' . $post_tag->slug,
|
||||
);
|
||||
$tags[] = $tag;
|
||||
}
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the as2 object-type for a given post
|
||||
*
|
||||
* @param string $type the object-type
|
||||
* @param Object $post the post-object
|
||||
*
|
||||
* @return string the object-type
|
||||
*/
|
||||
public function get_object_type() {
|
||||
if ( 'wordpress-post-format' !== \get_option( 'activitypub_object_type', 'note' ) ) {
|
||||
return \ucfirst( \get_option( 'activitypub_object_type', 'note' ) );
|
||||
}
|
||||
|
||||
$post_type = \get_post_type( $this->post );
|
||||
switch ( $post_type ) {
|
||||
case 'post':
|
||||
$post_format = \get_post_format( $this->post );
|
||||
switch ( $post_format ) {
|
||||
case 'aside':
|
||||
case 'status':
|
||||
case 'quote':
|
||||
case 'note':
|
||||
$object_type = 'Note';
|
||||
break;
|
||||
case 'gallery':
|
||||
case 'image':
|
||||
$object_type = 'Image';
|
||||
break;
|
||||
case 'video':
|
||||
$object_type = 'Video';
|
||||
break;
|
||||
case 'audio':
|
||||
$object_type = 'Audio';
|
||||
break;
|
||||
default:
|
||||
$object_type = 'Article';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'page':
|
||||
$object_type = 'Page';
|
||||
break;
|
||||
case 'attachment':
|
||||
$mime_type = \get_post_mime_type();
|
||||
$media_type = \preg_replace( '/(\/[a-zA-Z]+)/i', '', $mime_type );
|
||||
switch ( $media_type ) {
|
||||
case 'audio':
|
||||
$object_type = 'Audio';
|
||||
break;
|
||||
case 'video':
|
||||
$object_type = 'Video';
|
||||
break;
|
||||
case 'image':
|
||||
$object_type = 'Image';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$object_type = 'Article';
|
||||
break;
|
||||
}
|
||||
|
||||
return $object_type;
|
||||
}
|
||||
|
||||
public function get_the_content() {
|
||||
if ( 'excerpt' === \get_option( 'activitypub_post_content_type', 'content' ) ) {
|
||||
return $this->get_the_post_summary();
|
||||
}
|
||||
|
||||
if ( 'title' === \get_option( 'activitypub_post_content_type', 'content' ) ) {
|
||||
return $this->get_the_title();
|
||||
}
|
||||
|
||||
return $this->get_the_post_content();
|
||||
}
|
||||
|
||||
public function get_the_title() {
|
||||
if ( 'Article' === $this->get_object_type() ) {
|
||||
$title = \get_the_title( $this->post );
|
||||
|
||||
return \html_entity_decode( $title, ENT_QUOTES, 'UTF-8' );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the excerpt for a post for use outside of the loop.
|
||||
*
|
||||
* @param int Optional excerpt length.
|
||||
*
|
||||
* @return string The excerpt.
|
||||
*/
|
||||
public function get_the_post_excerpt( $excerpt_length = 400 ) {
|
||||
$post = $this->post;
|
||||
|
||||
$excerpt = \get_post_field( 'post_excerpt', $post );
|
||||
|
||||
if ( '' === $excerpt ) {
|
||||
|
||||
$content = \get_post_field( 'post_content', $post );
|
||||
|
||||
// An empty string will make wp_trim_excerpt do stuff we do not want.
|
||||
if ( '' !== $content ) {
|
||||
|
||||
$excerpt = \strip_shortcodes( $content );
|
||||
|
||||
/** This filter is documented in wp-includes/post-template.php */
|
||||
$excerpt = \apply_filters( 'the_content', $excerpt );
|
||||
$excerpt = \str_replace( ']]>', ']]>', $excerpt );
|
||||
|
||||
$excerpt_length = \apply_filters( 'excerpt_length', $excerpt_length );
|
||||
|
||||
/** This filter is documented in wp-includes/formatting.php */
|
||||
$excerpt_more = \apply_filters( 'excerpt_more', ' [...]' );
|
||||
|
||||
$excerpt = \wp_trim_words( $excerpt, $excerpt_length, $excerpt_more );
|
||||
}
|
||||
}
|
||||
|
||||
return $excerpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content for a post for use outside of the loop.
|
||||
*
|
||||
* @return string The content.
|
||||
*/
|
||||
public function get_the_post_content() {
|
||||
$post = $this->post;
|
||||
|
||||
$content = \get_post_field( 'post_content', $post );
|
||||
|
||||
$filtered_content = \apply_filters( 'the_content', $content );
|
||||
$filtered_content = \apply_filters( 'activitypub_the_content', $filtered_content, $this->post );
|
||||
|
||||
$decoded_content = \html_entity_decode( $filtered_content, ENT_QUOTES, 'UTF-8' );
|
||||
|
||||
$allowed_html = \apply_filters( 'activitypub_allowed_html', '<a><p><ul><ol><li><code><blockquote><pre>' );
|
||||
|
||||
return \trim( \preg_replace( '/[\r\n]{2,}/', '', \strip_tags( $decoded_content, $allowed_html ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the excerpt for a post for use outside of the loop.
|
||||
*
|
||||
* @param int Optional excerpt length.
|
||||
*
|
||||
* @return string The excerpt.
|
||||
*/
|
||||
public function get_the_post_summary( $summary_length = 400 ) {
|
||||
$summary = $this->get_the_post_excerpt( $summary_length );
|
||||
|
||||
$filtered_summary = \apply_filters( 'the_excerpt', $summary );
|
||||
$filtered_summary = \apply_filters( 'activitypub_the_summary', $filtered_summary, $this->post );
|
||||
|
||||
$decoded_summary = \html_entity_decode( $filtered_summary, ENT_QUOTES, 'UTF-8' );
|
||||
|
||||
$allowed_html = \apply_filters( 'activitypub_allowed_html', '<a><p>' );
|
||||
|
||||
return \trim( \preg_replace( '/[\r\n]{2,}/', '', \strip_tags( $decoded_summary, $allowed_html ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a backlink to the post/summary content
|
||||
*
|
||||
* @param string $content
|
||||
* @param WP_Post $post
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function add_backlink_to_content( $content, $post ) {
|
||||
$link = '';
|
||||
|
||||
if ( \get_option( 'activitypub_use_shortlink', 0 ) ) {
|
||||
$link = \esc_url( \wp_get_shortlink( $post->ID ) );
|
||||
} else {
|
||||
$link = \esc_url( \get_permalink( $post->ID ) );
|
||||
}
|
||||
|
||||
return $content . '<p><a href="' . $link . '">' . $link . '</a></p>';
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Peer;
|
||||
|
||||
/**
|
||||
* ActivityPub Followers DB-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Followers {
|
||||
|
||||
public static function get_followers( $author_id ) {
|
||||
$followers = \get_user_option( 'activitypub_followers', $author_id );
|
||||
|
||||
if ( ! $followers ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ( $followers as $key => $follower ) {
|
||||
if (
|
||||
\is_array( $follower ) &&
|
||||
isset( $follower['type'] ) &&
|
||||
'Person' === $follower['type'] &&
|
||||
isset( $follower['id'] ) &&
|
||||
false !== \filter_var( $follower['id'], FILTER_VALIDATE_URL )
|
||||
) {
|
||||
$followers[ $key ] = $follower['id'];
|
||||
}
|
||||
}
|
||||
|
||||
return $followers;
|
||||
}
|
||||
|
||||
public static function count_followers( $author_id ) {
|
||||
$followers = self::get_followers( $author_id );
|
||||
|
||||
return \count( $followers );
|
||||
}
|
||||
|
||||
public static function add_follower( $actor, $author_id ) {
|
||||
$followers = \get_user_option( 'activitypub_followers', $author_id );
|
||||
|
||||
if ( ! \is_string( $actor ) ) {
|
||||
if (
|
||||
\is_array( $actor ) &&
|
||||
isset( $actor['type'] ) &&
|
||||
'Person' === $actor['type'] &&
|
||||
isset( $actor['id'] ) &&
|
||||
false !== \filter_var( $actor['id'], FILTER_VALIDATE_URL )
|
||||
) {
|
||||
$actor = $actor['id'];
|
||||
}
|
||||
|
||||
return new \WP_Error( 'invalid_actor_object', \__( 'Unknown Actor schema', 'activitypub' ), array(
|
||||
'status' => 404,
|
||||
) );
|
||||
}
|
||||
|
||||
if ( ! \is_array( $followers ) ) {
|
||||
$followers = array( $actor );
|
||||
} else {
|
||||
$followers[] = $actor;
|
||||
}
|
||||
|
||||
$followers = \array_unique( $followers );
|
||||
|
||||
\update_user_meta( $author_id, 'activitypub_followers', $followers );
|
||||
}
|
||||
|
||||
public static function remove_follower( $actor, $author_id ) {
|
||||
$followers = \get_user_option( 'activitypub_followers', $author_id );
|
||||
|
||||
foreach ( $followers as $key => $value ) {
|
||||
if ( $value === $actor ) {
|
||||
unset( $followers[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
\update_user_meta( $author_id, 'activitypub_followers', $followers );
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
/**
|
||||
* ActivityPub Followers REST-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://www.w3.org/TR/activitypub/#followers
|
||||
*/
|
||||
class Followers {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'rest_api_init', array( '\Activitypub\Rest\Followers', 'register_routes' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/users/(?P<id>\d+)/followers', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Followers', 'get' ),
|
||||
'args' => self::request_parameters(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle GET request
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public static function get( $request ) {
|
||||
$user_id = $request->get_param( 'id' );
|
||||
$user = \get_user_by( 'ID', $user_id );
|
||||
|
||||
if ( ! $user ) {
|
||||
return new \WP_Error( 'rest_invalid_param', \__( 'User not found', 'activitypub' ), array(
|
||||
'status' => 404,
|
||||
'params' => array(
|
||||
'user_id' => \__( 'User not found', 'activitypub' ),
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the ActivityPub profile being created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_outbox_pre' );
|
||||
|
||||
$json = new \stdClass();
|
||||
|
||||
$json->{'@context'} = \Activitypub\get_context();
|
||||
|
||||
$json->partOf = \get_rest_url( null, "/activitypub/1.0/users/$user_id/followers" ); // phpcs:ignore
|
||||
$json->totalItems = \Activitypub\count_followers( $user_id ); // phpcs:ignore
|
||||
$json->orderedItems = \Activitypub\Peer\Followers::get_followers( $user_id ); // phpcs:ignore
|
||||
|
||||
$json->first = $json->partOf; // phpcs:ignore
|
||||
|
||||
$json->first = \get_rest_url( null, "/activitypub/1.0/users/$user_id/followers" );
|
||||
|
||||
$response = new \WP_REST_Response( $json, 200 );
|
||||
$response->header( 'Content-Type', 'application/activity+json' );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* The supported parameters
|
||||
*
|
||||
* @return array list of parameters
|
||||
*/
|
||||
public static function request_parameters() {
|
||||
$params = array();
|
||||
|
||||
$params['page'] = array(
|
||||
'type' => 'integer',
|
||||
);
|
||||
|
||||
$params['id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'integer',
|
||||
);
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
/**
|
||||
* ActivityPub Following REST-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://www.w3.org/TR/activitypub/#following
|
||||
*/
|
||||
class Following {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'rest_api_init', array( '\Activitypub\Rest\Following', 'register_routes' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/users/(?P<id>\d+)/following', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Following', 'get' ),
|
||||
'args' => self::request_parameters(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle GET request
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public static function get( $request ) {
|
||||
$user_id = $request->get_param( 'id' );
|
||||
$user = \get_user_by( 'ID', $user_id );
|
||||
|
||||
if ( ! $user ) {
|
||||
return new \WP_Error( 'rest_invalid_param', \__( 'User not found', 'activitypub' ), array(
|
||||
'status' => 404,
|
||||
'params' => array(
|
||||
'user_id' => \__( 'User not found', 'activitypub' ),
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the ActivityPub profile being created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_outbox_pre' );
|
||||
|
||||
$json = new \stdClass();
|
||||
|
||||
$json->{'@context'} = \Activitypub\get_context();
|
||||
|
||||
$json->partOf = \get_rest_url( null, "/activitypub/1.0/users/$user_id/following" ); // phpcs:ignore
|
||||
$json->totalItems = 0; // phpcs:ignore
|
||||
$json->orderedItems = array(); // phpcs:ignore
|
||||
|
||||
$json->first = $json->partOf; // phpcs:ignore
|
||||
|
||||
$json->first = \get_rest_url( null, "/activitypub/1.0/users/$user_id/following" );
|
||||
|
||||
$response = new \WP_REST_Response( $json, 200 );
|
||||
$response->header( 'Content-Type', 'application/activity+json' );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* The supported parameters
|
||||
*
|
||||
* @return array list of parameters
|
||||
*/
|
||||
public static function request_parameters() {
|
||||
$params = array();
|
||||
|
||||
$params['page'] = array(
|
||||
'type' => 'integer',
|
||||
);
|
||||
|
||||
$params['id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'integer',
|
||||
);
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
@@ -1,271 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
/**
|
||||
* ActivityPub Inbox REST-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://www.w3.org/TR/activitypub/#inbox
|
||||
*/
|
||||
class Inbox {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'rest_api_init', array( '\Activitypub\Rest\Inbox', 'register_routes' ) );
|
||||
\add_filter( 'rest_pre_serve_request', array( '\Activitypub\Rest\Inbox', 'serve_request' ), 11, 4 );
|
||||
\add_action( 'activitypub_inbox_follow', array( '\Activitypub\Rest\Inbox', 'handle_follow' ), 10, 2 );
|
||||
\add_action( 'activitypub_inbox_unfollow', array( '\Activitypub\Rest\Inbox', 'handle_unfollow' ), 10, 2 );
|
||||
//\add_action( 'activitypub_inbox_like', array( '\Activitypub\Rest\Inbox', 'handle_reaction' ), 10, 2 );
|
||||
//\add_action( 'activitypub_inbox_announce', array( '\Activitypub\Rest\Inbox', 'handle_reaction' ), 10, 2 );
|
||||
\add_action( 'activitypub_inbox_create', array( '\Activitypub\Rest\Inbox', 'handle_create' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/inbox', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::EDITABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Inbox', 'shared_inbox' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/users/(?P<user_id>\d+)/inbox', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::EDITABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Inbox', 'user_inbox' ),
|
||||
'args' => self::request_parameters(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks into the REST API request to verify the signature.
|
||||
*
|
||||
* @param bool $served Whether the request has already been served.
|
||||
* @param WP_HTTP_ResponseInterface $result Result to send to the client. Usually a WP_REST_Response.
|
||||
* @param WP_REST_Request $request Request used to generate the response.
|
||||
* @param WP_REST_Server $server Server instance.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public static function serve_request( $served, $result, $request, $server ) {
|
||||
if ( '/activitypub' !== \substr( $request->get_route(), 0, 12 ) ) {
|
||||
return $served;
|
||||
}
|
||||
|
||||
$signature = $request->get_header( 'signature' );
|
||||
|
||||
if ( ! $signature ) {
|
||||
return $served;
|
||||
}
|
||||
|
||||
$headers = $request->get_headers();
|
||||
|
||||
// verify signature
|
||||
//\Activitypub\Signature::verify_signature( $headers, $key );
|
||||
|
||||
return $served;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the user-inbox
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public static function user_inbox( $request ) {
|
||||
$user_id = $request->get_param( 'user_id' );
|
||||
|
||||
$data = $request->get_params();
|
||||
$type = $request->get_param( 'type' );
|
||||
|
||||
\do_action( 'activitypub_inbox', $data, $user_id, $type );
|
||||
\do_action( "activitypub_inbox_{$type}", $data, $user_id );
|
||||
|
||||
return new \WP_REST_Response( array(), 202 );
|
||||
}
|
||||
|
||||
/**
|
||||
* The shared inbox
|
||||
*
|
||||
* @param [type] $request [description]
|
||||
*
|
||||
* @return WP_Error not yet implemented
|
||||
*/
|
||||
public static function shared_inbox( $request ) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The supported parameters
|
||||
*
|
||||
* @return array list of parameters
|
||||
*/
|
||||
public static function request_parameters() {
|
||||
$params = array();
|
||||
|
||||
$params['page'] = array(
|
||||
'type' => 'integer',
|
||||
);
|
||||
|
||||
$params['user_id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'integer',
|
||||
);
|
||||
|
||||
$params['id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'string',
|
||||
'validate_callback' => function( $param, $request, $key ) {
|
||||
if ( ! \is_string( $param ) ) {
|
||||
$param = $param['id'];
|
||||
}
|
||||
return ! \Activitypub\is_blacklisted( $param );
|
||||
},
|
||||
'sanitize_callback' => 'esc_url_raw',
|
||||
);
|
||||
|
||||
$params['actor'] = array(
|
||||
'required' => true,
|
||||
//'type' => array( 'object', 'string' ),
|
||||
'validate_callback' => function( $param, $request, $key ) {
|
||||
if ( ! \is_string( $param ) ) {
|
||||
$param = $param['id'];
|
||||
}
|
||||
return ! \Activitypub\is_blacklisted( $param );
|
||||
},
|
||||
'sanitize_callback' => function( $param, $request, $key ) {
|
||||
if ( ! \is_string( $param ) ) {
|
||||
$param = $param['id'];
|
||||
}
|
||||
return \esc_url_raw( $param );
|
||||
},
|
||||
);
|
||||
|
||||
$params['type'] = array(
|
||||
'required' => true,
|
||||
//'type' => 'enum',
|
||||
//'enum' => array( 'Create' ),
|
||||
'sanitize_callback' => function( $param, $request, $key ) {
|
||||
return \strtolower( $param );
|
||||
},
|
||||
);
|
||||
|
||||
$params['object'] = array(
|
||||
'required' => true,
|
||||
//'type' => 'object',
|
||||
);
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles "Follow" requests
|
||||
*
|
||||
* @param array $object The activity-object
|
||||
* @param int $user_id The id of the local blog-user
|
||||
*/
|
||||
public static function handle_follow( $object, $user_id ) {
|
||||
// save follower
|
||||
\Activitypub\Peer\Followers::add_follower( $object['actor'], $user_id );
|
||||
|
||||
// get inbox
|
||||
$inbox = \Activitypub\get_inbox_by_actor( $object['actor'] );
|
||||
|
||||
// send "Accept" activity
|
||||
$activity = new \Activitypub\Model\Activity( 'Accept', \Activitypub\Model\Activity::TYPE_SIMPLE );
|
||||
$activity->set_object( $object );
|
||||
$activity->set_actor( \get_author_posts_url( $user_id ) );
|
||||
$activity->set_to( $object['actor'] );
|
||||
$activity->set_id( \get_author_posts_url( $user_id ) . '#follow' . \preg_replace( '~^https?://~', '', $object['actor'] ) );
|
||||
|
||||
$activity = $activity->to_simple_json();
|
||||
|
||||
$response = \Activitypub\safe_remote_post( $inbox, $activity, $user_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles "Unfollow" requests
|
||||
*
|
||||
* @param array $object The activity-object
|
||||
* @param int $user_id The id of the local blog-user
|
||||
*/
|
||||
public static function handle_unfollow( $object, $user_id ) {
|
||||
\Activitypub\Peer\Followers::remove_follower( $object['actor'], $user_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles "Reaction" requests
|
||||
*
|
||||
* @param array $object The activity-object
|
||||
* @param int $user_id The id of the local blog-user
|
||||
*/
|
||||
public static function handle_reaction( $object, $user_id ) {
|
||||
$meta = \Activitypub\get_remote_metadata_by_actor( $object['actor'] );
|
||||
|
||||
$commentdata = array(
|
||||
'comment_post_ID' => \url_to_postid( $object['object'] ),
|
||||
'comment_author' => \esc_attr( $meta['name'] ),
|
||||
'comment_author_email' => '',
|
||||
'comment_author_url' => \esc_url_raw( $object['actor'] ),
|
||||
'comment_content' => \esc_url_raw( $object['actor'] ),
|
||||
'comment_type' => \esc_attr( \strtolower( $object['type'] ) ),
|
||||
'comment_parent' => 0,
|
||||
'comment_meta' => array(
|
||||
'source_url' => \esc_url_raw( $object['id'] ),
|
||||
'avatar_url' => \esc_url_raw( $meta['icon']['url'] ),
|
||||
'protocol' => 'activitypub',
|
||||
),
|
||||
);
|
||||
|
||||
// disable flood control
|
||||
\remove_action( 'check_comment_flood', 'check_comment_flood_db', 10 );
|
||||
|
||||
$state = \wp_new_comment( $commentdata, true );
|
||||
|
||||
// re-add flood control
|
||||
\add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles "Create" requests
|
||||
*
|
||||
* @param array $object The activity-object
|
||||
* @param int $user_id The id of the local blog-user
|
||||
*/
|
||||
public static function handle_create( $object, $user_id ) {
|
||||
$meta = \Activitypub\get_remote_metadata_by_actor( $object['actor'] );
|
||||
|
||||
$commentdata = array(
|
||||
'comment_post_ID' => \url_to_postid( $object['object']['inReplyTo'] ),
|
||||
'comment_author' => \esc_attr( $meta['name'] ),
|
||||
'comment_author_url' => \esc_url_raw( $object['actor'] ),
|
||||
'comment_content' => \wp_filter_kses( $object['object']['content'] ),
|
||||
'comment_type' => '',
|
||||
'comment_author_email' => '',
|
||||
'comment_parent' => 0,
|
||||
'comment_meta' => array(
|
||||
'source_url' => \esc_url_raw( $object['object']['url'] ),
|
||||
'avatar_url' => \esc_url_raw( $meta['icon']['url'] ),
|
||||
'protocol' => 'activitypub',
|
||||
),
|
||||
);
|
||||
|
||||
// disable flood control
|
||||
\remove_action( 'check_comment_flood', 'check_comment_flood_db', 10 );
|
||||
|
||||
$state = \wp_new_comment( $commentdata, true );
|
||||
|
||||
// re-add flood control
|
||||
\add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 );
|
||||
}
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
/**
|
||||
* ActivityPub NodeInfo REST-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see http://nodeinfo.diaspora.software/
|
||||
*/
|
||||
class Nodeinfo {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'rest_api_init', array( '\Activitypub\Rest\Nodeinfo', 'register_routes' ) );
|
||||
\add_filter( 'nodeinfo_data', array( '\Activitypub\Rest\Nodeinfo', 'add_nodeinfo_discovery' ), 10, 2 );
|
||||
\add_filter( 'nodeinfo2_data', array( '\Activitypub\Rest\Nodeinfo', 'add_nodeinfo2_discovery' ), 10 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/nodeinfo/discovery', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Nodeinfo', 'discovery' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/nodeinfo', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Nodeinfo', 'nodeinfo' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/nodeinfo2', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Nodeinfo', 'nodeinfo2' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render NodeInfo file
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public static function nodeinfo( $request ) {
|
||||
$nodeinfo = array();
|
||||
|
||||
$nodeinfo['version'] = '2.0';
|
||||
$nodeinfo['software'] = array(
|
||||
'name' => 'wordpress',
|
||||
'version' => \get_bloginfo( 'version' ),
|
||||
);
|
||||
|
||||
$users = \count_users();
|
||||
$posts = \wp_count_posts();
|
||||
$comments = \wp_count_comments();
|
||||
|
||||
$nodeinfo['usage'] = array(
|
||||
'users' => array(
|
||||
'total' => (int) $users['total_users'],
|
||||
),
|
||||
'localPosts' => (int) $posts->publish,
|
||||
'localComments' => (int) $comments->approved,
|
||||
);
|
||||
|
||||
$nodeinfo['openRegistrations'] = false;
|
||||
$nodeinfo['protocols'] = array( 'activitypub' );
|
||||
|
||||
$nodeinfo['services'] = array(
|
||||
'inbound' => array(),
|
||||
'outbound' => array(),
|
||||
);
|
||||
|
||||
$nodeinfo['metadata'] = array(
|
||||
'email' => \get_option( 'admin_email' ),
|
||||
);
|
||||
|
||||
return new \WP_REST_Response( $nodeinfo, 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render NodeInfo file
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public static function nodeinfo2( $request ) {
|
||||
$nodeinfo = array();
|
||||
|
||||
$nodeinfo['version'] = '1.0';
|
||||
$nodeinfo['server'] = array(
|
||||
'baseUrl' => home_url( '/' ),
|
||||
'name' => \get_bloginfo( 'name' ),
|
||||
'software' => 'wordpress',
|
||||
'version' => \get_bloginfo( 'version' ),
|
||||
);
|
||||
|
||||
$users = \count_users();
|
||||
$posts = \wp_count_posts();
|
||||
$comments = \wp_count_comments();
|
||||
|
||||
$nodeinfo['usage'] = array(
|
||||
'users' => array(
|
||||
'total' => (int) $users['total_users'],
|
||||
),
|
||||
'localPosts' => (int) $posts->publish,
|
||||
'localComments' => (int) $comments->approved,
|
||||
);
|
||||
|
||||
$nodeinfo['openRegistrations'] = false;
|
||||
$nodeinfo['protocols'] = array( 'activitypub' );
|
||||
|
||||
$nodeinfo['services'] = array(
|
||||
'inbound' => array(),
|
||||
'outbound' => array(),
|
||||
);
|
||||
|
||||
$nodeinfo['metadata'] = array(
|
||||
'email' => \get_option( 'admin_email' ),
|
||||
);
|
||||
|
||||
return new \WP_REST_Response( $nodeinfo, 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render NodeInfo discovery file
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public static function discovery( $request ) {
|
||||
$discovery = array();
|
||||
$discovery['links'] = array(
|
||||
array(
|
||||
'rel' => 'http://nodeinfo.diaspora.software/ns/schema/2.0',
|
||||
'href' => \get_rest_url( null, 'activitypub/1.0/nodeinfo' ),
|
||||
),
|
||||
);
|
||||
|
||||
return new \WP_REST_Response( $discovery, 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend NodeInfo data
|
||||
*
|
||||
* @param array $nodeinfo NodeInfo data
|
||||
* @param string The NodeInfo Version
|
||||
*
|
||||
* @return array The extended array
|
||||
*/
|
||||
public static function add_nodeinfo_discovery( $nodeinfo, $version ) {
|
||||
if ( '2.0' === $version ) {
|
||||
$nodeinfo['protocols'][] = 'activitypub';
|
||||
} else {
|
||||
$nodeinfo['protocols']['inbound'][] = 'activitypub';
|
||||
$nodeinfo['protocols']['outbound'][] = 'activitypub';
|
||||
}
|
||||
|
||||
return $nodeinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend NodeInfo2 data
|
||||
*
|
||||
* @param array $nodeinfo NodeInfo2 data
|
||||
*
|
||||
* @return array The extended array
|
||||
*/
|
||||
public static function add_nodeinfo2_discovery( $nodeinfo ) {
|
||||
$nodeinfo['protocols'][] = 'activitypub';
|
||||
|
||||
return $nodeinfo;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
/**
|
||||
* ActivityPub OStatus REST-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://www.w3.org/community/ostatus/
|
||||
*/
|
||||
class Ostatus {
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/ostatus/remote-follow', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Ostatus', 'get' ),
|
||||
// 'args' => self::request_parameters(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static function get() {
|
||||
// @todo implement
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
/**
|
||||
* ActivityPub Outbox REST-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://www.w3.org/TR/activitypub/#outbox
|
||||
*/
|
||||
class Outbox {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'rest_api_init', array( '\Activitypub\Rest\Outbox', 'register_routes' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/users/(?P<id>\d+)/outbox', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Outbox', 'user_outbox' ),
|
||||
'args' => self::request_parameters(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the user-outbox
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public static function user_outbox( $request ) {
|
||||
$user_id = $request->get_param( 'id' );
|
||||
$author = \get_user_by( 'ID', $user_id );
|
||||
|
||||
if ( ! $author ) {
|
||||
return new \WP_Error( 'rest_invalid_param', __( 'User not found', 'activitypub' ), array(
|
||||
'status' => 404,
|
||||
'params' => array(
|
||||
'user_id' => \__( 'User not found', 'activitypub' ),
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
$page = $request->get_param( 'page', 0 );
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the ActivityPub profile being created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_outbox_pre' );
|
||||
|
||||
$json = new \stdClass();
|
||||
|
||||
$json->{'@context'} = \Activitypub\get_context();
|
||||
$json->id = \home_url( \add_query_arg( null, null ) );
|
||||
$json->generator = 'http://wordpress.org/?v=' . \get_bloginfo_rss( 'version' );
|
||||
$json->actor = \get_author_posts_url( $user_id );
|
||||
$json->type = 'OrderedCollectionPage';
|
||||
$json->partOf = \get_rest_url( null, "/activitypub/1.0/users/$user_id/outbox" ); // phpcs:ignore
|
||||
|
||||
$count_posts = \wp_count_posts();
|
||||
$json->totalItems = \intval( $count_posts->publish ); // phpcs:ignore
|
||||
|
||||
$posts = \get_posts( array(
|
||||
'posts_per_page' => 10,
|
||||
'author' => $user_id,
|
||||
'offset' => $page * 10,
|
||||
) );
|
||||
|
||||
$json->first = \add_query_arg( 'page', 0, $json->partOf ); // phpcs:ignore
|
||||
$json->last = \add_query_arg( 'page', ( \ceil ( $json->totalItems / 10 ) ) - 1, $json->partOf ); // phpcs:ignore
|
||||
|
||||
if ( ( \ceil ( $json->totalItems / 10 ) ) - 1 > $page ) { // phpcs:ignore
|
||||
$json->next = \add_query_arg( 'page', ++$page, $json->partOf ); // phpcs:ignore
|
||||
}
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_NONE );
|
||||
$activitypub_activity->from_post( $activitypub_post->to_array() );
|
||||
$json->orderedItems[] = $activitypub_activity->to_array(); // phpcs:ignore
|
||||
}
|
||||
|
||||
// filter output
|
||||
$json = \apply_filters( 'activitypub_outbox_array', $json );
|
||||
|
||||
/*
|
||||
* Action triggerd after the ActivityPub profile has been created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_outbox_post' );
|
||||
|
||||
$response = new \WP_REST_Response( $json, 200 );
|
||||
|
||||
$response->header( 'Content-Type', 'application/activity+json' );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* The supported parameters
|
||||
*
|
||||
* @return array list of parameters
|
||||
*/
|
||||
public static function request_parameters() {
|
||||
$params = array();
|
||||
|
||||
$params['page'] = array(
|
||||
'type' => 'integer',
|
||||
);
|
||||
|
||||
$params['id'] = array(
|
||||
'required' => true,
|
||||
'type' => 'integer',
|
||||
);
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
/**
|
||||
* Custom (hopefully temporary) ActivityPub Rest Server
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class Server extends \WP_REST_Server {
|
||||
/**
|
||||
* Overwrite dispatch function to quick fix missing subtype featur
|
||||
*
|
||||
* @see https://core.trac.wordpress.org/ticket/49404
|
||||
*
|
||||
* @param WP_REST_Request $request Request to attempt dispatching.
|
||||
* @return WP_REST_Response Response returned by the callback.
|
||||
*/
|
||||
public function dispatch( $request ) {
|
||||
$content_type = $request->get_content_type();
|
||||
|
||||
// check for content-sub-types like 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
|
||||
if ( \preg_match( '/application\/([a-zA-Z+_-]+\+)json/', $content_type['value'] ) ) {
|
||||
$request->set_header( 'Content-Type', 'application/json' );
|
||||
}
|
||||
|
||||
// make request filterable
|
||||
$request = apply_filters( 'activitypub_pre_dispatch_request', $request );
|
||||
|
||||
return parent::dispatch( $request );
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
/**
|
||||
* ActivityPub WebFinger REST-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://webfinger.net/
|
||||
*/
|
||||
class Webfinger {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
public static function init() {
|
||||
\add_action( 'rest_api_init', array( '\Activitypub\Rest\Webfinger', 'register_routes' ) );
|
||||
\add_action( 'webfinger_user_data', array( '\Activitypub\Rest\Webfinger', 'add_webfinger_discovery' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
'activitypub/1.0', '/webfinger', array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array( '\Activitypub\Rest\Webfinger', 'webfinger' ),
|
||||
'args' => self::request_parameters(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render JRD file
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public static function webfinger( $request ) {
|
||||
$resource = $request->get_param( 'resource' );
|
||||
|
||||
$matches = array();
|
||||
$matched = \preg_match( '/^acct:([^@]+)@(.+)$/', $resource, $matches );
|
||||
|
||||
if ( ! $matched ) {
|
||||
return new \WP_Error( 'activitypub_unsupported_resource', \__( 'Resource is invalid', 'activitypub' ), array( 'status' => 400 ) );
|
||||
}
|
||||
|
||||
$resource_identifier = $matches[1];
|
||||
$resource_host = $matches[2];
|
||||
|
||||
if ( \wp_parse_url( \home_url( '/' ), PHP_URL_HOST ) !== $resource_host ) {
|
||||
return new \WP_Error( 'activitypub_wrong_host', \__( 'Resource host does not match blog host', 'activitypub' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
$user = \get_user_by( 'login', \esc_sql( $resource_identifier ) );
|
||||
|
||||
if ( ! $user ) {
|
||||
return new \WP_Error( 'activitypub_user_not_found', \__( 'User not found', 'activitypub' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
$json = array(
|
||||
'subject' => $resource,
|
||||
'aliases' => array(
|
||||
\get_author_posts_url( $user->ID ),
|
||||
),
|
||||
'links' => array(
|
||||
array(
|
||||
'rel' => 'self',
|
||||
'type' => 'application/activity+json',
|
||||
'href' => \get_author_posts_url( $user->ID ),
|
||||
),
|
||||
array(
|
||||
'rel' => 'http://webfinger.net/rel/profile-page',
|
||||
'type' => 'text/html',
|
||||
'href' => \get_author_posts_url( $user->ID ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return new \WP_REST_Response( $json, 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* The supported parameters
|
||||
*
|
||||
* @return array list of parameters
|
||||
*/
|
||||
public static function request_parameters() {
|
||||
$params = array();
|
||||
|
||||
$params['resource'] = array(
|
||||
'required' => true,
|
||||
'type' => 'string',
|
||||
'pattern' => '^acct:([^@]+)@(.+)$',
|
||||
);
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add WebFinger discovery links
|
||||
*
|
||||
* @param array $array the jrd array
|
||||
* @param string $resource the WebFinger resource
|
||||
* @param WP_User $user the WordPress user
|
||||
*/
|
||||
public static function add_webfinger_discovery( $array, $resource, $user ) {
|
||||
$array['links'][] = array(
|
||||
'rel' => 'self',
|
||||
'type' => 'application/activity+json',
|
||||
'href' => \get_author_posts_url( $user->ID ),
|
||||
);
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
namespace Activitypub\Table;
|
||||
|
||||
if ( ! \class_exists( '\WP_List_Table' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
||||
}
|
||||
|
||||
class Followers_List extends \WP_List_Table {
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'identifier' => \__( 'Identifier', 'activitypub' ),
|
||||
);
|
||||
}
|
||||
|
||||
public function get_sortable_columns() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function prepare_items() {
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
|
||||
$this->process_action();
|
||||
$this->_column_headers = array( $columns, $hidden, $this->get_sortable_columns() );
|
||||
|
||||
$this->items = array();
|
||||
|
||||
foreach ( \Activitypub\Peer\Followers::get_followers( \get_current_user_id() ) as $follower ) {
|
||||
$this->items[]['identifier'] = \esc_attr( $follower );
|
||||
}
|
||||
}
|
||||
|
||||
public function column_default( $item, $column_name ) {
|
||||
return $item[ $column_name ];
|
||||
}
|
||||
}
|
||||
@@ -1,307 +0,0 @@
|
||||
# Copyright (C) 2020 Matthias Pfefferle
|
||||
# This file is distributed under the MIT.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: ActivityPub 0.10.1\n"
|
||||
"Report-Msgid-Bugs-To: "
|
||||
"https://wordpress.org/support/plugin/wordpress-activitypub\n"
|
||||
"POT-Creation-Date: 2020-05-03 22:06:03+00:00\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"X-Generator: grunt-wp-i18n 1.0.3\n"
|
||||
|
||||
#: includes/class-admin.php:33
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:33 templates/followers-list.php:2
|
||||
msgid "Followers (Fediverse)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:59
|
||||
msgid "Use title and link, summary or full content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:71
|
||||
msgid "The Activity-Object-Type"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:83 templates/settings.php:36
|
||||
msgid "Use the Shortlink instead of the permalink"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:90
|
||||
msgid ""
|
||||
"Add hashtags in the content as native tags and replace the #tag with the "
|
||||
"tag-link"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:97
|
||||
msgid "Add all tags as hashtags at the end of each activity"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:104
|
||||
msgid "Enable ActivityPub support for post types"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:112
|
||||
msgid "Block fediverse instances"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:123
|
||||
msgid "Overview"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:125
|
||||
msgid ""
|
||||
"ActivityPub is a decentralized social networking protocol based on the "
|
||||
"ActivityStreams 2.0 data format. ActivityPub is an official W3C recommended "
|
||||
"standard published by the W3C Social Web Working Group. It provides a "
|
||||
"client to server API for creating, updating and deleting content, as well "
|
||||
"as a federated server to server API for delivering notifications and "
|
||||
"subscribing to content."
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:130
|
||||
msgid "For more information:"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:131
|
||||
msgid "<a href=\"https://activitypub.rocks/\">Test Suite</a>"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:132
|
||||
msgid "<a href=\"https://www.w3.org/TR/activitypub/\">W3C Spec</a>"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:133
|
||||
msgid ""
|
||||
"<a href=\"https://github.com/pfefferle/wordpress-activitypub/issues\">Give "
|
||||
"us feedback</a>"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:135
|
||||
msgid "<a href=\"https://notiz.blog/donate\">Donate</a>"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-admin.php:145
|
||||
msgid "Fediverse"
|
||||
msgstr ""
|
||||
|
||||
#: includes/functions.php:110
|
||||
msgid "The \"actor\" is no valid URL"
|
||||
msgstr ""
|
||||
|
||||
#: includes/functions.php:132
|
||||
msgid "No valid JSON data"
|
||||
msgstr ""
|
||||
|
||||
#: includes/functions.php:160
|
||||
msgid "No \"Inbox\" found"
|
||||
msgstr ""
|
||||
|
||||
#: includes/functions.php:186
|
||||
msgid "No \"Public-Key\" found"
|
||||
msgstr ""
|
||||
|
||||
#: includes/functions.php:214
|
||||
msgid "Profile identifier"
|
||||
msgstr ""
|
||||
|
||||
#: includes/functions.php:219
|
||||
#. translators: the webfinger resource
|
||||
msgid "Try to follow \"@%s\" in the Mastodon/Friendica search field."
|
||||
msgstr ""
|
||||
|
||||
#: includes/peer/class-followers.php:53
|
||||
msgid "Unknown Actor schema"
|
||||
msgstr ""
|
||||
|
||||
#: includes/rest/class-followers.php:46 includes/rest/class-followers.php:49
|
||||
#: includes/rest/class-following.php:46 includes/rest/class-following.php:49
|
||||
#: includes/rest/class-outbox.php:45 includes/rest/class-outbox.php:48
|
||||
#: includes/rest/class-webfinger.php:61
|
||||
msgid "User not found"
|
||||
msgstr ""
|
||||
|
||||
#: includes/rest/class-webfinger.php:48
|
||||
msgid "Resource is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: includes/rest/class-webfinger.php:55
|
||||
msgid "Resource host does not match blog host"
|
||||
msgstr ""
|
||||
|
||||
#: includes/table/followers-list.php:11
|
||||
msgid "Identifier"
|
||||
msgstr ""
|
||||
|
||||
#: templates/followers-list.php:4
|
||||
msgid "You currently have %s followers."
|
||||
msgstr ""
|
||||
|
||||
#: templates/json-author.php:48
|
||||
msgid "Blog"
|
||||
msgstr ""
|
||||
|
||||
#: templates/json-author.php:58
|
||||
msgid "Profile"
|
||||
msgstr ""
|
||||
|
||||
#: templates/json-author.php:69
|
||||
msgid "Website"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:2
|
||||
msgid "ActivityPub Settings"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:4
|
||||
msgid ""
|
||||
"ActivityPub turns your blog into a federated social network. This means you "
|
||||
"can share and talk to everyone using the ActivityPub protocol, including "
|
||||
"users of Friendica, Pleroma and Mastodon."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:9
|
||||
msgid "Activities"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:11
|
||||
msgid "All activity related settings."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:17
|
||||
msgid "Post-Content"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:21
|
||||
msgid "Title and link"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:21
|
||||
msgid "Only the title and a link."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:24
|
||||
msgid "Excerpt"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:24
|
||||
msgid "A content summary, shortened to 400 characters and without markup."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:27
|
||||
msgid "Content (default)"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:27
|
||||
msgid "The full content."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:33
|
||||
msgid "Backlink"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:42
|
||||
msgid "Activity-Object-Type"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:46
|
||||
msgid "Note (default)"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:46
|
||||
msgid "Should work with most platforms."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:49
|
||||
msgid "Article"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:49
|
||||
msgid ""
|
||||
"The presentation of the \"Article\" might change on different platforms. "
|
||||
"Mastodon for example shows the \"Article\" type as a simple link."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:52
|
||||
msgid "WordPress Post-Format"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:52
|
||||
msgid "Maps the WordPress Post-Format to the ActivityPub Object Type."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:57
|
||||
msgid "Supported post types"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:60
|
||||
msgid "Enable ActivityPub support for the following post types:"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:77
|
||||
msgid "Hashtags"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:81
|
||||
msgid ""
|
||||
"Add hashtags in the content as native tags and replace the "
|
||||
"<code>#tag</code> with the tag-link."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:84
|
||||
msgid "Add all tags as hashtags to the end of each activity."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:93
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:95
|
||||
msgid "Server related settings."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:106
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:110
|
||||
msgid ""
|
||||
"A list of hosts, you want to block, one host per line. Please use only the "
|
||||
"host/domain of the server you want to block, without <code>http://</code> "
|
||||
"and without <code>www.</code>. For example <code>example.com</code>."
|
||||
msgstr ""
|
||||
|
||||
#: templates/settings.php:124
|
||||
msgid ""
|
||||
"If you like this plugin, what about a small <a "
|
||||
"href=\"https://notiz.blog/donate\">donation</a>?"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "ActivityPub"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin/theme
|
||||
msgid "https://github.com/pfefferle/wordpress-activitypub/"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid ""
|
||||
"The ActivityPub protocol is a decentralized social networking protocol "
|
||||
"based upon the ActivityStreams 2.0 data format."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "Matthias Pfefferle"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "https://notiz.blog/"
|
||||
msgstr ""
|
||||
@@ -1,281 +0,0 @@
|
||||
=== ActivityPub ===
|
||||
Contributors: pfefferle
|
||||
Donate link: https://notiz.blog/donate/
|
||||
Tags: OStatus, fediverse, activitypub, activitystream
|
||||
Requires at least: 4.7
|
||||
Tested up to: 5.4.1
|
||||
Stable tag: 0.10.1
|
||||
Requires PHP: 5.6
|
||||
License: MIT
|
||||
License URI: http://opensource.org/licenses/MIT
|
||||
|
||||
The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format.
|
||||
|
||||
== Description ==
|
||||
|
||||
This is **BETA** software, see the FAQ to see the current feature set or rather what is still planned.
|
||||
|
||||
The plugin implements the ActivityPub protocol for your blog. Your readers will be able to follow your blogposts on Mastodon and other federated platforms that support ActivityPub.
|
||||
|
||||
The plugin works with the following federated platforms:
|
||||
|
||||
* [Mastodon](https://joinmastodon.org/)
|
||||
* [Pleroma](https://pleroma.social/)
|
||||
* [Friendica](https://friendi.ca/)
|
||||
* [HubZilla](https://hubzilla.org/)
|
||||
* [Pixelfed](https://pixelfed.org/)
|
||||
* [SocialHome](https://socialhome.network/)
|
||||
* [Misskey](https://join.misskey.page/)
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
|
||||
= What is the status of this plugin? =
|
||||
|
||||
Implemented:
|
||||
|
||||
* profile pages (JSON representation)
|
||||
* custom links
|
||||
* functional inbox/outbox
|
||||
* follow (accept follows)
|
||||
* share posts
|
||||
* receive comments/reactions
|
||||
|
||||
To implement:
|
||||
|
||||
* signature verification
|
||||
* better WordPress integration
|
||||
* better configuration possibilities
|
||||
* threaded comments support
|
||||
|
||||
= What is "ActivityPub for WordPress" =
|
||||
|
||||
*ActivityPub for WordPress* extends WordPress with some Fediverse features, but it does not compete with platforms like Friendica or Mastodon. If you want to run a **decentralized social network**, please use [Mastodon](https://joinmastodon.org/) or [GNU social](https://gnu.io/social/).
|
||||
|
||||
= What are the differences between this plugin and Pterotype? =
|
||||
|
||||
**Compatibility**
|
||||
|
||||
*ActivityPub for WordPress* is compatible with OStatus and IndieWeb plugin suites. *Pterotype* is incompatible with the standalone [WebFinger plugin](https://wordpress.org/plugins/webfinger/), so it can't be run together with OStatus.
|
||||
|
||||
**Custom tables**
|
||||
|
||||
*Pterotype* creates/uses a bunch of custom tables, *ActivityPub for WordPress* only uses the native tables and adds as little meta data as possible.
|
||||
|
||||
= What if you are running your blog in a subdirectory? =
|
||||
|
||||
In order for webfinger to work, it must be mapped to the root directory of the URL on which your blog resides.
|
||||
|
||||
**Apache**
|
||||
|
||||
Add the following to the .htaccess file in the root directory:
|
||||
|
||||
RedirectMatch "^\/\.well-known(.*)$" "\/blog\/\.well-known$1"
|
||||
|
||||
Where 'blog' is the path to the subdirectory at which your blog resides.
|
||||
|
||||
**Nginx**
|
||||
|
||||
Add the following to the site.conf in sites-available:
|
||||
|
||||
location ~* /.well-known {
|
||||
allow all;
|
||||
try_files $uri $uri/ /blog/?$args;
|
||||
}
|
||||
|
||||
Where 'blog' is the path to the subdirectory at which your blog resides.
|
||||
|
||||
== Changelog ==
|
||||
|
||||
Project maintained on GitHub at [pfefferle/wordpress-activitypub](https://github.com/pfefferle/wordpress-activitypub).
|
||||
|
||||
= 0.10.1 =
|
||||
|
||||
* fix inbox activities, like follow
|
||||
* fix debug
|
||||
|
||||
= 0.10.0 =
|
||||
|
||||
* add image alt text to the ActivityStreams attachment property in a format that Mastodon can read. props [@BenLubar](https://github.com/BenLubar)
|
||||
* use the "summary" property for a title as Mastodon does. props [@BenLubar](https://github.com/BenLubar)
|
||||
* support authorized fetch to avoid having comments from "Anonymous". props [@BenLubar](https://github.com/BenLubar)
|
||||
* add new post type: "title and link only". props [@bgcarlisle](https://github.com/bgcarlisle)
|
||||
|
||||
= 0.9.1 =
|
||||
|
||||
* disable shared inbox
|
||||
* disable delete activity
|
||||
|
||||
= 0.9.0 =
|
||||
|
||||
* some code refactorings
|
||||
* fix #73
|
||||
|
||||
= 0.8.3 =
|
||||
|
||||
* fixed accept header bug
|
||||
|
||||
= 0.8.2 =
|
||||
|
||||
* add all required accept header
|
||||
* better/simpler accept-header handling
|
||||
* add debugging mechanism
|
||||
* Add setting to enable AP for different (public) Post-Types
|
||||
* explicit use of global functions
|
||||
|
||||
= 0.8.1 =
|
||||
|
||||
* fixed PHP warnings
|
||||
|
||||
= 0.8.0 =
|
||||
|
||||
* Moved followers list to user-menu
|
||||
|
||||
= 0.7.4 =
|
||||
|
||||
* added admin_email to metadata, to be able to "Manage your instance" on https://fediverse.network/manage/
|
||||
|
||||
= 0.7.3 =
|
||||
|
||||
* refactorings
|
||||
* fixed PHP warnings
|
||||
* better hashtag regex
|
||||
|
||||
= 0.7.2 =
|
||||
|
||||
* fixed JSON representation of posts https://merveilles.town/@xuv/101907542498716956
|
||||
|
||||
= 0.7.1 =
|
||||
|
||||
* fixed inbox problems with pleroma
|
||||
|
||||
= 0.7.0 =
|
||||
|
||||
* finally fixed pleroma compatibility
|
||||
* added "following" endpoint
|
||||
* simplified "followers" endpoint
|
||||
* fixed default value problem
|
||||
|
||||
= 0.6.0 =
|
||||
|
||||
* add tags as hashtags to the end of each activity
|
||||
* fixed pleroma following issue
|
||||
* followers-list improvements
|
||||
|
||||
= 0.5.1 =
|
||||
|
||||
* fixed name-collision that caused an infinite loop
|
||||
|
||||
= 0.5.0 =
|
||||
|
||||
* complete refactoring
|
||||
* fixed bug #30: Password-protected posts are federated
|
||||
* only send Activites when ActivityPub is enabled for this post-type
|
||||
|
||||
= 0.4.4 =
|
||||
|
||||
* show avatars
|
||||
|
||||
= 0.4.3 =
|
||||
|
||||
* finally fixed backlink in excerpt/summary posts
|
||||
|
||||
= 0.4.2 =
|
||||
|
||||
* fixed backlink in excerpt/summary posts (thanks @depone)
|
||||
|
||||
= 0.4.1 =
|
||||
|
||||
* finally fixed contact list
|
||||
|
||||
= 0.4.0 =
|
||||
|
||||
* added settings to enable/disable hashtag support
|
||||
* fixed follower list
|
||||
* send activities only for new posts, otherwise send updates
|
||||
|
||||
= 0.3.2 =
|
||||
|
||||
* added "followers" endpoint
|
||||
* change activity content from blog 'excerpt' to blog 'content'
|
||||
|
||||
= 0.3.1 =
|
||||
|
||||
* better json encoding
|
||||
|
||||
= 0.3.0 =
|
||||
|
||||
* basic hashtag support
|
||||
* temporarily deactivated likes and boosts
|
||||
* added support for actor objects
|
||||
* fixed encoding issue
|
||||
|
||||
= 0.2.1 =
|
||||
|
||||
* customizable backlink (permalink or shorturl)
|
||||
* show profile-identifiers also on profile settings
|
||||
|
||||
= 0.2.0 =
|
||||
|
||||
* added option to switch between content and excerpt
|
||||
* removed html and duplicate new-lines
|
||||
|
||||
= 0.1.1 =
|
||||
|
||||
* fixed "excerpt" in AS JSON
|
||||
* added settings for the activity-summary and for the activity-object-type
|
||||
|
||||
= 0.1.0 =
|
||||
|
||||
* added basic WebFinger support
|
||||
* added basic NodeInfo support
|
||||
* fully functional "follow" activity
|
||||
* send new posts to your followers
|
||||
* receive comments from your followers
|
||||
|
||||
= 0.0.2 =
|
||||
|
||||
* refactoring
|
||||
* functional inbox
|
||||
* nicer profile views
|
||||
|
||||
= 0.0.1 =
|
||||
|
||||
* initial
|
||||
|
||||
== Installation ==
|
||||
|
||||
Follow the normal instructions for [installing WordPress plugins](https://wordpress.org/support/article/managing-plugins/).
|
||||
|
||||
= Automatic Plugin Installation =
|
||||
|
||||
To add a WordPress Plugin using the [built-in plugin installer](https://codex.wordpress.org/Administration_Screens#Add_New_Plugins):
|
||||
|
||||
1. Go to [Plugins](https://codex.wordpress.org/Administration_Screens#Plugins) > [Add New](https://codex.wordpress.org/Plugins_Add_New_Screen).
|
||||
1. Type "`activitypub`" into the **Search Plugins** box.
|
||||
1. Find the WordPress Plugin you wish to install.
|
||||
1. Click **Details** for more information about the Plugin and instructions you may wish to print or save to help setup the Plugin.
|
||||
1. Click **Install Now** to install the WordPress Plugin.
|
||||
1. The resulting installation screen will list the installation as successful or note any problems during the install.
|
||||
1. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions.
|
||||
|
||||
= Manual Plugin Installation =
|
||||
|
||||
There are a few cases when manually installing a WordPress Plugin is appropriate.
|
||||
|
||||
* If you wish to control the placement and the process of installing a WordPress Plugin.
|
||||
* If your server does not permit automatic installation of a WordPress Plugin.
|
||||
* If you want to try the [latest development version](https://github.com/pfefferle/wordpress-activitypub).
|
||||
|
||||
Installation of a WordPress Plugin manually requires FTP familiarity and the awareness that you may put your site at risk if you install a WordPress Plugin incompatible with the current version or from an unreliable source.
|
||||
|
||||
Backup your site completely before proceeding.
|
||||
|
||||
To install a WordPress Plugin manually:
|
||||
|
||||
* Download your WordPress Plugin to your desktop.
|
||||
* Download from [the WordPress directory](https://wordpress.org/plugins/activitypub/)
|
||||
* Download from [GitHub](https://github.com/pfefferle/wordpress-activitypub/releases)
|
||||
* If downloaded as a zip archive, extract the Plugin folder to your desktop.
|
||||
* With your FTP program, upload the Plugin folder to the `wp-content/plugins` folder in your WordPress directory online.
|
||||
* Go to [Plugins screen](https://codex.wordpress.org/Administration_Screens#Plugins) and find the newly uploaded Plugin in the list.
|
||||
* Click **Activate** to activate it.
|
||||
@@ -1,15 +0,0 @@
|
||||
<div class="wrap">
|
||||
<h1><?php \esc_html_e( 'Followers (Fediverse)', 'activitypub' ); ?></h1>
|
||||
|
||||
<p><?php \printf( \__( 'You currently have %s followers.', 'activitypub' ), \esc_attr( \Activitypub\Peer\Followers::count_followers( \get_current_user_id() ) ) ); ?></p>
|
||||
|
||||
<?php $token_table = new \Activitypub\Table\Followers_List(); ?>
|
||||
|
||||
<form method="get">
|
||||
<input type="hidden" name="page" value="indieauth_user_token" />
|
||||
<?php
|
||||
$token_table->prepare_items();
|
||||
$token_table->display();
|
||||
?>
|
||||
</form>
|
||||
</div>
|
||||
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
$author_id = \get_the_author_meta( 'ID' );
|
||||
|
||||
$json = new \stdClass();
|
||||
|
||||
$json->{'@context'} = \Activitypub\get_context();
|
||||
$json->id = \get_author_posts_url( $author_id );
|
||||
$json->type = 'Person';
|
||||
$json->name = \get_the_author_meta( 'display_name', $author_id );
|
||||
$json->summary = \html_entity_decode(
|
||||
\get_the_author_meta( 'description', $author_id ),
|
||||
ENT_QUOTES,
|
||||
'UTF-8'
|
||||
);
|
||||
$json->preferredUsername = \get_the_author_meta( 'login', $author_id ); // phpcs:ignore
|
||||
$json->url = \get_author_posts_url( $author_id );
|
||||
$json->icon = array(
|
||||
'type' => 'Image',
|
||||
'url' => \get_avatar_url( $author_id, array( 'size' => 120 ) ),
|
||||
);
|
||||
|
||||
if ( \has_header_image() ) {
|
||||
$json->image = array(
|
||||
'type' => 'Image',
|
||||
'url' => \get_header_image(),
|
||||
);
|
||||
}
|
||||
|
||||
$json->inbox = \get_rest_url( null, "/activitypub/1.0/users/$author_id/inbox" );
|
||||
$json->outbox = \get_rest_url( null, "/activitypub/1.0/users/$author_id/outbox" );
|
||||
$json->followers = \get_rest_url( null, "/activitypub/1.0/users/$author_id/followers" );
|
||||
$json->following = \get_rest_url( null, "/activitypub/1.0/users/$author_id/following" );
|
||||
|
||||
$json->manuallyApprovesFollowers = \apply_filters( 'activitypub_json_manually_approves_followers', __return_false() ); // phpcs:ignore
|
||||
|
||||
// phpcs:ignore
|
||||
$json->publicKey = array(
|
||||
'id' => \get_author_posts_url( $author_id ) . '#main-key',
|
||||
'owner' => \get_author_posts_url( $author_id ),
|
||||
'publicKeyPem' => \trim( \Activitypub\Signature::get_public_key( $author_id ) ),
|
||||
);
|
||||
|
||||
$json->tag = array();
|
||||
$json->attachment = array();
|
||||
|
||||
$json->attachment[] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => __( 'Blog', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
'<a rel="me" title="' . \esc_attr( \home_url( '/' ) ) . '" target="_blank" href="' . \home_url( '/' ) . '">' . \wp_parse_url( \home_url( '/' ), PHP_URL_HOST ) . '</a>',
|
||||
ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
|
||||
$json->attachment[] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => __( 'Profile', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
'<a rel="me" title="' . \esc_attr( \get_author_posts_url( $author_id ) ) . '" target="_blank" href="' . \get_author_posts_url( $author_id ) . '">' . \wp_parse_url( \get_author_posts_url( $author_id ), PHP_URL_HOST ) . '</a>',
|
||||
ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
|
||||
if ( \get_the_author_meta( 'user_url', $author_id ) ) {
|
||||
$json->attachment[] = array(
|
||||
'type' => 'PropertyValue',
|
||||
'name' => __( 'Website', 'activitypub' ),
|
||||
'value' => \html_entity_decode(
|
||||
'<a rel="me" title="' . \esc_attr( \get_the_author_meta( 'user_url', $author_id ) ) . '" target="_blank" href="' . \get_the_author_meta( 'user_url', $author_id ) . '">' . \wp_parse_url( \get_the_author_meta( 'user_url', $author_id ), PHP_URL_HOST ) . '</a>',
|
||||
ENT_QUOTES,
|
||||
'UTF-8'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
$json->endpoints = array(
|
||||
'sharedInbox' => \get_rest_url( null, '/activitypub/1.0/inbox' ),
|
||||
);
|
||||
*/
|
||||
|
||||
// filter output
|
||||
$json = \apply_filters( 'activitypub_json_author_array', $json );
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the ActivityPub profile being created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_json_author_pre' );
|
||||
|
||||
$options = 0;
|
||||
// JSON_PRETTY_PRINT added in PHP 5.4
|
||||
if ( \get_query_var( 'pretty' ) ) {
|
||||
$options |= JSON_PRETTY_PRINT; // phpcs:ignore
|
||||
}
|
||||
|
||||
$options |= JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT;
|
||||
|
||||
/*
|
||||
* Options to be passed to json_encode()
|
||||
*
|
||||
* @param int $options The current options flags
|
||||
*/
|
||||
$options = \apply_filters( 'activitypub_json_author_options', $options );
|
||||
|
||||
\header( 'Content-Type: application/activity+json' );
|
||||
echo \wp_json_encode( $json, $options );
|
||||
|
||||
/*
|
||||
* Action triggerd after the ActivityPub profile has been created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_json_author_post' );
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
$post = \get_post();
|
||||
|
||||
$activitypub_post = new \Activitypub\Model\Post( $post );
|
||||
$json = \array_merge( array( '@context' => \Activitypub\get_context() ), $activitypub_post->to_array() );
|
||||
|
||||
// filter output
|
||||
$json = \apply_filters( 'activitypub_json_post_array', $json );
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the ActivityPub profile being created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_json_post_pre' );
|
||||
|
||||
$options = 0;
|
||||
// JSON_PRETTY_PRINT added in PHP 5.4
|
||||
if ( \get_query_var( 'pretty' ) ) {
|
||||
$options |= JSON_PRETTY_PRINT; // phpcs:ignore
|
||||
}
|
||||
|
||||
$options |= JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT;
|
||||
|
||||
/*
|
||||
* Options to be passed to json_encode()
|
||||
*
|
||||
* @param int $options The current options flags
|
||||
*/
|
||||
$options = \apply_filters( 'activitypub_json_post_options', $options );
|
||||
|
||||
\header( 'Content-Type: application/activity+json' );
|
||||
echo \wp_json_encode( $json, $options );
|
||||
|
||||
/*
|
||||
* Action triggerd after the ActivityPub profile has been created and sent to the client
|
||||
*/
|
||||
\do_action( 'activitypub_json_post_post' );
|
||||
@@ -1,126 +0,0 @@
|
||||
<div class="wrap">
|
||||
<h1><?php \esc_html_e( 'ActivityPub Settings', 'activitypub' ); ?></h1>
|
||||
|
||||
<p><?php \esc_html_e( 'ActivityPub turns your blog into a federated social network. This means you can share and talk to everyone using the ActivityPub protocol, including users of Friendica, Pleroma and Mastodon.', 'activitypub' ); ?></p>
|
||||
|
||||
<form method="post" action="options.php">
|
||||
<?php \settings_fields( 'activitypub' ); ?>
|
||||
|
||||
<h2><?php \esc_html_e( 'Activities', 'activitypub' ); ?></h2>
|
||||
|
||||
<p><?php \esc_html_e( 'All activity related settings.', 'activitypub' ); ?></p>
|
||||
|
||||
<table class="form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php esc_html_e( 'Post-Content', 'activitypub' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<p>
|
||||
<label><input type="radio" name="activitypub_post_content_type" id="activitypub_post_content_type_title_link" value="title" <?php echo \checked( 'title', \get_option( 'activitypub_post_content_type', 'content' ) ); ?> /> <?php \esc_html_e( 'Title and link', 'activitypub' ); ?></label> - <span class="description"><?php \esc_html_e( 'Only the title and a link.', 'activitypub' ); ?></span>
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="radio" name="activitypub_post_content_type" id="activitypub_post_content_type_excerpt" value="excerpt" <?php echo \checked( 'excerpt', \get_option( 'activitypub_post_content_type', 'content' ) ); ?> /> <?php \esc_html_e( 'Excerpt', 'activitypub' ); ?></label> - <span class="description"><?php \esc_html_e( 'A content summary, shortened to 400 characters and without markup.', 'activitypub' ); ?></span>
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="radio" name="activitypub_post_content_type" id="activitypub_post_content_type_content" value="content" <?php echo \checked( 'content', \get_option( 'activitypub_post_content_type', 'content' ) ); ?> /> <?php \esc_html_e( 'Content (default)', 'activitypub' ); ?></label> - <span class="description"><?php \esc_html_e( 'The full content.', 'activitypub' ); ?></span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php \esc_html_e( 'Backlink', 'activitypub' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<p><label><input type="checkbox" name="activitypub_use_shortlink" id="activitypub_use_shortlink" value="1" <?php echo \checked( '1', \get_option( 'activitypub_use_shortlink', '0' ) ); ?> /> <?php \esc_html_e( 'Use the Shortlink instead of the permalink', 'activitypub' ); ?></label></p>
|
||||
<p class="description"><?php \printf( esc_html( 'I can recommend %sHum%s, to prettify the Shortlinks', 'activitypub' ), '<a href="https://wordpress.org/plugins/hum/" target="_blank">', '</a>' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php \esc_html_e( 'Activity-Object-Type', 'activitypub' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<p>
|
||||
<label><input type="radio" name="activitypub_object_type" id="activitypub_object_type_note" value="note" <?php echo \checked( 'note', \get_option( 'activitypub_object_type', 'note' ) ); ?> /> <?php \esc_html_e( 'Note (default)', 'activitypub' ); ?></label> - <span class="description"><?php \esc_html_e( 'Should work with most platforms.', 'activitypub' ); ?></span>
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="radio" name="activitypub_object_type" id="activitypub_object_type_article" value="article" <?php echo \checked( 'article', \get_option( 'activitypub_object_type', 'note' ) ); ?> /> <?php \esc_html_e( 'Article', 'activitypub' ); ?></label> - <span class="description"><?php \esc_html_e( 'The presentation of the "Article" might change on different platforms. Mastodon for example shows the "Article" type as a simple link.', 'activitypub' ); ?></span>
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="radio" name="activitypub_object_type" id="activitypub_object_type" value="wordpress-post-format" <?php echo \checked( 'wordpress-post-format', \get_option( 'activitypub_object_type', 'note' ) ); ?> /> <?php \esc_html_e( 'WordPress Post-Format', 'activitypub' ); ?></label> - <span class="description"><?php \esc_html_e( 'Maps the WordPress Post-Format to the ActivityPub Object Type.', 'activitypub' ); ?></span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php \esc_html_e( 'Supported post types', 'activitypub' ); ?></th>
|
||||
<td>
|
||||
<fieldset>
|
||||
<?php \esc_html_e( 'Enable ActivityPub support for the following post types:', 'activitypub' ); ?>
|
||||
|
||||
<?php $post_types = \get_post_types( array( 'public' => true ), 'objects' ); ?>
|
||||
<?php $support_post_types = \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) ) ? \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) ) : array(); ?>
|
||||
<ul>
|
||||
<?php foreach ( $post_types as $post_type ) { ?>
|
||||
<li>
|
||||
<input type="checkbox" id="activitypub_support_post_types" name="activitypub_support_post_types[]" value="<?php echo \esc_attr( $post_type->name ); ?>" <?php echo \checked( true, \in_array( $post_type->name, $support_post_types, true ) ); ?> />
|
||||
<label for="<?php echo \esc_attr( $post_type->name ); ?>"><?php echo \esc_html( $post_type->label ); ?></label>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php \esc_html_e( 'Hashtags', 'activitypub' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<p>
|
||||
<label><input type="checkbox" name="activitypub_use_hashtags" id="activitypub_use_hashtags" value="1" <?php echo \checked( '1', \get_option( 'activitypub_use_hashtags', '1' ) ); ?> /> <?php \_e( 'Add hashtags in the content as native tags and replace the <code>#tag</code> with the tag-link.', 'activitypub' ); ?></label>
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="checkbox" name="activitypub_add_tags_as_hashtags" id="activitypub_add_tags_as_hashtags" value="1" <?php echo \checked( '1', \get_option( 'activitypub_add_tags_as_hashtags', '0' ) ); ?> /> <?php \_e( 'Add all tags as hashtags to the end of each activity.', 'activitypub' ); ?></label>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php \do_settings_fields( 'activitypub', 'activity' ); ?>
|
||||
|
||||
<h2><?php \esc_html_e( 'Server', 'activitypub' ); ?></h2>
|
||||
|
||||
<p><?php \esc_html_e( 'Server related settings.', 'activitypub' ); ?></p>
|
||||
|
||||
<?php
|
||||
// load the existing blacklist from the WordPress options table
|
||||
$activitypub_blacklist = \trim( \implode( PHP_EOL, \ActivityPub\get_blacklist() ), PHP_EOL );
|
||||
?>
|
||||
|
||||
<table class="form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php \esc_html_e( 'Blacklist', 'activitypub' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<textarea name="activitypub_blacklist" id="activitypub_blacklist" rows="10" cols="50" class="large-text"><?php echo $activitypub_blacklist; ?></textarea>
|
||||
<p class="description"><?php \_e( 'A list of hosts, you want to block, one host per line. Please use only the host/domain of the server you want to block, without <code>http://</code> and without <code>www.</code>. For example <code>example.com</code>.', 'activitypub' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php \do_settings_fields( 'activitypub', 'server' ); ?>
|
||||
|
||||
<?php \do_settings_sections( 'activitypub' ); ?>
|
||||
|
||||
<?php \submit_button(); ?>
|
||||
</form>
|
||||
|
||||
<p>
|
||||
<small><?php _e( 'If you like this plugin, what about a small <a href="https://notiz.blog/donate">donation</a>?', 'activitypub' ); ?></small>
|
||||
</p>
|
||||
</div>
|
||||
@@ -1,31 +0,0 @@
|
||||
.DS_Store
|
||||
.editorconfig
|
||||
.git
|
||||
.gitignore
|
||||
.travis.yml
|
||||
.codeclimate.yml
|
||||
.data
|
||||
Gruntfile.js
|
||||
LINGUAS
|
||||
Makefile
|
||||
README.md
|
||||
readme.md
|
||||
CODE_OF_CONDUCT.md
|
||||
LICENSE.md
|
||||
_site
|
||||
bin
|
||||
composer.json
|
||||
composer.lock
|
||||
docker-compose.yml
|
||||
gulpfile.js
|
||||
package.json
|
||||
node_modules
|
||||
npm-debug.log
|
||||
phpcs.xml
|
||||
package.json
|
||||
package-lock.json
|
||||
phpunit.xml
|
||||
phpunit.xml.dist
|
||||
tests
|
||||
node_modules
|
||||
vendor
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Matthias Pfefferle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,444 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: ActivityStream extension
|
||||
* Plugin URI: http://wordpress.org/plugins/activitystream-extension/
|
||||
* Description: An extensions which adds several ActivityStreams (<a href="http://www.activitystrea.ms">activitystrea.ms</a>) Feeds
|
||||
* Author: Matthias Pfefferle
|
||||
* Author URI: https://notiz.blog
|
||||
* Version: 1.3.3
|
||||
* License: MIT
|
||||
* License URI: https://opensource.org/licenses/MIT
|
||||
* Text Domain: activitystream-extension
|
||||
*/
|
||||
|
||||
add_action( 'init', array( 'ActivityStreamExtensionPlugin', 'init' ) );
|
||||
|
||||
register_activation_hook( __FILE__, array( 'ActivityStreamExtensionPlugin', 'flush_rewrite_rules' ) );
|
||||
register_deactivation_hook( __FILE__, array( 'ActivityStreamExtensionPlugin', 'flush_rewrite_rules' ) );
|
||||
|
||||
/**
|
||||
* ActivityStream Extension
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*/
|
||||
class ActivityStreamExtensionPlugin {
|
||||
|
||||
/**
|
||||
* Init function
|
||||
*/
|
||||
public static function init() {
|
||||
require_once dirname( __FILE__ ) . '/includes/functions.php';
|
||||
|
||||
add_filter( 'query_vars', array( 'ActivityStreamExtensionPlugin', 'query_vars' ) );
|
||||
add_filter( 'feed_content_type', array( 'ActivityStreamExtensionPlugin', 'feed_content_type' ), 10, 2 );
|
||||
|
||||
// add the as1 feed
|
||||
add_feed( 'as1', array( 'ActivityStreamExtensionPlugin', 'do_feed_as1' ) );
|
||||
add_action( 'do_feed_as1', array( 'ActivityStreamExtensionPlugin', 'do_feed_as1' ), 10, 1 );
|
||||
add_filter( 'as1_object_type', array( 'ActivityStreamExtensionPlugin', 'post_as1_object_type' ), 10, 2 );
|
||||
|
||||
// add the as2 feed
|
||||
add_feed( 'as2', array( 'ActivityStreamExtensionPlugin', 'do_feed_as2' ) );
|
||||
add_action( 'do_feed_as2', array( 'ActivityStreamExtensionPlugin', 'do_feed_as2' ), 10, 1 );
|
||||
add_filter( 'as2_object_type', array( 'ActivityStreamExtensionPlugin', 'post_as2_object_type' ), 10, 2 );
|
||||
|
||||
// push json feed
|
||||
add_filter( 'pshb_feed_urls', array( 'ActivityStreamExtensionPlugin', 'publish_to_hub' ) );
|
||||
|
||||
// extend core feeds with AS1
|
||||
add_action( 'atom_ns', array( 'ActivityStreamExtensionPlugin', 'add_atom_activity_namespace' ) );
|
||||
add_action( 'atom_entry', array( 'ActivityStreamExtensionPlugin', 'add_atom_activity_object' ) );
|
||||
add_action( 'atom_entry', array( 'ActivityStreamExtensionPlugin', 'add_atom_enclosure' ) );
|
||||
add_action( 'atom_author', array( 'ActivityStreamExtensionPlugin', 'add_atom_activity_author' ) ); // run before output
|
||||
add_action( 'comment_atom_ns', array( 'ActivityStreamExtensionPlugin', 'add_atom_activity_namespace' ) );
|
||||
add_action( 'comment_atom_entry', array( 'ActivityStreamExtensionPlugin', 'add_comment_atom_activity_object' ) );
|
||||
|
||||
// discovery
|
||||
add_action( 'wp_head', array( 'ActivityStreamExtensionPlugin', 'add_html_header' ), 5 );
|
||||
add_action( 'host_meta', array( 'ActivityStreamExtensionPlugin', 'add_host_meta_links' ) );
|
||||
add_action( 'webfinger_user_data', array( 'ActivityStreamExtensionPlugin', 'add_webfinger_links' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'callback' as a valid query variables.
|
||||
*
|
||||
* @param array $vars
|
||||
* @return array
|
||||
*/
|
||||
public static function query_vars( $vars ) {
|
||||
$vars[] = 'callback';
|
||||
$vars[] = 'feed';
|
||||
$vars[] = 'pretty';
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds "as1" content-type
|
||||
*
|
||||
* @param string $content_type the default content-type
|
||||
* @param string $type the feed-type
|
||||
* @return string the as1 content-type
|
||||
*/
|
||||
public static function feed_content_type( $content_type, $type ) {
|
||||
if ( 'as1' == $type ) {
|
||||
return 'application/stream+json';
|
||||
}
|
||||
|
||||
if ( 'as2' == $type ) {
|
||||
return 'application/activity+json';
|
||||
}
|
||||
|
||||
return $content_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset rewrite rules
|
||||
*/
|
||||
public static function flush_rewrite_rules() {
|
||||
global $wp_rewrite;
|
||||
$wp_rewrite->flush_rules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Echos autodiscovery links
|
||||
*/
|
||||
public static function add_html_header() {
|
||||
// check if theme author want to display feed links
|
||||
if ( ! current_theme_supports( 'automatic-feed-links' ) ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<link rel="alternate" type="<?php echo esc_attr( feed_content_type( 'as1' ) ); ?>" title="<?php echo esc_attr( sprintf( __( '%1$s %2$s Activity-Streams Feed', 'activitystream_extension' ), get_bloginfo( 'name' ), __( '»', 'activitystream_extension' ) ) ); ?>" href="<?php echo esc_url( get_feed_link( 'as1' ) ); ?>" />
|
||||
<link rel="alternate" type="<?php echo esc_attr( feed_content_type( 'as1' ) ); ?>" title="<?php echo esc_attr( sprintf( __( '%1$s %2$s Activity-Streams Comments Feed ', 'activitystream_extension' ), get_bloginfo( 'name' ), __( '»', 'activitystream_extension' ) ) ); ?>" href="<?php echo esc_url( get_feed_link( 'comments_as1' ) ); ?>" />
|
||||
<?php
|
||||
if ( is_singular() ) {
|
||||
$id = 0;
|
||||
$post = get_post( $id );
|
||||
|
||||
if ( comments_open() || pings_open() || $post->comment_count > 0 ) {
|
||||
?>
|
||||
<link rel="alternate" type="<?php echo esc_attr( feed_content_type( 'as1' ) ); ?>" title="<?php echo esc_attr( sprintf( __( '%1$s %2$s %3$s Activity-Streams Comments Feed', 'activitystream_extension' ), get_bloginfo( 'name' ), __( '»', 'activitystream_extension' ), esc_html( get_the_title() ) ) ); ?>" href="<?php echo esc_url( get_post_comments_feed_link( null, 'as1' ) ); ?>" />
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add AS links to the host-meta file
|
||||
*
|
||||
* @param array $jrd the host-meta JRD array
|
||||
*
|
||||
* @return array the filtered array
|
||||
*/
|
||||
public static function add_host_meta_links( $jrd ) {
|
||||
$jrd['links'][] = array(
|
||||
'rel' => 'feed',
|
||||
'type' => esc_attr( feed_content_type( 'as1' ) ),
|
||||
'title' => esc_attr( __( 'Activity-Streams 1.0 Feed', 'activitystream_extension' ) ),
|
||||
'href' => esc_url( get_feed_link( 'as1' ) )
|
||||
);
|
||||
|
||||
$jrd['links'][] = array(
|
||||
'rel' => 'feed',
|
||||
'type' => esc_attr( feed_content_type( 'as1' ) ),
|
||||
'title' => esc_attr( __( 'Activity-Streams 1.0 Comments Feed ', 'activitystream_extension' ) ),
|
||||
'href' => esc_url( get_feed_link( 'comments_as1' ) )
|
||||
);
|
||||
|
||||
$jrd['links'][] = array(
|
||||
'rel' => 'feed',
|
||||
'type' => esc_attr( feed_content_type( 'as2' ) ),
|
||||
'title' => esc_attr( __( 'Activity-Streams 2.0 Feed', 'activitystream_extension' ) ),
|
||||
'href' => esc_url( get_feed_link( 'as2' ) )
|
||||
);
|
||||
|
||||
$jrd['links'][] = array(
|
||||
'rel' => 'feed',
|
||||
'type' => esc_attr( feed_content_type( 'as2' ) ),
|
||||
'title' => esc_attr( __( 'Activity-Streams 2.0 Comments Feed ', 'activitystream_extension' ) ),
|
||||
'href' => esc_url( get_feed_link( 'comments_as2' ) )
|
||||
);
|
||||
|
||||
return $jrd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add AS links to the webfinger file
|
||||
*
|
||||
* @param array $jrd the WebFinger JRD array
|
||||
*
|
||||
* @return array the filtered array
|
||||
*/
|
||||
public static function add_webfinger_links( $jrd, $acct, $user ) {
|
||||
$jrd['links'][] = array(
|
||||
'rel' => 'feed',
|
||||
'type' => esc_attr( feed_content_type( 'as1' ) ),
|
||||
'title' => esc_attr( __( 'Activity-Streams 1.0 Feed', 'activitystream_extension' ) ),
|
||||
'href' => esc_url( get_author_feed_link( $user->ID, 'as1' ) )
|
||||
);
|
||||
|
||||
$jrd['links'][] = array(
|
||||
'rel' => 'feed',
|
||||
'type' => esc_attr( feed_content_type( 'as2' ) ),
|
||||
'title' => esc_attr( __( 'Activity-Streams 2.0 Feed', 'activitystream_extension' ) ),
|
||||
'href' => esc_url( get_author_feed_link( $user->ID, 'as2' ) )
|
||||
);
|
||||
|
||||
return $jrd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Echos the activitystream namespace
|
||||
*/
|
||||
public static function add_atom_activity_namespace() {
|
||||
echo 'xmlns:activity="http://activitystrea.ms/spec/1.0/"'."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Echos the activity verb and object for the wordpress entries
|
||||
*/
|
||||
public static function add_atom_activity_object() {
|
||||
/*
|
||||
* The object type of the current post in the Activity Streams 1 feed
|
||||
*
|
||||
* @param Object $comment_post The current post
|
||||
*/
|
||||
$object_type = apply_filters( 'as1_object_type', 'article', get_post() );
|
||||
?>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/<?php echo esc_attr( $object_type ); ?></activity:object-type>
|
||||
<id><?php the_guid(); ?></id>
|
||||
<title type="<?php html_type_rss(); ?>"><![CDATA[<?php the_title(); ?>]]></title>
|
||||
<summary type="<?php html_type_rss(); ?>"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary>
|
||||
<link rel="alternate" type="text/html" href="<?php the_permalink_rss(); ?>" />
|
||||
<?php
|
||||
$images = activitystream_extension_get_post_images( get_the_ID() );
|
||||
|
||||
if ( $images ) {
|
||||
foreach ( $images as $image ) {
|
||||
?>
|
||||
<link rel="enclosure" type="<?php echo $image['type']; ?>" href="<?php echo $image['url']; ?>" />
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</activity:object>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Echos the activity verb and object for the wordpress entries
|
||||
*/
|
||||
public static function add_atom_enclosure() {
|
||||
$images = activitystream_extension_get_post_images( get_the_ID() );
|
||||
|
||||
if ( ! $images ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $images as $image ) {
|
||||
?>
|
||||
<link rel="enclosure" type="<?php echo $image['type']; ?>" href="<?php echo $image['url']; ?>" />
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Echos the activity verb and object for the wordpress comments
|
||||
*/
|
||||
public static function add_comment_atom_activity_object() {
|
||||
?>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id><?php comment_guid(); ?></id>
|
||||
<content type="html" xml:base="<?php comment_link(); ?>"><![CDATA[<?php comment_text(); ?>]]></content>
|
||||
<link rel="alternate" href="<?php comment_link(); ?>" type="<?php bloginfo_rss( 'html_type' ); ?>" />
|
||||
<thr:in-reply-to ref="<?php the_guid() ?>" href="<?php the_permalink_rss() ?>" type="<?php bloginfo_rss( 'html_type' ); ?>" />
|
||||
</activity:object>
|
||||
<activity:target>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/article</activity:object-type>
|
||||
<id><?php the_guid(); ?></id>
|
||||
<title type="<?php html_type_rss(); ?>"><![CDATA[<?php the_title(); ?>]]></title>
|
||||
<summary type="<?php html_type_rss(); ?>"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary>
|
||||
<link rel="alternate" type="text/html" href="<?php the_permalink_rss() ?>" />
|
||||
</activity:target>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Add author informations to the Atom feed
|
||||
*/
|
||||
public static function add_atom_activity_author() {
|
||||
?>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an as1 json feed
|
||||
*/
|
||||
public static function do_feed_as1( $for_comments ) {
|
||||
if ( $for_comments ) {
|
||||
// load comment template
|
||||
load_template( dirname( __FILE__ ) . '/templates/feed-as1-comments.php' );
|
||||
} else {
|
||||
// load post template
|
||||
load_template( dirname( __FILE__ ) . '/templates/feed-as1.php' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an as2 json feed
|
||||
*/
|
||||
public static function do_feed_as2( $for_comments ) {
|
||||
if ( $for_comments ) {
|
||||
// load comment template
|
||||
load_template( dirname( __FILE__ ) . '/templates/feed-as2-comments.php' );
|
||||
} else {
|
||||
// load post template
|
||||
load_template( dirname( __FILE__ ) . '/templates/feed-as2.php' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the json feed to PubsubHubBub
|
||||
*
|
||||
* @param array $feeds
|
||||
* @return array
|
||||
*/
|
||||
public static function publish_to_hub( $feeds ) {
|
||||
$feeds[] = get_feed_link( 'as1' );
|
||||
$feeds[] = get_feed_link( 'as2' );
|
||||
|
||||
return $feeds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the as1 object for a given post
|
||||
*
|
||||
* @param string $type the object type
|
||||
* @param Object $post the post object
|
||||
* @return string the object type
|
||||
*/
|
||||
public static function post_as1_object_type( $type, $post ) {
|
||||
$post_type = get_post_type( $post );
|
||||
|
||||
switch ( $post_type ) {
|
||||
case 'post':
|
||||
$post_format = get_post_format( $post );
|
||||
|
||||
switch ( $post_format ) {
|
||||
case 'aside':
|
||||
case 'status':
|
||||
case 'quote':
|
||||
case 'note':
|
||||
$object_type = 'note';
|
||||
break;
|
||||
case 'gallery':
|
||||
case 'image':
|
||||
$object_type = 'image';
|
||||
break;
|
||||
case 'video':
|
||||
$object_type = 'video';
|
||||
break;
|
||||
case 'audio':
|
||||
$object_type = 'audio';
|
||||
break;
|
||||
default:
|
||||
$object_type = 'article';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'page':
|
||||
$object_type = 'page';
|
||||
break;
|
||||
case 'attachment':
|
||||
$mime_type = get_post_mime_type();
|
||||
$media_type = preg_replace( '/(\/[a-zA-Z]+)/i', '', $mime_type );
|
||||
|
||||
switch ( $media_type ) {
|
||||
case 'audio':
|
||||
$object_type = 'audio';
|
||||
break;
|
||||
case 'video':
|
||||
$object_type = 'video';
|
||||
break;
|
||||
case 'image':
|
||||
$object_type = 'image';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$object_type = 'article';
|
||||
break;
|
||||
}
|
||||
|
||||
return $object_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the as2 object for a given post
|
||||
*
|
||||
* @param string $type the object type
|
||||
* @param Object $post the post object
|
||||
* @return string the object type
|
||||
*/
|
||||
public static function post_as2_object_type( $type, $post ) {
|
||||
$post_type = get_post_type( $post );
|
||||
|
||||
switch ( $post_type ) {
|
||||
case 'post':
|
||||
$post_format = get_post_format( $post );
|
||||
|
||||
switch ( $post_format ) {
|
||||
case 'aside':
|
||||
case 'status':
|
||||
case 'quote':
|
||||
case 'note':
|
||||
$object_type = 'Note';
|
||||
break;
|
||||
case 'gallery':
|
||||
case 'image':
|
||||
$object_type = 'Image';
|
||||
break;
|
||||
case 'video':
|
||||
$object_type = 'Video';
|
||||
break;
|
||||
case 'audio':
|
||||
$object_type = 'Audio';
|
||||
break;
|
||||
default:
|
||||
$object_type = 'Article';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'page':
|
||||
$object_type = 'Page';
|
||||
break;
|
||||
case 'attachment':
|
||||
$mime_type = get_post_mime_type();
|
||||
$media_type = preg_replace( '/(\/[a-zA-Z]+)/i', '', $mime_type );
|
||||
|
||||
switch ( $media_type ) {
|
||||
case 'audio':
|
||||
$object_type = 'Audio';
|
||||
break;
|
||||
case 'video':
|
||||
$object_type = 'Video';
|
||||
break;
|
||||
case 'image':
|
||||
$object_type = 'Image';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$object_type = 'Article';
|
||||
break;
|
||||
}
|
||||
|
||||
return $object_type;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Display the post content. Optinally allows post ID to be passed
|
||||
* @uses the_content()
|
||||
*
|
||||
* @param int $id Optional. Post ID.
|
||||
* @param string $more_link_text Optional. Content for when there is more text.
|
||||
* @param bool $stripteaser Optional. Strip teaser content before the more text. Default is false.
|
||||
*/
|
||||
function get_the_content_by_id( $post_id = 0, $more_link_text = null, $stripteaser = false ) {
|
||||
global $post;
|
||||
$post = get_post( $post_id );
|
||||
setup_postdata( $post, $more_link_text, $stripteaser );
|
||||
$content = get_the_content();
|
||||
wp_reset_postdata( $post );
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default image property, using the post-thumbnail and any attached images.
|
||||
*
|
||||
* @see https://github.com/willnorris/wordpress-opengraph/blob/master/opengraph.php#L188
|
||||
*/
|
||||
function activitystream_extension_get_post_images( $id ) {
|
||||
$max_images = apply_filters( 'activitystram_extension_max_images', 3 );
|
||||
|
||||
$images = array();
|
||||
|
||||
// max images can't be negative or zero
|
||||
if ( $max_images <= 0 ) {
|
||||
$max_images = 1;
|
||||
}
|
||||
|
||||
$image_ids = array();
|
||||
// list post thumbnail first if this post has one
|
||||
if ( function_exists( 'has_post_thumbnail' ) && has_post_thumbnail( $id ) ) {
|
||||
$image_ids[] = get_post_thumbnail_id( $id );
|
||||
$max_images--;
|
||||
}
|
||||
// then list any image attachments
|
||||
$query = new WP_Query(
|
||||
array(
|
||||
'post_parent' => $id,
|
||||
'post_status' => 'inherit',
|
||||
'post_type' => 'attachment',
|
||||
'post_mime_type' => 'image',
|
||||
'order' => 'ASC',
|
||||
'orderby' => 'menu_order ID',
|
||||
'posts_per_page' => $max_images,
|
||||
)
|
||||
);
|
||||
foreach ( $query->get_posts() as $attachment ) {
|
||||
if ( ! in_array( $attachment->ID, $image_ids ) ) {
|
||||
$image_ids[] = $attachment->ID;
|
||||
}
|
||||
}
|
||||
// get URLs for each image
|
||||
foreach ( $image_ids as $id ) {
|
||||
$thumbnail = wp_get_attachment_image_src( $id, 'medium' );
|
||||
$mimetype = get_post_mime_type( $id );
|
||||
|
||||
if ( $thumbnail ) {
|
||||
$images[] = array(
|
||||
'url' => $thumbnail[0],
|
||||
'type' => $mimetype
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
# Copyright (C) 2018 Matthias Pfefferle
|
||||
# This file is distributed under the MIT.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: ActivityStream extension 1.2.3\n"
|
||||
"Report-Msgid-Bugs-To: "
|
||||
"https://wordpress.org/support/plugin/activitystream-extension\n"
|
||||
"POT-Creation-Date: 2018-02-10 20:53:38+00:00\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"X-Generator: grunt-wp-i18n 0.5.4\n"
|
||||
|
||||
#: activitystream-extension.php:109
|
||||
msgid "%1$s %2$s Activity-Streams Feed"
|
||||
msgstr ""
|
||||
|
||||
#: activitystream-extension.php:109 activitystream-extension.php:110
|
||||
#: activitystream-extension.php:118
|
||||
msgid "»"
|
||||
msgstr ""
|
||||
|
||||
#: activitystream-extension.php:110
|
||||
msgid "%1$s %2$s Activity-Streams Comments Feed "
|
||||
msgstr ""
|
||||
|
||||
#: activitystream-extension.php:118
|
||||
msgid "%1$s %2$s %3$s Activity-Streams Comments Feed"
|
||||
msgstr ""
|
||||
|
||||
#: activitystream-extension.php:135 activitystream-extension.php:174
|
||||
msgid "Activity-Streams 1.0 Feed"
|
||||
msgstr ""
|
||||
|
||||
#: activitystream-extension.php:142
|
||||
msgid "Activity-Streams 1.0 Comments Feed "
|
||||
msgstr ""
|
||||
|
||||
#: activitystream-extension.php:149 activitystream-extension.php:181
|
||||
msgid "Activity-Streams 2.0 Feed"
|
||||
msgstr ""
|
||||
|
||||
#: activitystream-extension.php:156
|
||||
msgid "Activity-Streams 2.0 Comments Feed "
|
||||
msgstr ""
|
||||
|
||||
#: templates/feed-as2-comments.php:12 templates/feed-as2-comments.php:15
|
||||
msgid "\"%1$s\" - comments"
|
||||
msgstr ""
|
||||
|
||||
#: templates/feed-as2-comments.php:78
|
||||
msgid "%1$s posted a comment"
|
||||
msgstr ""
|
||||
|
||||
#: templates/feed-as2.php:11
|
||||
msgid "%1$s - posts"
|
||||
msgstr ""
|
||||
|
||||
#: templates/feed-as2.php:63
|
||||
msgid "%1$s created a new post"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "ActivityStream extension"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin/theme
|
||||
msgid "http://wordpress.org/plugins/activitystream-extension/"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid ""
|
||||
"An extensions which adds several ActivityStreams (<a "
|
||||
"href=\"http://www.activitystrea.ms\">activitystrea.ms</a>) Feeds"
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "Matthias Pfefferle"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "https://notiz.blog"
|
||||
msgstr ""
|
||||
@@ -1,105 +0,0 @@
|
||||
=== ActivityStream extension ===
|
||||
Contributors: pfefferle
|
||||
Donate link: https://notiz.blog/donate/
|
||||
Tags: ActivityStreams, Activity Stream, feed, RSS, Atom, JSON, JSON-LD
|
||||
Requires at least: 4.2
|
||||
Tested up to: 5.2.2
|
||||
Stable tag: 1.3.3
|
||||
|
||||
ActivityStrea.ms feeds for WordPress (Atom and JSON(-LD))
|
||||
|
||||
== Description ==
|
||||
|
||||
ActivityStreams ([activitystrea.ms](http://www.activitystrea.ms)) support for your WordPress-blog
|
||||
|
||||
ActivityStreams is an open format specification for activity stream protocols, which are used to syndicate activities taken in social web applications and services, similar to those in Facebook's Newsfeed, FriendFeed, the Movable Type Action Streams plugin, etc.
|
||||
|
||||
== Installation ==
|
||||
|
||||
* Upload the whole folder to your `wp-content/plugins` folder
|
||||
* Activate it at the admin interface
|
||||
|
||||
Thats it
|
||||
|
||||
== Changelog ==
|
||||
|
||||
Project maintined on github at
|
||||
[pfefferle/wordpress-activitystream-extension](https://github.com/pfefferle/wordpress-activitystream-extension/).
|
||||
|
||||
= 1.3.3 =
|
||||
|
||||
* update dependencies
|
||||
|
||||
= 1.3.2 =
|
||||
|
||||
* added missing enclosure mime-type
|
||||
|
||||
= 1.3.1 =
|
||||
|
||||
* replaced json_encode with wp_json_encode
|
||||
* added enclosures to Atom `<activity:object>`
|
||||
|
||||
= 1.3.0 =
|
||||
|
||||
* Added enclosure support
|
||||
* Fixed summary js-summary
|
||||
|
||||
= 1.2.3 =
|
||||
|
||||
* added WebFinger and host-meta discovery
|
||||
|
||||
= 1.2.2 =
|
||||
|
||||
* updated requirement
|
||||
* fixed licenses
|
||||
|
||||
= 1.2.1 =
|
||||
|
||||
* removed charset
|
||||
|
||||
= 1.2.0 =
|
||||
|
||||
* updated to latest spec: <http://www.w3.org/TR/2016/WD-activitystreams-core-20160712/>
|
||||
* fixed comment feed
|
||||
|
||||
= 1.1.0 =
|
||||
|
||||
* initial AS2 feed (beta)
|
||||
* WordPress coding standard
|
||||
|
||||
= 1.0.0 =
|
||||
|
||||
* changes based on the 7B plugin <https://github.com/pento/7B>
|
||||
* json-feed for comments
|
||||
* cleanup
|
||||
|
||||
= 0.8 =
|
||||
|
||||
* some JSON changes to match spec 1.0
|
||||
* changed the HTML discovery-links
|
||||
* added post_thumbnail support
|
||||
|
||||
= 0.7.1 =
|
||||
|
||||
* updated to new JSON-Activity changes
|
||||
|
||||
= 0.7 =
|
||||
|
||||
* deprecated `<activity:subject>`
|
||||
* enriched Atom `<author />`
|
||||
|
||||
= 0.6 =
|
||||
|
||||
* added json feed
|
||||
* pubsubhubbub for json
|
||||
|
||||
= 0.5 =
|
||||
|
||||
* some OStatus compatibility fixes
|
||||
* added `<activity:subject>`
|
||||
* added `<activity:target>`
|
||||
|
||||
= 0.3 =
|
||||
|
||||
* Fixed a namespace bug
|
||||
* Added autodiscovery link
|
||||
@@ -1,143 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Activity Streams 1 Feed Template for displaying AS1 Comments feed.
|
||||
*
|
||||
* @link https://github.com/pento/7B a lot of changes made by @pento
|
||||
*/
|
||||
|
||||
$json = new stdClass();
|
||||
|
||||
$json->items = array();
|
||||
|
||||
header( 'Content-Type: ' . feed_content_type( 'as1' ), true );
|
||||
|
||||
/*
|
||||
* The JSONP callback function to add to the JSON feed
|
||||
*
|
||||
* @param string $callback The JSONP callback function name
|
||||
*/
|
||||
$callback = apply_filters( 'as1_feed_callback', get_query_var( 'callback' ) );
|
||||
|
||||
if ( ! empty( $callback ) && ! apply_filters( 'json_jsonp_enabled', true ) ) {
|
||||
status_header( 400 );
|
||||
echo wp_json_encode( array(
|
||||
'code' => 'json_callback_disabled',
|
||||
'message' => 'JSONP support is disabled on this site.',
|
||||
) );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( preg_match( '/\W/', $callback ) ) {
|
||||
status_header( 400 );
|
||||
echo wp_json_encode( array(
|
||||
'code' => 'json_callback_invalid',
|
||||
'message' => 'The JSONP callback function is invalid.',
|
||||
) );
|
||||
exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the AS1 feed being created and sent to the client
|
||||
*/
|
||||
do_action( 'comments_as1_feed_pre' );
|
||||
|
||||
while ( have_comments() ) {
|
||||
the_comment();
|
||||
|
||||
$comment_post = $GLOBALS['post'] = get_post( $comment->comment_post_ID );
|
||||
|
||||
/*
|
||||
* The object type of the current post in the Activity Streams 1 feed
|
||||
*
|
||||
* @param Object $comment_post The current post
|
||||
*/
|
||||
$object_type = apply_filters( 'as1_object_type', 'article', $comment_post );
|
||||
|
||||
/*
|
||||
* The object type of the current comment in the Activity Streams 1 feed
|
||||
*
|
||||
* @param Object $comment The current comment
|
||||
*/
|
||||
$comment_object_type = apply_filters( 'comments_as1_object_type', 'comment', $comment );
|
||||
|
||||
$item = array(
|
||||
'published' => get_comment_time( 'Y-m-d\TH:i:s\Z', true ),
|
||||
'generator' => (object) array(
|
||||
'url' => 'http://wordpress.org/?v=' . get_bloginfo_rss( 'version' ),
|
||||
),
|
||||
'provider' => (object) array(
|
||||
'url' => get_post_comments_feed_link( $comment_post->ID, 'as1' ),
|
||||
),
|
||||
'verb' => 'post',
|
||||
'target' => (object) array(
|
||||
'id' => get_the_guid( $comment_post->ID ),
|
||||
'displayName' => get_the_title( $comment_post->ID ),
|
||||
'objectType' => $object_type,
|
||||
'summary' => get_the_excerpt( $comment_post->ID ),
|
||||
'url' => get_permalink( $comment_post->ID ),
|
||||
),
|
||||
'object' => (object) array(
|
||||
'id' => get_comment_guid(),
|
||||
'objectType' => $comment_object_type,
|
||||
'content' => get_comment_text(),
|
||||
'url' => get_comment_link(),
|
||||
),
|
||||
'actor' => (object) array(
|
||||
'displayName' => get_comment_author(),
|
||||
'objectType' => 'person',
|
||||
'url' => get_comment_author_url(),
|
||||
'image' => (object) array(
|
||||
'width' => 96,
|
||||
'height' => 96,
|
||||
'url' => get_avatar_url( get_the_author_meta( 'email' ), array( 'size' => 96 ) ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if ( get_comment_author_url() ) {
|
||||
$item['actor']->url = get_comment_author_url();
|
||||
}
|
||||
|
||||
/*
|
||||
* The item to be added to the Activity Streams 1 feed
|
||||
*
|
||||
* @param object $item The Activity Streams 1 item
|
||||
*/
|
||||
$item = apply_filters( 'comments_as1_feed_item', $item );
|
||||
|
||||
$json->items[] = $item;
|
||||
}
|
||||
|
||||
/*
|
||||
* The array of data to be sent to the user as JSON
|
||||
*
|
||||
* @param object $json The JSON data object
|
||||
*/
|
||||
$json = apply_filters( 'comments_as1_feed', $json );
|
||||
|
||||
|
||||
$options = 0;
|
||||
// JSON_PRETTY_PRINT added in PHP 5.4
|
||||
if ( get_query_var( 'pretty' ) ) {
|
||||
$options |= JSON_PRETTY_PRINT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Options to be passed to wp_json_encode()
|
||||
*
|
||||
* @param int $options The current options flags
|
||||
*/
|
||||
$options = apply_filters( 'as1_feed_options', $options );
|
||||
|
||||
$json_str = wp_json_encode( $json, $options );
|
||||
|
||||
if ( ! empty( $callback ) ) {
|
||||
echo esc_html( $callback ) . "($json_str);";
|
||||
} else {
|
||||
echo $json_str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd after the AS1 feed has been created and sent to the client
|
||||
*/
|
||||
do_action( 'comments_as1_feed_post' );
|
||||
@@ -1,132 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Activity Streams 1 Feed Template for displaying AS1 Posts feed.
|
||||
*
|
||||
* @link https://github.com/pento/7B a lot of changes made by @pento
|
||||
*/
|
||||
|
||||
$json = new stdClass();
|
||||
|
||||
$json->items = array();
|
||||
|
||||
header( 'Content-Type: ' . feed_content_type( 'as1' ), true );
|
||||
|
||||
/*
|
||||
* The JSONP callback function to add to the JSON feed
|
||||
*
|
||||
* @param string $callback The JSONP callback function name
|
||||
*/
|
||||
$callback = apply_filters( 'as1_feed_callback', get_query_var( 'callback' ) );
|
||||
|
||||
if ( ! empty( $callback ) && ! apply_filters( 'json_jsonp_enabled', true ) ) {
|
||||
status_header( 400 );
|
||||
echo wp_json_encode( array(
|
||||
'code' => 'json_callback_disabled',
|
||||
'message' => 'JSONP support is disabled on this site.',
|
||||
) );
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( preg_match( '/\W/', $callback ) ) {
|
||||
status_header( 400 );
|
||||
echo wp_json_encode( array(
|
||||
'code' => 'json_callback_invalid',
|
||||
'message' => 'The JSONP callback function is invalid.',
|
||||
) );
|
||||
exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the AS1 feed being created and sent to the client
|
||||
*/
|
||||
do_action( 'as1_feed_pre' );
|
||||
|
||||
while ( have_posts() ) {
|
||||
the_post();
|
||||
|
||||
/*
|
||||
* The object type of the current post in the Activity Streams 1 feed
|
||||
*
|
||||
* @param Object get_post() The current post
|
||||
*/
|
||||
$object_type = apply_filters( 'as1_object_type', 'article', get_post() );
|
||||
|
||||
$item = array(
|
||||
'published' => get_post_modified_time( 'Y-m-d\TH:i:s\Z', true ),
|
||||
'generator' => (object) array(
|
||||
'url' => 'http://wordpress.org/?v=' . get_bloginfo_rss( 'version' ),
|
||||
),
|
||||
'provider' => (object) array(
|
||||
'url' => get_feed_link( 'as1' ),
|
||||
),
|
||||
'verb' => 'post',
|
||||
'target' => (object) array(
|
||||
'id' => get_bloginfo( 'url' ),
|
||||
'url' => get_bloginfo( 'url' ),
|
||||
'objectType' => 'blog',
|
||||
'displayName' => get_bloginfo( 'name' ),
|
||||
),
|
||||
'object' => (object) array(
|
||||
'id' => get_the_guid(),
|
||||
'displayName' => get_the_title(),
|
||||
'objectType' => $object_type,
|
||||
'summary' => get_the_excerpt(),
|
||||
'url' => get_permalink(),
|
||||
'content' => get_the_content(),
|
||||
),
|
||||
'actor' => (object) array(
|
||||
'id' => get_author_posts_url( get_the_author_meta( 'ID' ), get_the_author_meta( 'nicename' ) ),
|
||||
'displayName' => get_the_author(),
|
||||
'objectType' => 'person',
|
||||
'url' => get_author_posts_url( get_the_author_meta( 'ID' ), get_the_author_meta( 'nicename' ) ),
|
||||
'image' => (object) array(
|
||||
'width' => 96,
|
||||
'height' => 96,
|
||||
'url' => get_avatar_url( get_the_author_meta( 'email' ), array( 'size' => 96 ) ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
/*
|
||||
* The item to be added to the Activity Streams 1 feed
|
||||
*
|
||||
* @param object $item The Activity Streams 1 item
|
||||
*/
|
||||
$item = apply_filters( 'as1_feed_item', $item );
|
||||
|
||||
$json->items[] = $item;
|
||||
}
|
||||
|
||||
/*
|
||||
* The array of data to be sent to the user as JSON
|
||||
*
|
||||
* @param object $json The JSON data object
|
||||
*/
|
||||
$json = apply_filters( 'as1_feed', $json );
|
||||
|
||||
$options = 0;
|
||||
// JSON_PRETTY_PRINT added in PHP 5.4
|
||||
if ( get_query_var( 'pretty' ) ) {
|
||||
$options |= JSON_PRETTY_PRINT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Options to be passed to wp_json_encode()
|
||||
*
|
||||
* @param int $options The current options flags
|
||||
*/
|
||||
$options = apply_filters( 'as1_feed_options', $options );
|
||||
|
||||
$json_str = wp_json_encode( $json, $options );
|
||||
|
||||
if ( ! empty( $callback ) ) {
|
||||
echo esc_html( $callback ) . "($json_str);";
|
||||
} else {
|
||||
echo $json_str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd after the AS1 feed has been created and sent to the client
|
||||
*/
|
||||
do_action( 'as1_feed_post' );
|
||||
@@ -1,152 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Activity Streams 2 Feed Template for displaying AS2 Comments feed.
|
||||
*/
|
||||
|
||||
$json = new stdClass();
|
||||
|
||||
$json->{'@context'} = 'http://www.w3.org/ns/activitystreams';
|
||||
$json->type = 'Collection';
|
||||
if ( is_singular() ) {
|
||||
$json->id = get_post_comments_feed_link( get_the_ID(), 'as2' );
|
||||
$json->name = esc_attr( sprintf( __( '"%1$s" - comments', 'activitystream_extension' ), get_the_title() ) );
|
||||
} else {
|
||||
$json->id = get_feed_link( 'comments_as2' );
|
||||
$json->name = esc_attr( sprintf( __( '"%1$s" - comments', 'activitystream_extension' ), get_bloginfo( 'name' ) ) );
|
||||
}
|
||||
|
||||
$json->totalItems = (int) get_option( 'posts_per_rss' );
|
||||
|
||||
$json->items = array();
|
||||
|
||||
header( 'Content-Type: ' . feed_content_type( 'as2' ), true );
|
||||
|
||||
/*
|
||||
* The JSONP callback function to add to the JSON feed
|
||||
*
|
||||
* @param string $callback The JSONP callback function name
|
||||
*/
|
||||
$callback = apply_filters( 'as2_feed_callback', get_query_var( 'callback' ) );
|
||||
|
||||
if ( ! empty( $callback ) && ! apply_filters( 'json_jsonp_enabled', true ) ) {
|
||||
status_header( 400 );
|
||||
echo wp_json_encode( array(
|
||||
'code' => 'json_callback_disabled',
|
||||
'message' => 'JSONP support is disabled on this site.',
|
||||
) );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( preg_match( '/\W/', $callback ) ) {
|
||||
status_header( 400 );
|
||||
echo wp_json_encode( array(
|
||||
'code' => 'json_callback_invalid',
|
||||
'message' => 'The JSONP callback function is invalid.',
|
||||
) );
|
||||
exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the AS1 feed being created and sent to the client
|
||||
*/
|
||||
do_action( 'comments_as2_feed_pre' );
|
||||
|
||||
while ( have_comments() ) {
|
||||
the_comment();
|
||||
|
||||
$comment_post = $GLOBALS['post'] = get_post( $comment->comment_post_ID );
|
||||
|
||||
/*
|
||||
* The object type of the current post in the Activity Streams 1 feed
|
||||
*
|
||||
* @param Object $comment_post The current post
|
||||
*/
|
||||
$object_type = apply_filters( 'as2_object_type', 'article', $comment_post );
|
||||
|
||||
/*
|
||||
* The object type of the current comment in the Activity Streams 1 feed
|
||||
*
|
||||
* @param Object $comment The current comment
|
||||
*/
|
||||
$comment_object_type = apply_filters( 'comments_as2_object_type', 'comment', $comment );
|
||||
|
||||
$item = array(
|
||||
'published' => get_comment_time( 'Y-m-d\TH:i:s\Z', true ),
|
||||
'generator' => 'http://wordpress.org/?v=' . get_bloginfo_rss( 'version' ),
|
||||
'id' => get_post_comments_feed_link( get_the_ID(), 'as2' ),
|
||||
'type' => 'Create',
|
||||
'name' => esc_attr( sprintf( __( '%1$s posted a comment', 'activitystream_extension' ), get_comment_author() ) ),
|
||||
'inReplyTo' => (object) array(
|
||||
'id' => get_the_guid( $comment_post->ID ),
|
||||
'type' => $object_type,
|
||||
'name' => get_the_title( $comment_post->ID ),
|
||||
'summary' => get_the_excerpt( $comment_post->ID ),
|
||||
'url' => get_permalink( $comment_post->ID ),
|
||||
),
|
||||
'object' => (object) array(
|
||||
'id' => get_comment_guid(),
|
||||
'type' => 'Note',
|
||||
'name' => get_comment_text(),
|
||||
'content' => get_comment_text(),
|
||||
'url' => get_comment_link(),
|
||||
),
|
||||
'actor' => (object) array(
|
||||
'name' => get_comment_author(),
|
||||
'type' => 'Person',
|
||||
'image' => (object) array(
|
||||
'type' => 'Link',
|
||||
'width' => 96,
|
||||
'height' => 96,
|
||||
'href' => get_avatar_url( get_the_author_meta( 'email' ), array( 'size' => 96 ) ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// check if comment author provided his URL
|
||||
if ( get_comment_author_url() ) {
|
||||
$item['actor']->url = get_comment_author_url();
|
||||
$item['actor']->id = get_comment_author_url();
|
||||
}
|
||||
|
||||
/*
|
||||
* The item to be added to the Activity Streams 1 feed
|
||||
*
|
||||
* @param object $item The Activity Streams 1 item
|
||||
*/
|
||||
$item = apply_filters( 'comments_as2_feed_item', $item );
|
||||
|
||||
$json->items[] = $item;
|
||||
}
|
||||
|
||||
/*
|
||||
* The array of data to be sent to the user as JSON
|
||||
*
|
||||
* @param object $json The JSON data object
|
||||
*/
|
||||
$json = apply_filters( 'comments_as2_feed', $json );
|
||||
|
||||
$options = 0;
|
||||
// JSON_PRETTY_PRINT added in PHP 5.4
|
||||
if ( get_query_var( 'pretty' ) ) {
|
||||
$options |= JSON_PRETTY_PRINT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Options to be passed to wp_json_encode()
|
||||
*
|
||||
* @param int $options The current options flags
|
||||
*/
|
||||
$options = apply_filters( 'as2_feed_options', $options );
|
||||
|
||||
$json_str = wp_json_encode( $json, $options );
|
||||
|
||||
if ( ! empty( $callback ) ) {
|
||||
echo esc_html( $callback ) . "($json_str);";
|
||||
} else {
|
||||
echo $json_str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd after the AS1 feed has been created and sent to the client
|
||||
*/
|
||||
do_action( 'comments_as2_feed_post' );
|
||||
@@ -1,153 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Activity Streams 2 Feed Template for displaying AS2 Posts feed.
|
||||
*/
|
||||
|
||||
$json = new stdClass();
|
||||
|
||||
$json->{'@context'} = 'http://www.w3.org/ns/activitystreams';
|
||||
$json->id = get_feed_link( 'as2' );
|
||||
$json->type = 'Collection';
|
||||
$json->name = esc_attr( sprintf( __( '%1$s - posts', 'activitystream_extension' ), get_bloginfo( 'name' ) ) );
|
||||
$json->totalItems = (int) get_option( 'posts_per_rss' );
|
||||
|
||||
$json->items = array();
|
||||
|
||||
header( 'Content-Type: ' . feed_content_type( 'as2' ), true );
|
||||
|
||||
/*
|
||||
* The JSONP callback function to add to the JSON feed
|
||||
*
|
||||
* @param string $callback The JSONP callback function name
|
||||
*/
|
||||
$callback = apply_filters( 'as2_feed_callback', get_query_var( 'callback' ) );
|
||||
|
||||
if ( ! empty( $callback ) && ! apply_filters( 'json_jsonp_enabled', true ) ) {
|
||||
status_header( 400 );
|
||||
echo wp_json_encode( array(
|
||||
'code' => 'json_callback_disabled',
|
||||
'message' => 'JSONP support is disabled on this site.',
|
||||
) );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( preg_match( '/\W/', $callback ) ) {
|
||||
status_header( 400 );
|
||||
echo wp_json_encode( array(
|
||||
'code' => 'json_callback_invalid',
|
||||
'message' => 'The JSONP callback function is invalid.',
|
||||
) );
|
||||
exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd prior to the AS2 feed being created and sent to the client
|
||||
*/
|
||||
do_action( 'as2_feed_pre' );
|
||||
|
||||
while ( have_posts() ) {
|
||||
the_post();
|
||||
|
||||
/*
|
||||
* The object type of the current post in the Activity Streams 1 feed
|
||||
*
|
||||
* @param Object get_post() The current post
|
||||
*/
|
||||
$object_type = apply_filters( 'as2_object_type', 'Article', get_post() );
|
||||
|
||||
$item = array(
|
||||
'published' => get_post_modified_time( 'Y-m-d\TH:i:s\Z', true ),
|
||||
'generator' => 'http://wordpress.org/?v=' . get_bloginfo_rss( 'version' ),
|
||||
'id' => get_post_comments_feed_link( get_the_ID(), 'as2' ),
|
||||
'type' => 'Create',
|
||||
'name' => esc_attr( sprintf( __( '%1$s created a new post', 'activitystream_extension' ), get_the_author() ) ),
|
||||
'target' => (object) array(
|
||||
'id' => get_bloginfo( 'url' ),
|
||||
'type' => 'http://schema.org/Blog',
|
||||
'url' => get_bloginfo( 'url' ),
|
||||
'name' => get_bloginfo( 'name' ),
|
||||
'description' => get_bloginfo( 'description' ),
|
||||
),
|
||||
'object' => (object) array(
|
||||
'id' => get_the_guid(),
|
||||
'type' => $object_type,
|
||||
'name' => get_the_title(),
|
||||
'summary' => get_the_excerpt(),
|
||||
'url' => get_permalink(),
|
||||
'content' => get_the_content(),
|
||||
),
|
||||
'actor' => (object) array(
|
||||
'id' => get_author_posts_url( get_the_author_meta( 'ID' ), get_the_author_meta( 'nicename' ) ),
|
||||
'type' => 'Person',
|
||||
'name' => get_the_author(),
|
||||
'url' => get_author_posts_url( get_the_author_meta( 'ID' ), get_the_author_meta( 'nicename' ) ),
|
||||
'image' => (object) array(
|
||||
'type' => 'Link',
|
||||
'width' => 96,
|
||||
'height' => 96,
|
||||
'href' => get_avatar_url( get_the_author_meta( 'email' ), array( 'size' => 96 ) ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$images = activitystream_extension_get_post_images( get_the_ID() );
|
||||
|
||||
// add attachments
|
||||
if ( $images ) {
|
||||
$attachments = array();
|
||||
|
||||
foreach ( $images as $image ) {
|
||||
$attachment = array(
|
||||
"type" => "Image",
|
||||
"url" => $image['url'],
|
||||
"mediaType" => $image['type'],
|
||||
);
|
||||
|
||||
$attachments[] = $attachment;
|
||||
}
|
||||
|
||||
$item['object']->attachment = $attachments;
|
||||
}
|
||||
|
||||
/*
|
||||
* The item to be added to the Activity Streams 1 feed
|
||||
*
|
||||
* @param object $item The Activity Streams 1 item
|
||||
*/
|
||||
$item = apply_filters( 'as2_feed_item', $item );
|
||||
|
||||
$json->items[] = $item;
|
||||
}
|
||||
|
||||
/*
|
||||
* The array of data to be sent to the user as JSON
|
||||
*
|
||||
* @param object $json The JSON data object
|
||||
*/
|
||||
$json = apply_filters( 'as2_feed', $json );
|
||||
|
||||
$options = 0;
|
||||
// JSON_PRETTY_PRINT added in PHP 5.4
|
||||
if ( get_query_var( 'pretty' ) ) {
|
||||
$options |= JSON_PRETTY_PRINT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Options to be passed to wp_json_encode()
|
||||
*
|
||||
* @param int $options The current options flags
|
||||
*/
|
||||
$options = apply_filters( 'as2_feed_options', $options );
|
||||
|
||||
$json_str = wp_json_encode( $json, $options );
|
||||
|
||||
if ( ! empty( $callback ) ) {
|
||||
echo esc_html( $callback ) . "($json_str);";
|
||||
} else {
|
||||
echo $json_str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action triggerd after the AS2 feed has been created and sent to the client
|
||||
*/
|
||||
do_action( 'as2_feed_post' );
|
||||
@@ -1,34 +0,0 @@
|
||||
# Only allow direct access to specific Web-available files.
|
||||
|
||||
# Apache 2.2
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</IfModule>
|
||||
|
||||
# Apache 2.4
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
|
||||
# Akismet CSS and JS
|
||||
<FilesMatch "^(form\.js|akismet\.js|akismet\.css)$">
|
||||
<IfModule !mod_authz_core.c>
|
||||
Allow from all
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all granted
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
|
||||
# Akismet images
|
||||
<FilesMatch "^logo-full-2x\.png$">
|
||||
<IfModule !mod_authz_core.c>
|
||||
Allow from all
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all granted
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
@@ -1,339 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -1,662 +0,0 @@
|
||||
.wp-admin.jetpack_page_akismet-key-config, .wp-admin.settings_page_akismet-key-config {
|
||||
background-color:#f3f6f8;
|
||||
}
|
||||
|
||||
#submitted-on {
|
||||
position: relative;
|
||||
}
|
||||
#the-comment-list .author .akismet-user-comment-count {
|
||||
display: inline;
|
||||
}
|
||||
#the-comment-list .author a span {
|
||||
text-decoration: none;
|
||||
color: #999;
|
||||
}
|
||||
#the-comment-list .author a span.akismet-span-link {
|
||||
text-decoration: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
#the-comment-list .akismet_remove_url {
|
||||
margin-left: 3px;
|
||||
color: #999;
|
||||
padding: 2px 3px 2px 0;
|
||||
}
|
||||
#the-comment-list .akismet_remove_url:hover {
|
||||
color: #A7301F;
|
||||
font-weight: bold;
|
||||
padding: 2px 2px 2px 0;
|
||||
}
|
||||
#dashboard_recent_comments .akismet-status {
|
||||
display: none;
|
||||
}
|
||||
.akismet-status {
|
||||
float: right;
|
||||
}
|
||||
.akismet-status a {
|
||||
color: #AAA;
|
||||
font-style: italic;
|
||||
}
|
||||
table.comments td.comment p a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
table.comments td.comment p a:after {
|
||||
content: attr(href);
|
||||
color: #aaa;
|
||||
display: inline-block; /* Show the URL without the link's underline extending under it. */
|
||||
padding: 0 1ex; /* Because it's inline block, we can't just use spaces in the content: attribute to separate it from the link text. */
|
||||
}
|
||||
.mshot-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 10px solid transparent;
|
||||
border-bottom: 10px solid transparent;
|
||||
border-right: 10px solid #5C5C5C;
|
||||
position: absolute;
|
||||
left: -6px;
|
||||
top: 91px;
|
||||
}
|
||||
.mshot-container {
|
||||
background: #5C5C5C;
|
||||
position: absolute;
|
||||
top: -94px;
|
||||
padding: 7px;
|
||||
width: 450px;
|
||||
height: 338px;
|
||||
z-index: 20000;
|
||||
-moz-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
}
|
||||
.akismet-mshot {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
}
|
||||
.akismet-mshot .mshot-image {
|
||||
margin: 0;
|
||||
height: 338px;
|
||||
width: 450px;
|
||||
}
|
||||
.checkforspam {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.checkforspam-spinner {
|
||||
display: inline-block;
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.akismet-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.akismet-card .akismet-right {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.akismet-alert-text {
|
||||
color: #dd3d36;
|
||||
font-weight: bold;
|
||||
font-size: 120%;
|
||||
margin-top: .5rem;
|
||||
}
|
||||
.akismet-alert {
|
||||
border: 1px solid #e5e5e5;
|
||||
padding: 0.4em 1em 1.4em 1em;
|
||||
border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.akismet-alert h3.akismet-key-status {
|
||||
color: #fff;
|
||||
margin: 1em 0 0.5em 0;
|
||||
}
|
||||
|
||||
.akismet-alert.akismet-critical {
|
||||
background-color: #993300;
|
||||
}
|
||||
|
||||
.akismet-alert.akismet-active {
|
||||
background-color: #649316;
|
||||
}
|
||||
|
||||
.akismet-alert p.akismet-key-status {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.akismet-alert p.akismet-description {
|
||||
color:#fff;
|
||||
font-size: 14px;
|
||||
margin: 0 0;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.akismet-alert p.akismet-description a,
|
||||
.akismet-alert p.akismet-description a,
|
||||
.akismet-alert p.akismet-description a,
|
||||
.akismet-alert p.akismet-description a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.akismet-new-snapshot {
|
||||
margin-top: 1em;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.akismet-new-snapshot h3 {
|
||||
background: #f5f5f5;
|
||||
color: #888;
|
||||
font-size: 11px;
|
||||
margin: 0;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.new-snapspot ul {
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.akismet-new-snapshot ul li {
|
||||
color: #999;
|
||||
float: left;
|
||||
font-size: 11px;
|
||||
padding: 0 20px;
|
||||
text-transform: uppercase;
|
||||
width: 33%;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
}
|
||||
|
||||
.akismet-new-snapshot ul li:first-child,
|
||||
.akismet-new-snapshot ul li:nth-child(2) {
|
||||
border-right:1px dotted #ccc;
|
||||
}
|
||||
|
||||
.akismet-new-snapshot ul li span {
|
||||
color: #52accc;
|
||||
display: block;
|
||||
font-size: 32px;
|
||||
font-weight: lighter;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.akismet-settings th:first-child {
|
||||
vertical-align: top;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.akismet-settings th.akismet-api-key {
|
||||
vertical-align: middle;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.akismet-settings input[type=text] {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.akismet-settings span.akismet-note{
|
||||
float: left;
|
||||
padding-left: 23px;
|
||||
font-size: 75%;
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
/**
|
||||
* For the activation notice on the plugins page.
|
||||
*/
|
||||
|
||||
#akismet_setup_prompt {
|
||||
background: none;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.akismet_activate {
|
||||
border: 1px solid #4F800D;
|
||||
padding: 5px;
|
||||
margin: 15px 0;
|
||||
background: #83AF24;
|
||||
background-image: -webkit-gradient(linear, 0% 0, 80% 100%, from(#83AF24), to(#4F800D));
|
||||
background-image: -moz-linear-gradient(80% 100% 120deg, #4F800D, #83AF24);
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.akismet_activate .aa_a {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
right: 10px;
|
||||
font-size: 140px;
|
||||
color: #769F33;
|
||||
font-family: Georgia, "Times New Roman", Times, serif;
|
||||
}
|
||||
|
||||
.akismet_activate .aa_button {
|
||||
font-weight: bold;
|
||||
border: 1px solid #029DD6;
|
||||
border-top: 1px solid #06B9FD;
|
||||
font-size: 15px;
|
||||
text-align: center;
|
||||
padding: 9px 0 8px 0;
|
||||
color: #FFF;
|
||||
background: #029DD6;
|
||||
background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(#029DD6), to(#0079B1));
|
||||
background-image: -moz-linear-gradient(0% 100% 90deg, #0079B1, #029DD6);
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.akismet_activate .aa_button:hover {
|
||||
text-decoration: none !important;
|
||||
border: 1px solid #029DD6;
|
||||
border-bottom: 1px solid #00A8EF;
|
||||
font-size: 15px;
|
||||
text-align: center;
|
||||
padding: 9px 0 8px 0;
|
||||
color: #F0F8FB;
|
||||
background: #0079B1;
|
||||
background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(#0079B1), to(#0092BF));
|
||||
background-image: -moz-linear-gradient(0% 100% 90deg, #0092BF, #0079B1);
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
}
|
||||
|
||||
.akismet_activate .aa_button_border {
|
||||
border: 1px solid #006699;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
background: #029DD6;
|
||||
background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(#029DD6), to(#0079B1));
|
||||
background-image: -moz-linear-gradient(0% 100% 90deg, #0079B1, #029DD6);
|
||||
}
|
||||
|
||||
.akismet_activate .aa_button_container {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
background: #DEF1B8;
|
||||
padding: 5px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
width: 266px;
|
||||
}
|
||||
|
||||
.akismet_activate .aa_description {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
left: 285px;
|
||||
margin-left: 25px;
|
||||
color: #E5F2B1;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.akismet_activate .aa_description strong {
|
||||
color: #FFF;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@media (max-width: 550px) {
|
||||
.akismet_activate .aa_a {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.akismet_activate .aa_button_container {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 782px) {
|
||||
.akismet_activate {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 850px) {
|
||||
#akismet_setup_prompt .aa_description {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.akismet_activate {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.jetpack_page_akismet-key-config #wpcontent, .settings_page_akismet-key-config #wpcontent {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.akismet-masthead {
|
||||
background-color:#fff;
|
||||
text-align:center;
|
||||
box-shadow:0 1px 0 rgba(200,215,225,0.5),0 1px 2px #e9eff3
|
||||
}
|
||||
@media (max-width: 45rem) {
|
||||
.akismet-masthead {
|
||||
padding:0 1.25rem
|
||||
}
|
||||
}
|
||||
|
||||
.akismet-masthead__inside-container {
|
||||
padding:.375rem 0;
|
||||
margin:0 auto;
|
||||
width:100%;
|
||||
max-width:45rem;
|
||||
text-align: left;
|
||||
}
|
||||
.akismet-masthead__logo-container {
|
||||
padding:.3125rem 0 0
|
||||
}
|
||||
.akismet-masthead__logo {
|
||||
width:10.375rem;
|
||||
height:1.8125rem;
|
||||
}
|
||||
.akismet-masthead__logo-link {
|
||||
display:inline-block;
|
||||
outline:none;
|
||||
vertical-align:middle
|
||||
}
|
||||
.akismet-masthead__logo-link:focus {
|
||||
line-height:0;
|
||||
box-shadow:0 0 0 2px #78dcfa
|
||||
}
|
||||
.akismet-masthead__logo-link+code {
|
||||
margin:0 10px;
|
||||
padding:5px 9px;
|
||||
border-radius:2px;
|
||||
background:#e6ecf1;
|
||||
color:#647a88
|
||||
}
|
||||
.akismet-masthead__links {
|
||||
display:-ms-flexbox;
|
||||
display:flex;
|
||||
-ms-flex-flow:row wrap;
|
||||
flex-flow:row wrap;
|
||||
-ms-flex:2 50%;
|
||||
flex:2 50%;
|
||||
-ms-flex-pack:end;
|
||||
justify-content:flex-end;
|
||||
margin:0
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.akismet-masthead__links {
|
||||
padding-right:.625rem
|
||||
}
|
||||
}
|
||||
.akismet-masthead__link-li {
|
||||
margin:0;
|
||||
padding:0
|
||||
}
|
||||
.akismet-masthead__link {
|
||||
font-style:normal;
|
||||
color:#0087be;
|
||||
padding:.625rem;
|
||||
display:inline-block
|
||||
}
|
||||
.akismet-masthead__link:visited {
|
||||
color:#0087be
|
||||
}
|
||||
.akismet-masthead__link:active,.akismet-masthead__link:hover {
|
||||
color:#00aadc
|
||||
}
|
||||
.akismet-masthead__link:hover {
|
||||
text-decoration:underline
|
||||
}
|
||||
.akismet-masthead__link .dashicons {
|
||||
display:none
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.akismet-masthead__link:hover,.akismet-masthead__link:active {
|
||||
text-decoration:none
|
||||
}
|
||||
.akismet-masthead__link .dashicons {
|
||||
display:block;
|
||||
font-size:1.75rem
|
||||
}
|
||||
.akismet-masthead__link span+span {
|
||||
display:none
|
||||
}
|
||||
}
|
||||
.akismet-masthead__link-li:last-of-type .akismet-masthead__link {
|
||||
padding-right:0
|
||||
}
|
||||
|
||||
.akismet-lower {
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
max-width: 45rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.akismet-lower .notice {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.akismet-card {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0;
|
||||
position: relative;
|
||||
margin: 0 auto 0.625rem auto;
|
||||
box-sizing: border-box;
|
||||
background: white;
|
||||
box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
|
||||
}
|
||||
|
||||
.akismet-card:after, .akismet-card .inside:after, .akismet-masthead__logo-container:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.akismet-card .inside {
|
||||
padding: 1.5rem;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.akismet-card .akismet-card-actions {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.jetpack_page_akismet-key-config .update-nag, .settings_page_akismet-key-config .update-nag {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.akismet-masthead .akismet-right {
|
||||
line-height: 2.125rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.akismet-box {
|
||||
box-sizing: border-box;
|
||||
background: white;
|
||||
border: 1px solid rgba(200, 215, 225, 0.5);
|
||||
}
|
||||
|
||||
.akismet-box h2, .akismet-box h3 {
|
||||
padding: 1.5rem 1.5rem .5rem 1.5rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.akismet-box p {
|
||||
padding: 0 1.5rem 1.5rem 1.5rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.akismet-jetpack-email {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
.akismet-jetpack-gravatar {
|
||||
padding: 0 0 0 1.5rem;
|
||||
float: left;
|
||||
margin-right: 1rem;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
}
|
||||
|
||||
.akismet-box p:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.akismet-box .akismet-right {
|
||||
padding-right: 1.5rem;
|
||||
}
|
||||
|
||||
.akismet-boxes .akismet-box {
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.akismet-boxes .akismet-box:last-child {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.akismet-boxes .akismet-box:first-child {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.akismet-box-header {
|
||||
max-width: 700px;
|
||||
margin: 0 auto 40px auto;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.akismet-box-header h2 {
|
||||
margin: 1.5rem 10% 0;
|
||||
font-size: 1.375rem;
|
||||
font-weight: 700;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.akismet-box .centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.akismet-enter-api-key-box {
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
.akismet-box .enter-api-key {
|
||||
display: none;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.akismet-box .akismet-toggles {
|
||||
margin: 3rem 0;
|
||||
}
|
||||
|
||||
.akismet-box .akismet-ak-connect, .akismet-box .toggle-jp-connect {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.akismet-box .enter-api-key p {
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
|
||||
.akismet-button, .akismet-button:hover, .akismet-button:visited {
|
||||
background: white;
|
||||
border-color: #c8d7e1;
|
||||
border-style: solid;
|
||||
border-width: 1px 1px 2px;
|
||||
color: #2e4453;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
outline: 0;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-overflow: ellipsis;
|
||||
text-decoration: none;
|
||||
vertical-align: top;
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
line-height: 21px;
|
||||
border-radius: 4px;
|
||||
padding: 7px 14px 9px;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.akismet-button:hover {
|
||||
border-color: #a8bece;
|
||||
}
|
||||
|
||||
.akismet-button:active {
|
||||
border-width: 2px 1px 1px;
|
||||
}
|
||||
|
||||
.akismet-is-primary, .akismet-is-primary:hover, .akismet-is-primary:visited {
|
||||
background: #00aadc;
|
||||
border-color: #0087be;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.akismet-is-primary:hover, .akismet-is-primary:focus {
|
||||
border-color: #005082;
|
||||
}
|
||||
|
||||
.akismet-is-primary:hover {
|
||||
border-color: #005082;
|
||||
}
|
||||
|
||||
.akismet-section-header {
|
||||
position: relative;
|
||||
margin: 0 auto 0.625rem auto;
|
||||
padding: 1rem;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
|
||||
background: #ffffff;
|
||||
width: 100%;
|
||||
padding-top: 0.6875rem;
|
||||
padding-bottom: 0.6875rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.akismet-section-header__label {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-ms-flex-positive: 1;
|
||||
flex-grow: 1;
|
||||
line-height: 1.75rem;
|
||||
position: relative;
|
||||
font-size: 0.875rem;
|
||||
color: #4f748e;
|
||||
}
|
||||
|
||||
.akismet-section-header__actions {
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
|
||||
.akismet-setup-instructions {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.akismet-setup-instructions form {
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
@@ -1,350 +0,0 @@
|
||||
jQuery( function ( $ ) {
|
||||
var mshotRemovalTimer = null;
|
||||
var mshotSecondTryTimer = null
|
||||
var mshotThirdTryTimer = null
|
||||
|
||||
var mshotEnabledLinkSelector = 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a';
|
||||
|
||||
$('.akismet-status').each(function () {
|
||||
var thisId = $(this).attr('commentid');
|
||||
$(this).prependTo('#comment-' + thisId + ' .column-comment');
|
||||
});
|
||||
$('.akismet-user-comment-count').each(function () {
|
||||
var thisId = $(this).attr('commentid');
|
||||
$(this).insertAfter('#comment-' + thisId + ' .author strong:first').show();
|
||||
});
|
||||
|
||||
akismet_enable_comment_author_url_removal();
|
||||
|
||||
$( '#the-comment-list' ).on( 'click', '.akismet_remove_url', function () {
|
||||
var thisId = $(this).attr('commentid');
|
||||
var data = {
|
||||
action: 'comment_author_deurl',
|
||||
_wpnonce: WPAkismet.comment_author_url_nonce,
|
||||
id: thisId
|
||||
};
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
type: 'POST',
|
||||
data: data,
|
||||
beforeSend: function () {
|
||||
// Removes "x" link
|
||||
$("a[commentid='"+ thisId +"']").hide();
|
||||
// Show temp status
|
||||
$("#author_comment_url_"+ thisId).html( $( '<span/>' ).text( WPAkismet.strings['Removing...'] ) );
|
||||
},
|
||||
success: function (response) {
|
||||
if (response) {
|
||||
// Show status/undo link
|
||||
$("#author_comment_url_"+ thisId)
|
||||
.attr('cid', thisId)
|
||||
.addClass('akismet_undo_link_removal')
|
||||
.html(
|
||||
$( '<span/>' ).text( WPAkismet.strings['URL removed'] )
|
||||
)
|
||||
.append( ' ' )
|
||||
.append(
|
||||
$( '<span/>' )
|
||||
.text( WPAkismet.strings['(undo)'] )
|
||||
.addClass( 'akismet-span-link' )
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}).on( 'click', '.akismet_undo_link_removal', function () {
|
||||
var thisId = $(this).attr('cid');
|
||||
var thisUrl = $(this).attr('href');
|
||||
var data = {
|
||||
action: 'comment_author_reurl',
|
||||
_wpnonce: WPAkismet.comment_author_url_nonce,
|
||||
id: thisId,
|
||||
url: thisUrl
|
||||
};
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
type: 'POST',
|
||||
data: data,
|
||||
beforeSend: function () {
|
||||
// Show temp status
|
||||
$("#author_comment_url_"+ thisId).html( $( '<span/>' ).text( WPAkismet.strings['Re-adding...'] ) );
|
||||
},
|
||||
success: function (response) {
|
||||
if (response) {
|
||||
// Add "x" link
|
||||
$("a[commentid='"+ thisId +"']").show();
|
||||
// Show link. Core strips leading http://, so let's do that too.
|
||||
$("#author_comment_url_"+ thisId).removeClass('akismet_undo_link_removal').text( thisUrl.replace( /^http:\/\/(www\.)?/ig, '' ) );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// Show a preview image of the hovered URL. Applies to author URLs and URLs inside the comments.
|
||||
if ( "enable_mshots" in WPAkismet && WPAkismet.enable_mshots ) {
|
||||
$( '#the-comment-list' ).on( 'mouseover', mshotEnabledLinkSelector, function () {
|
||||
clearTimeout( mshotRemovalTimer );
|
||||
|
||||
if ( $( '.akismet-mshot' ).length > 0 ) {
|
||||
if ( $( '.akismet-mshot:first' ).data( 'link' ) == this ) {
|
||||
// The preview is already showing for this link.
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// A new link is being hovered, so remove the old preview.
|
||||
$( '.akismet-mshot' ).remove();
|
||||
}
|
||||
}
|
||||
|
||||
clearTimeout( mshotSecondTryTimer );
|
||||
clearTimeout( mshotThirdTryTimer );
|
||||
|
||||
var thisHref = $( this ).attr( 'href' );
|
||||
|
||||
var mShot = $( '<div class="akismet-mshot mshot-container"><div class="mshot-arrow"></div><img src="' + akismet_mshot_url( thisHref ) + '" width="450" height="338" class="mshot-image" /></div>' );
|
||||
mShot.data( 'link', this );
|
||||
|
||||
var offset = $( this ).offset();
|
||||
|
||||
mShot.offset( {
|
||||
left : Math.min( $( window ).width() - 475, offset.left + $( this ).width() + 10 ), // Keep it on the screen if the link is near the edge of the window.
|
||||
top: offset.top + ( $( this ).height() / 2 ) - 101 // 101 = top offset of the arrow plus the top border thickness
|
||||
} );
|
||||
|
||||
// These retries appear to be superfluous if .mshot-image has already loaded, but it's because mShots
|
||||
// can return a "Generating thumbnail..." image if it doesn't have a thumbnail ready, so we need
|
||||
// to retry to see if we can get the newly generated thumbnail.
|
||||
mshotSecondTryTimer = setTimeout( function () {
|
||||
mShot.find( '.mshot-image' ).attr( 'src', akismet_mshot_url( thisHref, 2 ) );
|
||||
}, 6000 );
|
||||
|
||||
mshotThirdTryTimer = setTimeout( function () {
|
||||
mShot.find( '.mshot-image' ).attr( 'src', akismet_mshot_url( thisHref, 3 ) );
|
||||
}, 12000 );
|
||||
|
||||
$( 'body' ).append( mShot );
|
||||
} ).on( 'mouseout', 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a', function () {
|
||||
mshotRemovalTimer = setTimeout( function () {
|
||||
clearTimeout( mshotSecondTryTimer );
|
||||
clearTimeout( mshotThirdTryTimer );
|
||||
|
||||
$( '.akismet-mshot' ).remove();
|
||||
}, 200 );
|
||||
} ).on( 'mouseover', 'tr', function () {
|
||||
// When the mouse hovers over a comment row, begin preloading mshots for any links in the comment or the comment author.
|
||||
var linksToPreloadMshotsFor = $( this ).find( mshotEnabledLinkSelector );
|
||||
|
||||
linksToPreloadMshotsFor.each( function () {
|
||||
// Don't attempt to preload an mshot for a single link twice. Browser caching should cover this, but in case of
|
||||
// race conditions, save a flag locally when we've begun trying to preload one.
|
||||
if ( ! $( this ).data( 'akismet-mshot-preloaded' ) ) {
|
||||
akismet_preload_mshot( $( this ).attr( 'href' ) );
|
||||
$( this ).data( 'akismet-mshot-preloaded', true );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
$( '.checkforspam.enable-on-load' ).click( function( e ) {
|
||||
if ( $( this ).hasClass( 'ajax-disabled' ) ) {
|
||||
// Akismet hasn't been configured yet. Allow the user to proceed to the button's link.
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if ( $( this ).hasClass( 'button-disabled' ) ) {
|
||||
window.location.href = $( this ).data( 'success-url' ).replace( '__recheck_count__', 0 ).replace( '__spam_count__', 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
$('.checkforspam').addClass('button-disabled').addClass( 'checking' );
|
||||
$('.checkforspam-spinner').addClass( 'spinner' ).addClass( 'is-active' );
|
||||
|
||||
akismet_check_for_spam(0, 100);
|
||||
});
|
||||
$( '.checkforspam.enable-on-load' ).removeClass( 'button-disabled' );
|
||||
|
||||
var spam_count = 0;
|
||||
var recheck_count = 0;
|
||||
|
||||
function akismet_check_for_spam(offset, limit) {
|
||||
var check_for_spam_buttons = $( '.checkforspam' );
|
||||
|
||||
var nonce = check_for_spam_buttons.data( 'nonce' );
|
||||
|
||||
// We show the percentage complete down to one decimal point so even queues with 100k
|
||||
// pending comments will show some progress pretty quickly.
|
||||
var percentage_complete = Math.round( ( recheck_count / check_for_spam_buttons.data( 'pending-comment-count' ) ) * 1000 ) / 10;
|
||||
|
||||
// Update the progress counter on the "Check for Spam" button.
|
||||
$( '.checkforspam' ).text( check_for_spam_buttons.data( 'progress-label' ).replace( '%1$s', percentage_complete ) );
|
||||
|
||||
$.post(
|
||||
ajaxurl,
|
||||
{
|
||||
'action': 'akismet_recheck_queue',
|
||||
'offset': offset,
|
||||
'limit': limit,
|
||||
'nonce': nonce
|
||||
},
|
||||
function(result) {
|
||||
if ( 'error' in result ) {
|
||||
// An error is only returned in the case of a missing nonce, so we don't need the actual error message.
|
||||
window.location.href = check_for_spam_buttons.data( 'failure-url' );
|
||||
return;
|
||||
}
|
||||
|
||||
recheck_count += result.counts.processed;
|
||||
spam_count += result.counts.spam;
|
||||
|
||||
if (result.counts.processed < limit) {
|
||||
window.location.href = check_for_spam_buttons.data( 'success-url' ).replace( '__recheck_count__', recheck_count ).replace( '__spam_count__', spam_count );
|
||||
}
|
||||
else {
|
||||
// Account for comments that were caught as spam and moved out of the queue.
|
||||
akismet_check_for_spam(offset + limit - result.counts.spam, limit);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if ( "start_recheck" in WPAkismet && WPAkismet.start_recheck ) {
|
||||
$( '.checkforspam' ).click();
|
||||
}
|
||||
|
||||
if ( typeof MutationObserver !== 'undefined' ) {
|
||||
// Dynamically add the "X" next the the author URL links when a comment is quick-edited.
|
||||
var comment_list_container = document.getElementById( 'the-comment-list' );
|
||||
|
||||
if ( comment_list_container ) {
|
||||
var observer = new MutationObserver( function ( mutations ) {
|
||||
for ( var i = 0, _len = mutations.length; i < _len; i++ ) {
|
||||
if ( mutations[i].addedNodes.length > 0 ) {
|
||||
akismet_enable_comment_author_url_removal();
|
||||
|
||||
// Once we know that we'll have to check for new author links, skip the rest of the mutations.
|
||||
break;
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
observer.observe( comment_list_container, { attributes: true, childList: true, characterData: true } );
|
||||
}
|
||||
}
|
||||
|
||||
function akismet_enable_comment_author_url_removal() {
|
||||
$( '#the-comment-list' )
|
||||
.find( 'tr.comment, tr[id ^= "comment-"]' )
|
||||
.find( '.column-author a[href^="http"]:first' ) // Ignore mailto: links, which would be the comment author's email.
|
||||
.each(function () {
|
||||
if ( $( this ).parent().find( '.akismet_remove_url' ).length > 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var linkHref = $(this).attr( 'href' );
|
||||
|
||||
// Ignore any links to the current domain, which are diagnostic tools, like the IP address link
|
||||
// or any other links another plugin might add.
|
||||
var currentHostParts = document.location.href.split( '/' );
|
||||
var currentHost = currentHostParts[0] + '//' + currentHostParts[2] + '/';
|
||||
|
||||
if ( linkHref.indexOf( currentHost ) != 0 ) {
|
||||
var thisCommentId = $(this).parents('tr:first').attr('id').split("-");
|
||||
|
||||
$(this)
|
||||
.attr("id", "author_comment_url_"+ thisCommentId[1])
|
||||
.after(
|
||||
$( '<a href="#" class="akismet_remove_url">x</a>' )
|
||||
.attr( 'commentid', thisCommentId[1] )
|
||||
.attr( 'title', WPAkismet.strings['Remove this URL'] )
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an mShot URL if given a link URL.
|
||||
*
|
||||
* @param string linkUrl
|
||||
* @param int retry If retrying a request, the number of the retry.
|
||||
* @return string The mShot URL;
|
||||
*/
|
||||
function akismet_mshot_url( linkUrl, retry ) {
|
||||
var mshotUrl = '//s0.wordpress.com/mshots/v1/' + encodeURIComponent( linkUrl ) + '?w=900';
|
||||
|
||||
if ( retry ) {
|
||||
mshotUrl += '&r=' + encodeURIComponent( retry );
|
||||
}
|
||||
|
||||
return mshotUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin loading an mShot preview of a link.
|
||||
*
|
||||
* @param string linkUrl
|
||||
*/
|
||||
function akismet_preload_mshot( linkUrl ) {
|
||||
var img = new Image();
|
||||
img.src = akismet_mshot_url( linkUrl );
|
||||
}
|
||||
|
||||
$( '.akismet-could-be-primary' ).each( function () {
|
||||
var form = $( this ).closest( 'form' );
|
||||
|
||||
form.data( 'initial-state', form.serialize() );
|
||||
|
||||
form.on( 'change keyup', function () {
|
||||
var self = $( this );
|
||||
var submit_button = self.find( '.akismet-could-be-primary' );
|
||||
|
||||
if ( self.serialize() != self.data( 'initial-state' ) ) {
|
||||
submit_button.addClass( 'akismet-is-primary' );
|
||||
}
|
||||
else {
|
||||
submit_button.removeClass( 'akismet-is-primary' );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Shows the Enter API key form
|
||||
*/
|
||||
$( '.akismet-enter-api-key-box a' ).on( 'click', function ( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
var div = $( '.enter-api-key' );
|
||||
div.show( 500 );
|
||||
div.find( 'input[name=key]' ).focus();
|
||||
|
||||
$( this ).hide();
|
||||
} );
|
||||
|
||||
/**
|
||||
* Hides the Connect with Jetpack form | Shows the Activate Akismet Account form
|
||||
*/
|
||||
$( 'a.toggle-ak-connect' ).on( 'click', function ( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
$( '.akismet-ak-connect' ).slideToggle('slow');
|
||||
$( 'a.toggle-ak-connect' ).hide();
|
||||
$( '.akismet-jp-connect' ).hide();
|
||||
$( 'a.toggle-jp-connect' ).show();
|
||||
} );
|
||||
|
||||
/**
|
||||
* Shows the Connect with Jetpack form | Hides the Activate Akismet Account form
|
||||
*/
|
||||
$( 'a.toggle-jp-connect' ).on( 'click', function ( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
$( '.akismet-jp-connect' ).slideToggle('slow');
|
||||
$( 'a.toggle-jp-connect' ).hide();
|
||||
$( '.akismet-ak-connect' ).hide();
|
||||
$( 'a.toggle-ak-connect' ).show();
|
||||
} );
|
||||
});
|
||||
@@ -1,30 +0,0 @@
|
||||
var ak_js = document.getElementById( "ak_js" );
|
||||
|
||||
if ( ! ak_js ) {
|
||||
ak_js = document.createElement( 'input' );
|
||||
ak_js.setAttribute( 'id', 'ak_js' );
|
||||
ak_js.setAttribute( 'name', 'ak_js' );
|
||||
ak_js.setAttribute( 'type', 'hidden' );
|
||||
}
|
||||
else {
|
||||
ak_js.parentNode.removeChild( ak_js );
|
||||
}
|
||||
|
||||
ak_js.setAttribute( 'value', ( new Date() ).getTime() );
|
||||
|
||||
var commentForm = document.getElementById( 'commentform' );
|
||||
|
||||
if ( commentForm ) {
|
||||
commentForm.appendChild( ak_js );
|
||||
}
|
||||
else {
|
||||
var replyRowContainer = document.getElementById( 'replyrow' );
|
||||
|
||||
if ( replyRowContainer ) {
|
||||
var children = replyRowContainer.getElementsByTagName( 'td' );
|
||||
|
||||
if ( children.length > 0 ) {
|
||||
children[0].appendChild( ak_js );
|
||||
}
|
||||
}
|
||||
}
|
||||
Archivo binario no mostrado.
|
Antes Anchura: | Altura: | Tamaño: 4.9 KiB |
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Akismet
|
||||
*/
|
||||
/*
|
||||
Plugin Name: Akismet Anti-Spam
|
||||
Plugin URI: https://akismet.com/
|
||||
Description: Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from spam</strong>. It keeps your site protected even while you sleep. To get started: activate the Akismet plugin and then go to your Akismet Settings page to set up your API key.
|
||||
Version: 4.1.6
|
||||
Author: Automattic
|
||||
Author URI: https://automattic.com/wordpress-plugins/
|
||||
License: GPLv2 or later
|
||||
Text Domain: akismet
|
||||
*/
|
||||
|
||||
/*
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Copyright 2005-2015 Automattic, Inc.
|
||||
*/
|
||||
|
||||
// Make sure we don't expose any info if called directly
|
||||
if ( !function_exists( 'add_action' ) ) {
|
||||
echo 'Hi there! I\'m just a plugin, not much I can do when called directly.';
|
||||
exit;
|
||||
}
|
||||
|
||||
define( 'AKISMET_VERSION', '4.1.6' );
|
||||
define( 'AKISMET__MINIMUM_WP_VERSION', '4.0' );
|
||||
define( 'AKISMET__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
||||
define( 'AKISMET_DELETE_LIMIT', 100000 );
|
||||
|
||||
register_activation_hook( __FILE__, array( 'Akismet', 'plugin_activation' ) );
|
||||
register_deactivation_hook( __FILE__, array( 'Akismet', 'plugin_deactivation' ) );
|
||||
|
||||
require_once( AKISMET__PLUGIN_DIR . 'class.akismet.php' );
|
||||
require_once( AKISMET__PLUGIN_DIR . 'class.akismet-widget.php' );
|
||||
require_once( AKISMET__PLUGIN_DIR . 'class.akismet-rest-api.php' );
|
||||
|
||||
add_action( 'init', array( 'Akismet', 'init' ) );
|
||||
|
||||
add_action( 'rest_api_init', array( 'Akismet_REST_API', 'init' ) );
|
||||
|
||||
if ( is_admin() || ( defined( 'WP_CLI' ) && WP_CLI ) ) {
|
||||
require_once( AKISMET__PLUGIN_DIR . 'class.akismet-admin.php' );
|
||||
add_action( 'init', array( 'Akismet_Admin', 'init' ) );
|
||||
}
|
||||
|
||||
//add wrapper class around deprecated akismet functions that are referenced elsewhere
|
||||
require_once( AKISMET__PLUGIN_DIR . 'wrapper.php' );
|
||||
|
||||
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||||
require_once( AKISMET__PLUGIN_DIR . 'class.akismet-cli.php' );
|
||||
}
|
||||
@@ -1,418 +0,0 @@
|
||||
=== Akismet Anti-Spam ===
|
||||
|
||||
== Archived Changelog Entries ==
|
||||
|
||||
This file contains older changelog entries, so we can keep the size of the standard WordPress readme.txt file reasonable.
|
||||
For the latest changes, please see the "Changelog" section of the [readme.txt file](https://plugins.svn.wordpress.org/akismet/trunk/readme.txt).
|
||||
|
||||
= 4.0.8 =
|
||||
*Release Date - 19 June 2018*
|
||||
|
||||
* Improved the grammar and consistency of the in-admin privacy related notes (notice and config).
|
||||
* Revised in-admin explanation of the comment form privacy notice to make its usage clearer.
|
||||
* Added `rel="nofollow noopener"` to the comment form privacy notice to improve SEO and security.
|
||||
|
||||
= 4.0.7 =
|
||||
*Release Date - 28 May 2018*
|
||||
|
||||
* Based on user feedback, the link on "Learn how your comment data is processed." in the optional privacy notice now has a `target` of `_blank` and opens in a new tab/window.
|
||||
* Updated the in-admin privacy notice to use the term "comment" instead of "contact" in "Akismet can display a notice to your users under your comment forms."
|
||||
* Only show in-admin privacy notice if Akismet has an API Key configured
|
||||
|
||||
= 4.0.6 =
|
||||
*Release Date - 26 May 2018*
|
||||
|
||||
* Moved away from using `empty( get_option() )` to instantiating a variable to be compatible with older versions of PHP (5.3, 5.4, etc).
|
||||
|
||||
= 4.0.5 =
|
||||
*Release Date - 26 May 2018*
|
||||
|
||||
* Corrected version number after tagging. Sorry...
|
||||
|
||||
= 4.0.4 =
|
||||
*Release Date - 26 May 2018*
|
||||
|
||||
* Added a hook to provide Akismet-specific privacy information for a site's privacy policy.
|
||||
* Added tools to control the display of a privacy related notice under comment forms.
|
||||
* Fixed HTML in activation failure message to close META and HEAD tag properly.
|
||||
* Fixed a bug that would sometimes prevent Akismet from being correctly auto-configured.
|
||||
|
||||
= 4.0.3 =
|
||||
*Release Date - 19 February 2018*
|
||||
|
||||
* Added a scheduled task to remove entries in wp_commentmeta that no longer have corresponding comments in wp_comments.
|
||||
* Added a new `akismet_batch_delete_count` action to the batch delete methods for people who'd like to keep track of the numbers of records being processed by those methods.
|
||||
|
||||
= 4.0.2 =
|
||||
*Release Date - 18 December 2017*
|
||||
|
||||
* Fixed a bug that could cause Akismet to recheck a comment that has already been manually approved or marked as spam.
|
||||
* Fixed a bug that could cause Akismet to claim that some comments are still waiting to be checked when no comments are waiting to be checked.
|
||||
|
||||
= 4.0.1 =
|
||||
*Release Date - 6 November 2017*
|
||||
|
||||
* Fixed a bug that could prevent some users from connecting Akismet via their Jetpack connection.
|
||||
* Ensured that any pending Akismet-related events are unscheduled if the plugin is deactivated.
|
||||
* Allow some JavaScript to be run asynchronously to avoid affecting page render speeds.
|
||||
|
||||
= 4.0 =
|
||||
*Release Date - 19 September 2017*
|
||||
|
||||
* Added REST API endpoints for configuring Akismet and retrieving stats.
|
||||
* Increased the minimum supported WordPress version to 4.0.
|
||||
* Added compatibility with comments submitted via the REST API.
|
||||
* Improved the progress indicator on the "Check for Spam" button.
|
||||
|
||||
= 3.3.4 =
|
||||
*Release Date - 3 August 2017*
|
||||
|
||||
* Disabled Akismet's debug log output by default unless AKISMET_DEBUG is defined.
|
||||
* URL previews now begin preloading when the mouse moves near them in the comments section of wp-admin.
|
||||
* When a comment is caught by the Comment Blacklist, Akismet will always allow it to stay in the trash even if it is spam as well.
|
||||
* Fixed a bug that was preventing an error from being shown when a site can't reach Akismet's servers.
|
||||
|
||||
= 3.3.3 =
|
||||
*Release Date - 13 July 2017*
|
||||
|
||||
* Reduced amount of bandwidth used by the URL Preview feature.
|
||||
* Improved the admin UI when the API key is manually pre-defined for the site.
|
||||
* Removed a workaround for WordPress installations older than 3.3 that will improve Akismet's compatibility with other plugins.
|
||||
* The number of spam blocked that is displayed on the WordPress dashboard will now be more accurate and updated more frequently.
|
||||
* Fixed a bug in the Akismet widget that could cause PHP warnings.
|
||||
|
||||
= 3.3.2 =
|
||||
*Release Date - 10 May 2017*
|
||||
|
||||
* Fixed a bug causing JavaScript errors in some browsers.
|
||||
|
||||
= 3.3.1 =
|
||||
*Release Date - 2 May 2017*
|
||||
|
||||
* Improve performance by only requesting the akismet_comment_nonce option when absolutely necessary.
|
||||
* Fixed two bugs that could cause PHP warnings.
|
||||
* Fixed a bug that was preventing the "Remove author URL" feature from working after a comment was edited using "Quick Edit."
|
||||
* Fixed a bug that was preventing the URL preview feature from working after a comment was edited using "Quick Edit."
|
||||
|
||||
= 3.3 =
|
||||
*Release Date - 23 February 2017*
|
||||
|
||||
* Updated the Akismet admin pages with a new clean design.
|
||||
* Fixed bugs preventing the `akismet_add_comment_nonce` and `akismet_update_alert` wrapper functions from working properly.
|
||||
* Fixed bug preventing the loading indicator from appearing when re-checking all comments for spam.
|
||||
* Added a progress indicator to the "Check for Spam" button.
|
||||
* Added a success message after manually rechecking the Pending queue for spam.
|
||||
|
||||
= 3.2 =
|
||||
*Release Date - 6 September 2016*
|
||||
|
||||
* Added a WP-CLI module. You can now check comments and recheck the moderation queue from the command line.
|
||||
* Stopped using the deprecated jQuery function `.live()`.
|
||||
* Fixed a bug in `remove_comment_author_url()` and `add_comment_author_url()` that could generate PHP notices.
|
||||
* Fixed a bug that could cause an infinite loop for sites with very very very large comment IDs.
|
||||
* Fixed a bug that could cause the Akismet widget title to be blank.
|
||||
|
||||
= 3.1.11 =
|
||||
*Release Date - 12 May 2016*
|
||||
|
||||
* Fixed a bug that could cause the "Check for Spam" button to skip some comments.
|
||||
* Fixed a bug that could prevent some spam submissions from being sent to Akismet.
|
||||
* Updated all links to use https:// when possible.
|
||||
* Disabled Akismet debug logging unless WP_DEBUG and WP_DEBUG_LOG are both enabled.
|
||||
|
||||
= 3.1.10 =
|
||||
*Release Date - 1 April 2016*
|
||||
|
||||
* Fixed a bug that could cause comments caught as spam to be placed in the Pending queue.
|
||||
* Fixed a bug that could have resulted in comments that were caught by the core WordPress comment blacklist not to have a corresponding History entry.
|
||||
* Fixed a bug that could have caused avoidable PHP warnings in the error log.
|
||||
|
||||
= 3.1.9 =
|
||||
*Release Date - 28 March 2016*
|
||||
|
||||
* Add compatibility with Jetpack so that Jetpack can automatically configure Akismet settings when appropriate.
|
||||
* Fixed a bug preventing some comment data from being sent to Akismet.
|
||||
|
||||
= 3.1.8 =
|
||||
*Release Date - 4 March 2016*
|
||||
|
||||
* Fixed a bug preventing Akismet from being used with some plugins that rewrite admin URLs.
|
||||
* Reduced the amount of bandwidth used on Akismet API calls
|
||||
* Reduced the amount of space Akismet uses in the database
|
||||
* Fixed a bug that could cause comments caught as spam to be placed in the Pending queue.
|
||||
|
||||
= 3.1.7 =
|
||||
*Release Date - 4 January 2016*
|
||||
|
||||
* Added documentation for the 'akismet_comment_nonce' filter.
|
||||
* The post-install activation button is now accessible to screen readers and keyboard-only users.
|
||||
* Fixed a bug that was preventing the "Remove author URL" feature from working in WordPress 4.4
|
||||
|
||||
= 3.1.6 =
|
||||
*Release Date - 14 December 2015*
|
||||
|
||||
* Improve the notices shown after activating Akismet.
|
||||
* Update some strings to allow for the proper plural forms in all languages.
|
||||
|
||||
= 3.1.5 =
|
||||
*Release Date - 13 October 2015*
|
||||
|
||||
* Closes a potential XSS vulnerability.
|
||||
|
||||
= 3.1.4 =
|
||||
*Release Date - 24 September 2015*
|
||||
|
||||
* Fixed a bug that was preventing some users from automatically connecting using Jetpack if they didn't have a current Akismet subscription.
|
||||
* Fixed a bug that could cause comments caught as spam to be placed in the Pending queue.
|
||||
* Error messages and instructions have been simplified to be more understandable.
|
||||
* Link previews are enabled for all links inside comments, not just the author's website link.
|
||||
|
||||
= 3.1.3 =
|
||||
*Release Date - 6 July 2015*
|
||||
|
||||
* Notify users when their account status changes after previously being successfully set up. This should help any users who are seeing blank Akismet settings screens.
|
||||
|
||||
= 3.1.2 =
|
||||
*Release Date - 7 June 2015*
|
||||
|
||||
* Reduced the amount of space Akismet uses in the commentmeta table.
|
||||
* Fixed a bug where some comments with quotes in the author name weren't getting history entries
|
||||
* Pre-emptive security improvements to ensure that the Akismet plugin can't be used by attackers to compromise a WordPress installation.
|
||||
* Better UI for the key entry field: allow whitespace to be included at the beginning or end of the key and strip it out automatically when the form is submitted.
|
||||
* When deactivating the plugin, notify the Akismet API so the site can be marked as inactive.
|
||||
* Clearer error messages.
|
||||
|
||||
= 3.1.1 =
|
||||
*Release Date - 17th March, 2015*
|
||||
|
||||
* Improvements to the "Remove comment author URL" JavaScript
|
||||
* Include the pingback pre-check from the 2.6 branch.
|
||||
|
||||
= 3.1 =
|
||||
*Release Date - 11th March, 2015*
|
||||
|
||||
* Use HTTPS by default for all requests to Akismet.
|
||||
* Fix for a situation where Akismet might strip HTML from a comment.
|
||||
|
||||
= 3.0.4 =
|
||||
*Release Date - 11th December, 2014*
|
||||
|
||||
* Fix to make .htaccess compatible with Apache 2.4.
|
||||
* Fix to allow removal of https author URLs.
|
||||
* Fix to avoid stripping part of the author URL when removing and re-adding.
|
||||
* Removed the "Check for Spam" button from the "Trash" and "Approved" queues, where it would have no effect.
|
||||
* Allow automatic API key configuration when Jetpack is installed and connected to a WordPress.com account
|
||||
|
||||
= 3.0.3 =
|
||||
*Release Date - 3rd November, 2014*
|
||||
|
||||
* Fix for sending the wrong data to delete_comment action that could have prevented old spam comments from being deleted.
|
||||
* Added a filter to disable logging of Akismet debugging information.
|
||||
* Added a filter for the maximum comment age when deleting old spam comments.
|
||||
* Added a filter for the number per batch when deleting old spam comments.
|
||||
* Removed the "Check for Spam" button from the Spam folder.
|
||||
|
||||
= 3.0.2 =
|
||||
*Release Date - 18th August, 2014*
|
||||
|
||||
* Performance improvements.
|
||||
* Fixed a bug that could truncate the comment data being sent to Akismet for checking.
|
||||
|
||||
= 3.0.1 =
|
||||
*Release Date - 9th July, 2014*
|
||||
|
||||
* Removed dependency on PHP's fsockopen function
|
||||
* Fix spam/ham reports to work when reported outside of the WP dashboard, e.g., from Notifications or the WP app
|
||||
* Remove jQuery dependency for comment form JavaScript
|
||||
* Remove unnecessary data from some Akismet comment meta
|
||||
* Suspended keys will now result in all comments being put in moderation, not spam.
|
||||
|
||||
= 3.0.0 =
|
||||
*Release Date - 15th April, 2014*
|
||||
|
||||
* Move Akismet to Settings menu
|
||||
* Drop Akismet Stats menu
|
||||
* Add stats snapshot to Akismet settings
|
||||
* Add Akismet subscription details and status to Akismet settings
|
||||
* Add contextual help for each page
|
||||
* Improve Akismet setup to use Jetpack to automate plugin setup
|
||||
* Fix "Check for Spam" to use AJAX to avoid page timing out
|
||||
* Fix Akismet settings page to be responsive
|
||||
* Drop legacy code
|
||||
* Tidy up CSS and Javascript
|
||||
* Replace the old discard setting with a new "discard pervasive spam" feature.
|
||||
|
||||
= 2.6.0 =
|
||||
*Release Date - 18th March, 2014*
|
||||
|
||||
* Add ajax paging to the check for spam button to handle large volumes of comments
|
||||
* Optimize javascript and add localization support
|
||||
* Fix bug in link to spam comments from right now dashboard widget
|
||||
* Fix bug with deleting old comments to avoid timeouts dealing with large volumes of comments
|
||||
* Include X-Pingback-Forwarded-For header in outbound WordPress pingback verifications
|
||||
* Add pre-check for pingbacks, to stop spam before an outbound verification request is made
|
||||
|
||||
= 2.5.9 =
|
||||
*Release Date - 1st August, 2013*
|
||||
|
||||
* Update 'Already have a key' link to redirect page rather than depend on javascript
|
||||
* Fix some non-translatable strings to be translatable
|
||||
* Update Activation banner in plugins page to redirect user to Akismet config page
|
||||
|
||||
= 2.5.8 =
|
||||
*Release Date - 20th January, 2013*
|
||||
|
||||
* Simplify the activation process for new users
|
||||
* Remove the reporter_ip parameter
|
||||
* Minor preventative security improvements
|
||||
|
||||
= 2.5.7 =
|
||||
*Release Date - 13th December, 2012*
|
||||
|
||||
* FireFox Stats iframe preview bug
|
||||
* Fix mshots preview when using https
|
||||
* Add .htaccess to block direct access to files
|
||||
* Prevent some PHP notices
|
||||
* Fix Check For Spam return location when referrer is empty
|
||||
* Fix Settings links for network admins
|
||||
* Fix prepare() warnings in WP 3.5
|
||||
|
||||
= 2.5.6 =
|
||||
*Release Date - 26th April, 2012*
|
||||
|
||||
* Prevent retry scheduling problems on sites where wp_cron is misbehaving
|
||||
* Preload mshot previews
|
||||
* Modernize the widget code
|
||||
* Fix a bug where comments were not held for moderation during an error condition
|
||||
* Improve the UX and display when comments are temporarily held due to an error
|
||||
* Make the Check For Spam button force a retry when comments are held due to an error
|
||||
* Handle errors caused by an invalid key
|
||||
* Don't retry comments that are too old
|
||||
* Improve error messages when verifying an API key
|
||||
|
||||
= 2.5.5 =
|
||||
*Release Date - 11th January, 2012*
|
||||
|
||||
* Add nonce check for comment author URL remove action
|
||||
* Fix the settings link
|
||||
|
||||
= 2.5.4 =
|
||||
*Release Date - 5th January, 2012*
|
||||
|
||||
* Limit Akismet CSS and Javascript loading in wp-admin to just the pages that need it
|
||||
* Added author URL quick removal functionality
|
||||
* Added mShot preview on Author URL hover
|
||||
* Added empty index.php to prevent directory listing
|
||||
* Move wp-admin menu items under Jetpack, if it is installed
|
||||
* Purge old Akismet comment meta data, default of 15 days
|
||||
|
||||
= 2.5.3 =
|
||||
*Release Date - 8th Febuary, 2011*
|
||||
|
||||
* Specify the license is GPL v2 or later
|
||||
* Fix a bug that could result in orphaned commentmeta entries
|
||||
* Include hotfix for WordPress 3.0.5 filter issue
|
||||
|
||||
= 2.5.2 =
|
||||
*Release Date - 14th January, 2011*
|
||||
|
||||
* Properly format the comment count for author counts
|
||||
* Look for super admins on multisite installs when looking up user roles
|
||||
* Increase the HTTP request timeout
|
||||
* Removed padding for author approved count
|
||||
* Fix typo in function name
|
||||
* Set Akismet stats iframe height to fixed 2500px. Better to have one tall scroll bar than two side by side.
|
||||
|
||||
= 2.5.1 =
|
||||
*Release Date - 17th December, 2010*
|
||||
|
||||
* Fix a bug that caused the "Auto delete" option to fail to discard comments correctly
|
||||
* Remove the comment nonce form field from the 'Akismet Configuration' page in favor of using a filter, akismet_comment_nonce
|
||||
* Fixed padding bug in "author" column of posts screen
|
||||
* Added margin-top to "cleared by ..." badges on dashboard
|
||||
* Fix possible error when calling akismet_cron_recheck()
|
||||
* Fix more PHP warnings
|
||||
* Clean up XHTML warnings for comment nonce
|
||||
* Fix for possible condition where scheduled comment re-checks could get stuck
|
||||
* Clean up the comment meta details after deleting a comment
|
||||
* Only show the status badge if the comment status has been changed by someone/something other than Akismet
|
||||
* Show a 'History' link in the row-actions
|
||||
* Translation fixes
|
||||
* Reduced font-size on author name
|
||||
* Moved "flagged by..." notification to top right corner of comment container and removed heavy styling
|
||||
* Hid "flagged by..." notification while on dashboard
|
||||
|
||||
= 2.5.0 =
|
||||
*Release Date - 7th December, 2010*
|
||||
|
||||
* Track comment actions under 'Akismet Status' on the edit comment screen
|
||||
* Fix a few remaining deprecated function calls ( props Mike Glendinning )
|
||||
* Use HTTPS for the stats IFRAME when wp-admin is using HTTPS
|
||||
* Use the WordPress HTTP class if available
|
||||
* Move the admin UI code to a separate file, only loaded when needed
|
||||
* Add cron retry feature, to replace the old connectivity check
|
||||
* Display Akismet status badge beside each comment
|
||||
* Record history for each comment, and display it on the edit page
|
||||
* Record the complete comment as originally submitted in comment_meta, to use when reporting spam and ham
|
||||
* Highlight links in comment content
|
||||
* New option, "Show the number of comments you've approved beside each comment author."
|
||||
* New option, "Use a nonce on the comment form."
|
||||
|
||||
= 2.4.0 =
|
||||
*Release Date - 23rd August, 2010*
|
||||
|
||||
* Spell out that the license is GPLv2
|
||||
* Fix PHP warnings
|
||||
* Fix WordPress deprecated function calls
|
||||
* Fire the delete_comment action when deleting comments
|
||||
* Move code specific for older WP versions to legacy.php
|
||||
* General code clean up
|
||||
|
||||
= 2.3.0 =
|
||||
*Release Date - 5th June, 2010*
|
||||
|
||||
* Fix "Are you sure" nonce message on config screen in WPMU
|
||||
* Fix XHTML compliance issue in sidebar widget
|
||||
* Change author link; remove some old references to WordPress.com accounts
|
||||
* Localize the widget title (core ticket #13879)
|
||||
|
||||
= 2.2.9 =
|
||||
*Release Date - 2nd June, 2010*
|
||||
|
||||
* Eliminate a potential conflict with some plugins that may cause spurious reports
|
||||
|
||||
= 2.2.8 =
|
||||
*Release Date - 27th May, 2010*
|
||||
|
||||
* Fix bug in initial comment check for ipv6 addresses
|
||||
* Report comments as ham when they are moved from spam to moderation
|
||||
* Report comments as ham when clicking undo after spam
|
||||
* Use transition_comment_status action when available instead of older actions for spam/ham submissions
|
||||
* Better diagnostic messages when PHP network functions are unavailable
|
||||
* Better handling of comments by logged-in users
|
||||
|
||||
= 2.2.7 =
|
||||
*Release Date - 17th December, 2009*
|
||||
|
||||
* Add a new AKISMET_VERSION constant
|
||||
* Reduce the possibility of over-counting spam when another spam filter plugin is in use
|
||||
* Disable the connectivity check when the API key is hard-coded for WPMU
|
||||
|
||||
= 2.2.6 =
|
||||
*Release Date - 20th July, 2009*
|
||||
|
||||
* Fix a global warning introduced in 2.2.5
|
||||
* Add changelog and additional readme.txt tags
|
||||
* Fix an array conversion warning in some versions of PHP
|
||||
* Support a new WPCOM_API_KEY constant for easier use with WordPress MU
|
||||
|
||||
= 2.2.5 =
|
||||
*Release Date - 13th July, 2009*
|
||||
|
||||
* Include a new Server Connectivity diagnostic check, to detect problems caused by firewalls
|
||||
|
||||
= 2.2.4 =
|
||||
*Release Date - 3rd June, 2009*
|
||||
|
||||
* Fixed a key problem affecting the stats feature in WordPress MU
|
||||
* Provide additional blog information in Akismet API calls
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,185 +0,0 @@
|
||||
<?php
|
||||
|
||||
WP_CLI::add_command( 'akismet', 'Akismet_CLI' );
|
||||
|
||||
/**
|
||||
* Filter spam comments.
|
||||
*/
|
||||
class Akismet_CLI extends WP_CLI_Command {
|
||||
/**
|
||||
* Checks one or more comments against the Akismet API.
|
||||
*
|
||||
* ## OPTIONS
|
||||
* <comment_id>...
|
||||
* : The ID(s) of the comment(s) to check.
|
||||
*
|
||||
* [--noaction]
|
||||
* : Don't change the status of the comment. Just report what Akismet thinks it is.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp akismet check 12345
|
||||
*
|
||||
* @alias comment-check
|
||||
*/
|
||||
public function check( $args, $assoc_args ) {
|
||||
foreach ( $args as $comment_id ) {
|
||||
if ( isset( $assoc_args['noaction'] ) ) {
|
||||
// Check the comment, but don't reclassify it.
|
||||
$api_response = Akismet::check_db_comment( $comment_id, 'wp-cli' );
|
||||
}
|
||||
else {
|
||||
$api_response = Akismet::recheck_comment( $comment_id, 'wp-cli' );
|
||||
}
|
||||
|
||||
if ( 'true' === $api_response ) {
|
||||
WP_CLI::line( sprintf( __( "Comment #%d is spam.", 'akismet' ), $comment_id ) );
|
||||
}
|
||||
else if ( 'false' === $api_response ) {
|
||||
WP_CLI::line( sprintf( __( "Comment #%d is not spam.", 'akismet' ), $comment_id ) );
|
||||
}
|
||||
else {
|
||||
if ( false === $api_response ) {
|
||||
WP_CLI::error( __( "Failed to connect to Akismet.", 'akismet' ) );
|
||||
}
|
||||
else if ( is_wp_error( $api_response ) ) {
|
||||
WP_CLI::warning( sprintf( __( "Comment #%d could not be checked.", 'akismet' ), $comment_id ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recheck all comments in the Pending queue.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp akismet recheck_queue
|
||||
*
|
||||
* @alias recheck-queue
|
||||
*/
|
||||
public function recheck_queue() {
|
||||
$batch_size = 100;
|
||||
$start = 0;
|
||||
|
||||
$total_counts = array();
|
||||
|
||||
do {
|
||||
$result_counts = Akismet_Admin::recheck_queue_portion( $start, $batch_size );
|
||||
|
||||
if ( $result_counts['processed'] > 0 ) {
|
||||
foreach ( $result_counts as $key => $count ) {
|
||||
if ( ! isset( $total_counts[ $key ] ) ) {
|
||||
$total_counts[ $key ] = $count;
|
||||
}
|
||||
else {
|
||||
$total_counts[ $key ] += $count;
|
||||
}
|
||||
}
|
||||
$start += $batch_size;
|
||||
$start -= $result_counts['spam']; // These comments will have been removed from the queue.
|
||||
}
|
||||
} while ( $result_counts['processed'] > 0 );
|
||||
|
||||
WP_CLI::line( sprintf( _n( "Processed %d comment.", "Processed %d comments.", $total_counts['processed'], 'akismet' ), number_format( $total_counts['processed'] ) ) );
|
||||
WP_CLI::line( sprintf( _n( "%d comment moved to Spam.", "%d comments moved to Spam.", $total_counts['spam'], 'akismet' ), number_format( $total_counts['spam'] ) ) );
|
||||
|
||||
if ( $total_counts['error'] ) {
|
||||
WP_CLI::line( sprintf( _n( "%d comment could not be checked.", "%d comments could not be checked.", $total_counts['error'], 'akismet' ), number_format( $total_counts['error'] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches stats from the Akismet API.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [<interval>]
|
||||
* : The time period for which to retrieve stats.
|
||||
* ---
|
||||
* default: all
|
||||
* options:
|
||||
* - days
|
||||
* - months
|
||||
* - all
|
||||
* ---
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Allows overriding the output of the command when listing connections.
|
||||
* ---
|
||||
* default: table
|
||||
* options:
|
||||
* - table
|
||||
* - json
|
||||
* - csv
|
||||
* - yaml
|
||||
* - count
|
||||
* ---
|
||||
*
|
||||
* [--summary]
|
||||
* : When set, will display a summary of the stats.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp akismet stats
|
||||
* wp akismet stats all
|
||||
* wp akismet stats days
|
||||
* wp akismet stats months
|
||||
* wp akismet stats all --summary
|
||||
*/
|
||||
public function stats( $args, $assoc_args ) {
|
||||
$api_key = Akismet::get_api_key();
|
||||
|
||||
if ( empty( $api_key ) ) {
|
||||
WP_CLI::error( __( 'API key must be set to fetch stats.', 'akismet' ) );
|
||||
}
|
||||
|
||||
switch ( $args[0] ) {
|
||||
case 'days':
|
||||
$interval = '60-days';
|
||||
break;
|
||||
case 'months':
|
||||
$interval = '6-months';
|
||||
break;
|
||||
default:
|
||||
$interval = 'all';
|
||||
break;
|
||||
}
|
||||
|
||||
$response = Akismet::http_post(
|
||||
Akismet::build_query( array(
|
||||
'blog' => get_option( 'home' ),
|
||||
'key' => $api_key,
|
||||
'from' => $interval,
|
||||
) ),
|
||||
'get-stats'
|
||||
);
|
||||
|
||||
if ( empty( $response[1] ) ) {
|
||||
WP_CLI::error( __( 'Currently unable to fetch stats. Please try again.', 'akismet' ) );
|
||||
}
|
||||
|
||||
$response_body = json_decode( $response[1], true );
|
||||
|
||||
if ( is_null( $response_body ) ) {
|
||||
WP_CLI::error( __( 'Stats response could not be decoded.', 'akismet' ) );
|
||||
}
|
||||
|
||||
if ( isset( $assoc_args['summary'] ) ) {
|
||||
$keys = array(
|
||||
'spam',
|
||||
'ham',
|
||||
'missed_spam',
|
||||
'false_positives',
|
||||
'accuracy',
|
||||
'time_saved',
|
||||
);
|
||||
|
||||
WP_CLI\Utils\format_items( $assoc_args['format'], array( $response_body ), $keys );
|
||||
}
|
||||
else {
|
||||
$stats = $response_body['breakdown'];
|
||||
WP_CLI\Utils\format_items( $assoc_args['format'], $stats, array_keys( end( $stats ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,366 +0,0 @@
|
||||
<?php
|
||||
|
||||
class Akismet_REST_API {
|
||||
/**
|
||||
* Register the REST API routes.
|
||||
*/
|
||||
public static function init() {
|
||||
if ( ! function_exists( 'register_rest_route' ) ) {
|
||||
// The REST API wasn't integrated into core until 4.4, and we support 4.0+ (for now).
|
||||
return false;
|
||||
}
|
||||
|
||||
register_rest_route( 'akismet/v1', '/key', array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'privileged_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'get_key' ),
|
||||
), array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'privileged_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'set_key' ),
|
||||
'args' => array(
|
||||
'key' => array(
|
||||
'required' => true,
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'Akismet_REST_API', 'sanitize_key' ),
|
||||
'description' => __( 'A 12-character Akismet API key. Available at akismet.com/get/', 'akismet' ),
|
||||
),
|
||||
),
|
||||
), array(
|
||||
'methods' => WP_REST_Server::DELETABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'privileged_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'delete_key' ),
|
||||
)
|
||||
) );
|
||||
|
||||
register_rest_route( 'akismet/v1', '/settings/', array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'privileged_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'get_settings' ),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'privileged_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'set_boolean_settings' ),
|
||||
'args' => array(
|
||||
'akismet_strictness' => array(
|
||||
'required' => false,
|
||||
'type' => 'boolean',
|
||||
'description' => __( 'If true, Akismet will automatically discard the worst spam automatically rather than putting it in the spam folder.', 'akismet' ),
|
||||
),
|
||||
'akismet_show_user_comments_approved' => array(
|
||||
'required' => false,
|
||||
'type' => 'boolean',
|
||||
'description' => __( 'If true, show the number of approved comments beside each comment author in the comments list page.', 'akismet' ),
|
||||
),
|
||||
),
|
||||
)
|
||||
) );
|
||||
|
||||
register_rest_route( 'akismet/v1', '/stats', array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'privileged_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'get_stats' ),
|
||||
'args' => array(
|
||||
'interval' => array(
|
||||
'required' => false,
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'Akismet_REST_API', 'sanitize_interval' ),
|
||||
'description' => __( 'The time period for which to retrieve stats. Options: 60-days, 6-months, all', 'akismet' ),
|
||||
'default' => 'all',
|
||||
),
|
||||
),
|
||||
) );
|
||||
|
||||
register_rest_route( 'akismet/v1', '/stats/(?P<interval>[\w+])', array(
|
||||
'args' => array(
|
||||
'interval' => array(
|
||||
'description' => __( 'The time period for which to retrieve stats. Options: 60-days, 6-months, all', 'akismet' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'privileged_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'get_stats' ),
|
||||
)
|
||||
) );
|
||||
|
||||
register_rest_route( 'akismet/v1', '/alert', array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'remote_call_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'get_alert' ),
|
||||
'args' => array(
|
||||
'key' => array(
|
||||
'required' => false,
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'Akismet_REST_API', 'sanitize_key' ),
|
||||
'description' => __( 'A 12-character Akismet API key. Available at akismet.com/get/', 'akismet' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'remote_call_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'set_alert' ),
|
||||
'args' => array(
|
||||
'key' => array(
|
||||
'required' => false,
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'Akismet_REST_API', 'sanitize_key' ),
|
||||
'description' => __( 'A 12-character Akismet API key. Available at akismet.com/get/', 'akismet' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::DELETABLE,
|
||||
'permission_callback' => array( 'Akismet_REST_API', 'remote_call_permission_callback' ),
|
||||
'callback' => array( 'Akismet_REST_API', 'delete_alert' ),
|
||||
'args' => array(
|
||||
'key' => array(
|
||||
'required' => false,
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'Akismet_REST_API', 'sanitize_key' ),
|
||||
'description' => __( 'A 12-character Akismet API key. Available at akismet.com/get/', 'akismet' ),
|
||||
),
|
||||
),
|
||||
)
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Akismet API key.
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public static function get_key( $request = null ) {
|
||||
return rest_ensure_response( Akismet::get_api_key() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the API key, if possible.
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public static function set_key( $request ) {
|
||||
if ( defined( 'WPCOM_API_KEY' ) ) {
|
||||
return rest_ensure_response( new WP_Error( 'hardcoded_key', __( 'This site\'s API key is hardcoded and cannot be changed via the API.', 'akismet' ), array( 'status'=> 409 ) ) );
|
||||
}
|
||||
|
||||
$new_api_key = $request->get_param( 'key' );
|
||||
|
||||
if ( ! self::key_is_valid( $new_api_key ) ) {
|
||||
return rest_ensure_response( new WP_Error( 'invalid_key', __( 'The value provided is not a valid and registered API key.', 'akismet' ), array( 'status' => 400 ) ) );
|
||||
}
|
||||
|
||||
update_option( 'wordpress_api_key', $new_api_key );
|
||||
|
||||
return self::get_key();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the API key, if possible.
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public static function delete_key( $request ) {
|
||||
if ( defined( 'WPCOM_API_KEY' ) ) {
|
||||
return rest_ensure_response( new WP_Error( 'hardcoded_key', __( 'This site\'s API key is hardcoded and cannot be deleted.', 'akismet' ), array( 'status'=> 409 ) ) );
|
||||
}
|
||||
|
||||
delete_option( 'wordpress_api_key' );
|
||||
|
||||
return rest_ensure_response( true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Akismet settings.
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public static function get_settings( $request = null ) {
|
||||
return rest_ensure_response( array(
|
||||
'akismet_strictness' => ( get_option( 'akismet_strictness', '1' ) === '1' ),
|
||||
'akismet_show_user_comments_approved' => ( get_option( 'akismet_show_user_comments_approved', '1' ) === '1' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Akismet settings.
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public static function set_boolean_settings( $request ) {
|
||||
foreach ( array(
|
||||
'akismet_strictness',
|
||||
'akismet_show_user_comments_approved',
|
||||
) as $setting_key ) {
|
||||
|
||||
$setting_value = $request->get_param( $setting_key );
|
||||
if ( is_null( $setting_value ) ) {
|
||||
// This setting was not specified.
|
||||
continue;
|
||||
}
|
||||
|
||||
// From 4.7+, WP core will ensure that these are always boolean
|
||||
// values because they are registered with 'type' => 'boolean',
|
||||
// but we need to do this ourselves for prior versions.
|
||||
$setting_value = Akismet_REST_API::parse_boolean( $setting_value );
|
||||
|
||||
update_option( $setting_key, $setting_value ? '1' : '0' );
|
||||
}
|
||||
|
||||
return self::get_settings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a numeric or string boolean value into a boolean.
|
||||
*
|
||||
* @param mixed $value The value to convert into a boolean.
|
||||
* @return bool The converted value.
|
||||
*/
|
||||
public static function parse_boolean( $value ) {
|
||||
switch ( $value ) {
|
||||
case true:
|
||||
case 'true':
|
||||
case '1':
|
||||
case 1:
|
||||
return true;
|
||||
|
||||
case false:
|
||||
case 'false':
|
||||
case '0':
|
||||
case 0:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return (bool) $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Akismet stats for a given time period.
|
||||
*
|
||||
* Possible `interval` values:
|
||||
* - all
|
||||
* - 60-days
|
||||
* - 6-months
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public static function get_stats( $request ) {
|
||||
$api_key = Akismet::get_api_key();
|
||||
|
||||
$interval = $request->get_param( 'interval' );
|
||||
|
||||
$stat_totals = array();
|
||||
|
||||
$response = Akismet::http_post( Akismet::build_query( array( 'blog' => get_option( 'home' ), 'key' => $api_key, 'from' => $interval ) ), 'get-stats' );
|
||||
|
||||
if ( ! empty( $response[1] ) ) {
|
||||
$stat_totals[$interval] = json_decode( $response[1] );
|
||||
}
|
||||
|
||||
return rest_ensure_response( $stat_totals );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current alert code and message. Alert codes are used to notify the site owner
|
||||
* if there's a problem, like a connection issue between their site and the Akismet API,
|
||||
* invalid requests being sent, etc.
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public static function get_alert( $request ) {
|
||||
return rest_ensure_response( array(
|
||||
'code' => get_option( 'akismet_alert_code' ),
|
||||
'message' => get_option( 'akismet_alert_msg' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current alert code and message by triggering a call to the Akismet server.
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public static function set_alert( $request ) {
|
||||
delete_option( 'akismet_alert_code' );
|
||||
delete_option( 'akismet_alert_msg' );
|
||||
|
||||
// Make a request so the most recent alert code and message are retrieved.
|
||||
Akismet::verify_key( Akismet::get_api_key() );
|
||||
|
||||
return self::get_alert( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the current alert code and message.
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public static function delete_alert( $request ) {
|
||||
delete_option( 'akismet_alert_code' );
|
||||
delete_option( 'akismet_alert_msg' );
|
||||
|
||||
return self::get_alert( $request );
|
||||
}
|
||||
|
||||
private static function key_is_valid( $key ) {
|
||||
$response = Akismet::http_post(
|
||||
Akismet::build_query(
|
||||
array(
|
||||
'key' => $key,
|
||||
'blog' => get_option( 'home' )
|
||||
)
|
||||
),
|
||||
'verify-key'
|
||||
);
|
||||
|
||||
if ( $response[1] == 'valid' ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function privileged_permission_callback() {
|
||||
return current_user_can( 'manage_options' );
|
||||
}
|
||||
|
||||
/**
|
||||
* For calls that Akismet.com makes to the site to clear outdated alert codes, use the API key for authorization.
|
||||
*/
|
||||
public static function remote_call_permission_callback( $request ) {
|
||||
$local_key = Akismet::get_api_key();
|
||||
|
||||
return $local_key && ( strtolower( $request->get_param( 'key' ) ) === strtolower( $local_key ) );
|
||||
}
|
||||
|
||||
public static function sanitize_interval( $interval, $request, $param ) {
|
||||
$interval = trim( $interval );
|
||||
|
||||
$valid_intervals = array( '60-days', '6-months', 'all', );
|
||||
|
||||
if ( ! in_array( $interval, $valid_intervals ) ) {
|
||||
$interval = 'all';
|
||||
}
|
||||
|
||||
return $interval;
|
||||
}
|
||||
|
||||
public static function sanitize_key( $key, $request, $param ) {
|
||||
return trim( $key );
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Akismet
|
||||
*/
|
||||
class Akismet_Widget extends WP_Widget {
|
||||
|
||||
function __construct() {
|
||||
load_plugin_textdomain( 'akismet' );
|
||||
|
||||
parent::__construct(
|
||||
'akismet_widget',
|
||||
__( 'Akismet Widget' , 'akismet'),
|
||||
array( 'description' => __( 'Display the number of spam comments Akismet has caught' , 'akismet') )
|
||||
);
|
||||
|
||||
if ( is_active_widget( false, false, $this->id_base ) ) {
|
||||
add_action( 'wp_head', array( $this, 'css' ) );
|
||||
}
|
||||
}
|
||||
|
||||
function css() {
|
||||
?>
|
||||
|
||||
<style type="text/css">
|
||||
.a-stats {
|
||||
width: auto;
|
||||
}
|
||||
.a-stats a {
|
||||
background: #7CA821;
|
||||
background-image:-moz-linear-gradient(0% 100% 90deg,#5F8E14,#7CA821);
|
||||
background-image:-webkit-gradient(linear,0% 0,0% 100%,from(#7CA821),to(#5F8E14));
|
||||
border: 1px solid #5F8E14;
|
||||
border-radius:3px;
|
||||
color: #CFEA93;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-weight: normal;
|
||||
height: 100%;
|
||||
-moz-border-radius:3px;
|
||||
padding: 7px 0 8px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
-webkit-border-radius:3px;
|
||||
width: 100%;
|
||||
}
|
||||
.a-stats a:hover {
|
||||
text-decoration: none;
|
||||
background-image:-moz-linear-gradient(0% 100% 90deg,#6F9C1B,#659417);
|
||||
background-image:-webkit-gradient(linear,0% 0,0% 100%,from(#659417),to(#6F9C1B));
|
||||
}
|
||||
.a-stats .count {
|
||||
color: #FFF;
|
||||
display: block;
|
||||
font-size: 15px;
|
||||
line-height: 16px;
|
||||
padding: 0 13px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
function form( $instance ) {
|
||||
if ( $instance && isset( $instance['title'] ) ) {
|
||||
$title = $instance['title'];
|
||||
}
|
||||
else {
|
||||
$title = __( 'Spam Blocked' , 'akismet' );
|
||||
}
|
||||
?>
|
||||
|
||||
<p>
|
||||
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:' , 'akismet'); ?></label>
|
||||
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
|
||||
</p>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
function update( $new_instance, $old_instance ) {
|
||||
$instance['title'] = strip_tags( $new_instance['title'] );
|
||||
return $instance;
|
||||
}
|
||||
|
||||
function widget( $args, $instance ) {
|
||||
$count = get_option( 'akismet_spam_count' );
|
||||
|
||||
if ( ! isset( $instance['title'] ) ) {
|
||||
$instance['title'] = __( 'Spam Blocked' , 'akismet' );
|
||||
}
|
||||
|
||||
echo $args['before_widget'];
|
||||
if ( ! empty( $instance['title'] ) ) {
|
||||
echo $args['before_title'];
|
||||
echo esc_html( $instance['title'] );
|
||||
echo $args['after_title'];
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="a-stats">
|
||||
<a href="https://akismet.com" target="_blank" title=""><?php printf( _n( '<strong class="count">%1$s spam</strong> blocked by <strong>Akismet</strong>', '<strong class="count">%1$s spam</strong> blocked by <strong>Akismet</strong>', $count , 'akismet'), number_format_i18n( $count ) ); ?></a>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
echo $args['after_widget'];
|
||||
}
|
||||
}
|
||||
|
||||
function akismet_register_widgets() {
|
||||
register_widget( 'Akismet_Widget' );
|
||||
}
|
||||
|
||||
add_action( 'widgets_init', 'akismet_register_widgets' );
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,2 +0,0 @@
|
||||
<?php
|
||||
# Silence is golden.
|
||||
@@ -1,86 +0,0 @@
|
||||
=== Akismet Anti-Spam ===
|
||||
Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eoigal, cfinke, automattic, jgs, procifer, stephdau
|
||||
Tags: akismet, comments, spam, antispam, anti-spam, anti spam, comment moderation, comment spam, contact form spam, spam comments
|
||||
Requires at least: 4.6
|
||||
Tested up to: 5.4
|
||||
Stable tag: 4.1.6
|
||||
License: GPLv2 or later
|
||||
|
||||
Akismet checks your comments and contact form submissions against our global database of spam to protect you and your site from malicious content.
|
||||
|
||||
== Description ==
|
||||
|
||||
Akismet checks your comments and contact form submissions against our global database of spam to prevent your site from publishing malicious content. You can review the comment spam it catches on your blog's "Comments" admin screen.
|
||||
|
||||
Major features in Akismet include:
|
||||
|
||||
* Automatically checks all comments and filters out the ones that look like spam.
|
||||
* Each comment has a status history, so you can easily see which comments were caught or cleared by Akismet and which were spammed or unspammed by a moderator.
|
||||
* URLs are shown in the comment body to reveal hidden or misleading links.
|
||||
* Moderators can see the number of approved comments for each user.
|
||||
* A discard feature that outright blocks the worst spam, saving you disk space and speeding up your site.
|
||||
|
||||
PS: You'll be prompted to get an Akismet.com API key to use it, once activated. Keys are free for personal blogs; paid subscriptions are available for businesses and commercial sites.
|
||||
|
||||
== Installation ==
|
||||
|
||||
Upload the Akismet plugin to your blog, activate it, and then enter your Akismet.com API key.
|
||||
|
||||
1, 2, 3: You're done!
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 4.1.6 =
|
||||
*Release Date - 4 June 2020*
|
||||
|
||||
* Disable "Check for Spam" button until the page is loaded to avoid errors with clicking through to queue recheck endpoint directly.
|
||||
* Add filter "akismet_enable_mshots" to allow disabling screenshot popups on the edit comments admin page.
|
||||
|
||||
= 4.1.5 =
|
||||
*Release Date - 29 April 2020*
|
||||
|
||||
* Based on user feedback, we have dropped the in-admin notice explaining the availability of the "privacy notice" option in the AKismet settings screen. The option itself is available, but after displaying the notice for the last 2 years, it is now considered a known fact.
|
||||
* Updated the "Requires at least" to WP 4.6, based on recommendations from https://wp-info.org/tools/checkplugini18n.php?slug=akismet
|
||||
* Moved older changelog entries to a separate file to keep the size of this readme reasonable, also based on recommendations from https://wp-info.org/tools/checkplugini18n.php?slug=akismet
|
||||
|
||||
= 4.1.4 =
|
||||
*Release Date - 17 March 2020*
|
||||
|
||||
* Only redirect to the Akismet setup screen upon plugin activation if the plugin was activated manually from within the plugin-related screens, to help users with non-standard install workflows, like WP-CLI.
|
||||
* Update the layout of the initial setup screen to be more readable on small screens.
|
||||
* If no API key has been entered, don't run code that expects an API key.
|
||||
* Improve the readability of the comment history entries.
|
||||
* Don't modify the comment form HTML if no API key has been set.
|
||||
|
||||
= 4.1.3 =
|
||||
*Release Date - 31 October 2019*
|
||||
|
||||
* Prevented an attacker from being able to cause a user to unknowingly recheck their Pending comments for spam.
|
||||
* Improved compatibility with Jetpack 7.7+.
|
||||
* Updated the plugin activation page to use consistent language and markup.
|
||||
* Redirecting users to the Akismet connnection/settings screen upon plugin activation, in an effort to make it easier for people to get setup.
|
||||
|
||||
= 4.1.2 =
|
||||
*Release Date - 14 May 2019*
|
||||
|
||||
* Fixed a conflict between the Akismet setup banner and other plugin notices.
|
||||
* Reduced the number of API requests made by the plugin when attempting to verify the API key.
|
||||
* Include additional data in the pingback pre-check API request to help make the stats more accurate.
|
||||
* Fixed a bug that was enabling the "Check for Spam" button when no comments were eligible to be checked.
|
||||
* Improved Akismet's AMP compatibility.
|
||||
|
||||
= 4.1.1 =
|
||||
*Release Date - 31 January 2019*
|
||||
|
||||
* Fixed the "Setup Akismet" notice so it resizes responsively.
|
||||
* Only highlight the "Save Changes" button in the Akismet config when changes have been made.
|
||||
* The count of comments in your spam queue shown on the dashboard show now always be up-to-date.
|
||||
|
||||
= 4.1 =
|
||||
*Release Date - 12 November 2018*
|
||||
|
||||
* Added a WP-CLI method for retrieving stats.
|
||||
* Hooked into the new "Personal Data Eraser" functionality from WordPress 4.9.6.
|
||||
* Added functionality to clear outdated alerts from Akismet.com.
|
||||
|
||||
For older changelog entries, please see the [additional changelog.txt file](https://plugins.svn.wordpress.org/akismet/trunk/changelog.txt) delivered with the plugin.
|
||||
@@ -1,8 +0,0 @@
|
||||
<div class="akismet-box">
|
||||
<?php Akismet::view( 'title' ); ?>
|
||||
<?php Akismet::view( 'setup' );?>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="akismet-box">
|
||||
<?php Akismet::view( 'enter' );?>
|
||||
</div>
|
||||
@@ -1,242 +0,0 @@
|
||||
<div id="akismet-plugin-container">
|
||||
<div class="akismet-masthead">
|
||||
<div class="akismet-masthead__inside-container">
|
||||
<div class="akismet-masthead__logo-container">
|
||||
<img class="akismet-masthead__logo" src="<?php echo esc_url( plugins_url( '../_inc/img/logo-full-2x.png', __FILE__ ) ); ?>" alt="Akismet" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="akismet-lower">
|
||||
<?php if ( Akismet::get_api_key() ) { ?>
|
||||
<?php Akismet_Admin::display_status(); ?>
|
||||
<?php } ?>
|
||||
<?php if ( ! empty( $notices ) ) { ?>
|
||||
<?php foreach ( $notices as $notice ) { ?>
|
||||
<?php Akismet::view( 'notice', $notice ); ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php if ( $stat_totals && isset( $stat_totals['all'] ) && (int) $stat_totals['all']->spam > 0 ) : ?>
|
||||
<div class="akismet-card">
|
||||
<div class="akismet-section-header">
|
||||
<div class="akismet-section-header__label">
|
||||
<span><?php esc_html_e( 'Statistics' , 'akismet'); ?></span>
|
||||
</div>
|
||||
<div class="akismet-section-header__actions">
|
||||
<a href="<?php echo esc_url( Akismet_Admin::get_page_url( 'stats' ) ); ?>">
|
||||
<?php esc_html_e( 'Detailed Stats' , 'akismet');?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="akismet-new-snapshot">
|
||||
<iframe allowtransparency="true" scrolling="no" frameborder="0" style="width: 100%; height: 220px; overflow: hidden;" src="<?php printf( '//akismet.com/web/1.0/snapshot.php?blog=%s&api_key=%s&height=200&locale=%s', urlencode( get_option( 'home' ) ), Akismet::get_api_key(), get_locale() );?>"></iframe>
|
||||
<ul>
|
||||
<li>
|
||||
<h3><?php esc_html_e( 'Past six months' , 'akismet');?></h3>
|
||||
<span><?php echo number_format( $stat_totals['6-months']->spam );?></span>
|
||||
<?php echo esc_html( _n( 'Spam blocked', 'Spam blocked', $stat_totals['6-months']->spam, 'akismet' ) ); ?>
|
||||
</li>
|
||||
<li>
|
||||
<h3><?php esc_html_e( 'All time' , 'akismet');?></h3>
|
||||
<span><?php echo number_format( $stat_totals['all']->spam );?></span>
|
||||
<?php echo esc_html( _n( 'Spam blocked', 'Spam blocked', $stat_totals['all']->spam, 'akismet' ) ); ?>
|
||||
</li>
|
||||
<li>
|
||||
<h3><?php esc_html_e( 'Accuracy' , 'akismet');?></h3>
|
||||
<span><?php echo floatval( $stat_totals['all']->accuracy ); ?>%</span>
|
||||
<?php printf( _n( '%s missed spam', '%s missed spam', $stat_totals['all']->missed_spam, 'akismet' ), number_format( $stat_totals['all']->missed_spam ) ); ?>
|
||||
|
|
||||
<?php printf( _n( '%s false positive', '%s false positives', $stat_totals['all']->false_positives, 'akismet' ), number_format( $stat_totals['all']->false_positives ) ); ?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
|
||||
<?php if ( $akismet_user ):?>
|
||||
<div class="akismet-card">
|
||||
<div class="akismet-section-header">
|
||||
<div class="akismet-section-header__label">
|
||||
<span><?php esc_html_e( 'Settings' , 'akismet'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inside">
|
||||
<form action="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>" method="POST">
|
||||
<table cellspacing="0" class="akismet-settings">
|
||||
<tbody>
|
||||
<?php if ( ! Akismet::predefined_api_key() ) { ?>
|
||||
<tr>
|
||||
<th class="akismet-api-key" width="10%" align="left" scope="row"><?php esc_html_e('API Key', 'akismet');?></th>
|
||||
<td width="5%"/>
|
||||
<td align="left">
|
||||
<span class="api-key"><input id="key" name="key" type="text" size="15" value="<?php echo esc_attr( get_option('wordpress_api_key') ); ?>" class="<?php echo esc_attr( 'regular-text code ' . $akismet_user->status ); ?>"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<?php if ( isset( $_GET['ssl_status'] ) ) { ?>
|
||||
<tr>
|
||||
<th align="left" scope="row"><?php esc_html_e( 'SSL Status', 'akismet' ); ?></th>
|
||||
<td></td>
|
||||
<td align="left">
|
||||
<p>
|
||||
<?php
|
||||
|
||||
if ( ! wp_http_supports( array( 'ssl' ) ) ) {
|
||||
?><b><?php esc_html_e( 'Disabled.', 'akismet' ); ?></b> <?php esc_html_e( 'Your Web server cannot make SSL requests; contact your Web host and ask them to add support for SSL requests.', 'akismet' ); ?><?php
|
||||
}
|
||||
else {
|
||||
$ssl_disabled = get_option( 'akismet_ssl_disabled' );
|
||||
|
||||
if ( $ssl_disabled ) {
|
||||
?><b><?php esc_html_e( 'Temporarily disabled.', 'akismet' ); ?></b> <?php esc_html_e( 'Akismet encountered a problem with a previous SSL request and disabled it temporarily. It will begin using SSL for requests again shortly.', 'akismet' ); ?><?php
|
||||
}
|
||||
else {
|
||||
?><b><?php esc_html_e( 'Enabled.', 'akismet' ); ?></b> <?php esc_html_e( 'All systems functional.', 'akismet' ); ?><?php
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<tr>
|
||||
<th align="left" scope="row"><?php esc_html_e('Comments', 'akismet');?></th>
|
||||
<td></td>
|
||||
<td align="left">
|
||||
<p>
|
||||
<label for="akismet_show_user_comments_approved" title="<?php esc_attr_e( 'Show approved comments' , 'akismet'); ?>">
|
||||
<input
|
||||
name="akismet_show_user_comments_approved"
|
||||
id="akismet_show_user_comments_approved"
|
||||
value="1"
|
||||
type="checkbox"
|
||||
<?php
|
||||
|
||||
// If the option isn't set, or if it's enabled ('1'), or if it was enabled a long time ago ('true'), check the checkbox.
|
||||
checked( true, ( in_array( get_option( 'akismet_show_user_comments_approved' ), array( false, '1', 'true' ), true ) ) );
|
||||
|
||||
?>
|
||||
/>
|
||||
<?php esc_html_e( 'Show the number of approved comments beside each comment author', 'akismet' ); ?>
|
||||
</label>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="strictness" align="left" scope="row"><?php esc_html_e('Strictness', 'akismet'); ?></th>
|
||||
<td></td>
|
||||
<td align="left">
|
||||
<fieldset><legend class="screen-reader-text"><span><?php esc_html_e('Akismet anti-spam strictness', 'akismet'); ?></span></legend>
|
||||
<p><label for="akismet_strictness_1"><input type="radio" name="akismet_strictness" id="akismet_strictness_1" value="1" <?php checked('1', get_option('akismet_strictness')); ?> /> <?php esc_html_e('Silently discard the worst and most pervasive spam so I never see it.', 'akismet'); ?></label></p>
|
||||
<p><label for="akismet_strictness_0"><input type="radio" name="akismet_strictness" id="akismet_strictness_0" value="0" <?php checked('0', get_option('akismet_strictness')); ?> /> <?php esc_html_e('Always put spam in the Spam folder for review.', 'akismet'); ?></label></p>
|
||||
</fieldset>
|
||||
<span class="akismet-note"><strong><?php esc_html_e('Note:', 'akismet');?></strong>
|
||||
<?php
|
||||
|
||||
$delete_interval = max( 1, intval( apply_filters( 'akismet_delete_comment_interval', 15 ) ) );
|
||||
|
||||
printf(
|
||||
_n(
|
||||
'Spam in the <a href="%1$s">spam folder</a> older than 1 day is deleted automatically.',
|
||||
'Spam in the <a href="%1$s">spam folder</a> older than %2$d days is deleted automatically.',
|
||||
$delete_interval,
|
||||
'akismet'
|
||||
),
|
||||
admin_url( 'edit-comments.php?comment_status=spam' ),
|
||||
$delete_interval
|
||||
);
|
||||
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="comment-form-privacy-notice" align="left" scope="row"><?php esc_html_e('Privacy', 'akismet'); ?></th>
|
||||
<td></td>
|
||||
<td align="left">
|
||||
<fieldset><legend class="screen-reader-text"><span><?php esc_html_e('Akismet privacy notice', 'akismet'); ?></span></legend>
|
||||
<p><label for="akismet_comment_form_privacy_notice_display"><input type="radio" name="akismet_comment_form_privacy_notice" id="akismet_comment_form_privacy_notice_display" value="display" <?php checked('display', get_option('akismet_comment_form_privacy_notice')); ?> /> <?php esc_html_e('Display a privacy notice under your comment forms.', 'akismet'); ?></label></p>
|
||||
<p><label for="akismet_comment_form_privacy_notice_hide"><input type="radio" name="akismet_comment_form_privacy_notice" id="akismet_comment_form_privacy_notice_hide" value="hide" <?php echo in_array( get_option('akismet_comment_form_privacy_notice'), array('display', 'hide') ) ? checked('hide', get_option('akismet_comment_form_privacy_notice'), false) : 'checked="checked"'; ?> /> <?php esc_html_e('Do not display privacy notice.', 'akismet'); ?></label></p>
|
||||
</fieldset>
|
||||
<span class="akismet-note"><?php esc_html_e( 'To help your site with transparency under privacy laws like the GDPR, Akismet can display a notice to your users under your comment forms. This feature is disabled by default, however, you can turn it on above.', 'akismet' );?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="akismet-card-actions">
|
||||
<?php if ( ! Akismet::predefined_api_key() ) { ?>
|
||||
<div id="delete-action">
|
||||
<a class="submitdelete deletion" href="<?php echo esc_url( Akismet_Admin::get_page_url( 'delete_key' ) ); ?>"><?php esc_html_e('Disconnect this account', 'akismet'); ?></a>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php wp_nonce_field(Akismet_Admin::NONCE) ?>
|
||||
<div id="publishing-action">
|
||||
<input type="hidden" name="action" value="enter-key">
|
||||
<input type="submit" name="submit" id="submit" class="akismet-button akismet-could-be-primary" value="<?php esc_attr_e('Save Changes', 'akismet');?>">
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ( ! Akismet::predefined_api_key() ) { ?>
|
||||
<div class="akismet-card">
|
||||
<div class="akismet-section-header">
|
||||
<div class="akismet-section-header__label">
|
||||
<span><?php esc_html_e( 'Account' , 'akismet'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inside">
|
||||
<table cellspacing="0" border="0" class="akismet-settings">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row" align="left"><?php esc_html_e( 'Subscription Type' , 'akismet');?></th>
|
||||
<td width="5%"/>
|
||||
<td align="left">
|
||||
<p><?php echo esc_html( $akismet_user->account_name ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row" align="left"><?php esc_html_e( 'Status' , 'akismet');?></th>
|
||||
<td width="5%"/>
|
||||
<td align="left">
|
||||
<p><?php
|
||||
if ( 'cancelled' == $akismet_user->status ) :
|
||||
esc_html_e( 'Cancelled', 'akismet' );
|
||||
elseif ( 'suspended' == $akismet_user->status ) :
|
||||
esc_html_e( 'Suspended', 'akismet' );
|
||||
elseif ( 'missing' == $akismet_user->status ) :
|
||||
esc_html_e( 'Missing', 'akismet' );
|
||||
elseif ( 'no-sub' == $akismet_user->status ) :
|
||||
esc_html_e( 'No Subscription Found', 'akismet' );
|
||||
else :
|
||||
esc_html_e( 'Active', 'akismet' );
|
||||
endif; ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if ( $akismet_user->next_billing_date ) : ?>
|
||||
<tr>
|
||||
<th scope="row" align="left"><?php esc_html_e( 'Next Billing Date' , 'akismet');?></th>
|
||||
<td width="5%"/>
|
||||
<td align="left">
|
||||
<p><?php echo date( 'F j, Y', $akismet_user->next_billing_date ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="akismet-card-actions">
|
||||
<div id="publishing-action">
|
||||
<?php Akismet::view( 'get', array( 'text' => ( $akismet_user->account_type == 'free-api-key' && $akismet_user->status == 'active' ? __( 'Upgrade' , 'akismet') : __( 'Change' , 'akismet') ), 'redirect' => 'upgrade' ) ); ?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
//phpcs:disable VariableAnalysis
|
||||
// There are "undefined" variables here because they're defined in the code that includes this file as a template.
|
||||
|
||||
?>
|
||||
<div class="akismet-box">
|
||||
<?php Akismet::view( 'title' ); ?>
|
||||
<div class="akismet-jp-connect">
|
||||
<h3><?php esc_html_e( 'Connect with Jetpack', 'akismet' ); ?></h3><?php
|
||||
if ( in_array( $akismet_user->status, array( 'no-sub', 'missing' ) ) ) {?>
|
||||
<p><?php esc_html_e( 'Use your Jetpack connection to set up Akismet.', 'akismet' ); ?></p>
|
||||
<form name="akismet_activate" id="akismet_activate" action="https://akismet.com/get/" method="post" class="akismet-right" target="_blank">
|
||||
<input type="hidden" name="passback_url" value="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>"/>
|
||||
<input type="hidden" name="blog" value="<?php echo esc_url( get_option( 'home' ) ); ?>"/>
|
||||
<input type="hidden" name="auto-connect" value="<?php echo esc_attr( $akismet_user->ID ); ?>"/>
|
||||
<input type="hidden" name="redirect" value="plugin-signup"/>
|
||||
<input type="submit" class="akismet-button akismet-is-primary" value="<?php esc_attr_e( 'Connect with Jetpack' , 'akismet' ); ?>"/>
|
||||
</form>
|
||||
<?php echo get_avatar( $akismet_user->user_email, null, null, null, array( 'class' => 'akismet-jetpack-gravatar' ) ); ?>
|
||||
<p><?php
|
||||
/* translators: %s is the WordPress.com username */
|
||||
echo sprintf( esc_html( __( 'You are connected as %s.', 'akismet' ) ), '<b>' . esc_html( $akismet_user->user_login ) . '</b>' ); ?><br /><span class="akismet-jetpack-email"><?php echo esc_html( $akismet_user->user_email ); ?></span></p>
|
||||
<?php } elseif ( $akismet_user->status == 'cancelled' ) { ?>
|
||||
<p><?php esc_html_e( 'Use your Jetpack connection to set up Akismet.', 'akismet' ); ?></p>
|
||||
<form name="akismet_activate" id="akismet_activate" action="https://akismet.com/get/" method="post" class="akismet-right" target="_blank">
|
||||
<input type="hidden" name="passback_url" value="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>"/>
|
||||
<input type="hidden" name="blog" value="<?php echo esc_url( get_option( 'home' ) ); ?>"/>
|
||||
<input type="hidden" name="user_id" value="<?php echo esc_attr( $akismet_user->ID ); ?>"/>
|
||||
<input type="hidden" name="redirect" value="upgrade"/>
|
||||
<input type="submit" class="akismet-button akismet-is-primary" value="<?php esc_attr_e( 'Connect with Jetpack' , 'akismet' ); ?>"/>
|
||||
</form>
|
||||
<?php echo get_avatar( $akismet_user->user_email, null, null, null, array( 'class' => 'akismet-jetpack-gravatar' ) ); ?>
|
||||
<p><?php
|
||||
/* translators: %s is the WordPress.com email address */
|
||||
echo esc_html( sprintf( __( 'Your subscription for %s is cancelled.' , 'akismet' ), $akismet_user->user_email ) ); ?><br /><span class="akismet-jetpack-email"><?php echo esc_html( $akismet_user->user_email ); ?></span></p>
|
||||
<?php } elseif ( $akismet_user->status == 'suspended' ) { ?>
|
||||
<div class="akismet-right">
|
||||
<p><a href="https://akismet.com/contact" class="akismet-button akismet-is-primary"><?php esc_html_e( 'Contact Akismet support' , 'akismet' ); ?></a></p>
|
||||
</div>
|
||||
<p>
|
||||
<span class="akismet-alert-text"><?php
|
||||
/* translators: %s is the WordPress.com email address */
|
||||
echo esc_html( sprintf( __( 'Your subscription for %s is suspended.' , 'akismet' ), $akismet_user->user_email ) ); ?></span>
|
||||
<?php esc_html_e( 'No worries! Get in touch and we’ll sort this out.', 'akismet' ); ?>
|
||||
</p>
|
||||
<?php } else { // ask do they want to use akismet account found using jetpack wpcom connection ?>
|
||||
<p><?php esc_html_e( 'Use your Jetpack connection to set up Akismet.', 'akismet' ); ?></p>
|
||||
<form name="akismet_use_wpcom_key" action="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>" method="post" id="akismet-activate" class="akismet-right">
|
||||
<input type="hidden" name="key" value="<?php echo esc_attr( $akismet_user->api_key );?>"/>
|
||||
<input type="hidden" name="action" value="enter-key">
|
||||
<?php wp_nonce_field( Akismet_Admin::NONCE ) ?>
|
||||
<input type="submit" class="akismet-button akismet-is-primary" value="<?php esc_attr_e( 'Connect with Jetpack' , 'akismet' ); ?>"/>
|
||||
</form>
|
||||
<?php echo get_avatar( $akismet_user->user_email, null, null, null, array( 'class' => 'akismet-jetpack-gravatar' ) ); ?>
|
||||
<p><?php
|
||||
/* translators: %s is the WordPress.com username */
|
||||
echo sprintf( esc_html( __( 'You are connected as %s.', 'akismet' ) ), '<b>' . esc_html( $akismet_user->user_login ) . '</b>' ); ?><br /><span class="akismet-jetpack-email"><?php echo esc_html( $akismet_user->user_email ); ?></span></p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="akismet-ak-connect">
|
||||
<?php Akismet::view( 'setup' );?>
|
||||
</div>
|
||||
<div class="centered akismet-toggles">
|
||||
<a href="#" class="toggle-jp-connect"><?php esc_html_e( 'Connect with Jetpack' ); ?></a>
|
||||
<a href="#" class="toggle-ak-connect"><?php esc_html_e( 'Set up a different account' ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="akismet-box">
|
||||
<?php Akismet::view( 'enter' );?>
|
||||
</div>
|
||||
@@ -1,13 +0,0 @@
|
||||
<div class="akismet-enter-api-key-box centered">
|
||||
<a href="#"><?php esc_html_e( 'Manually enter an API key' ); ?></a>
|
||||
<div class="enter-api-key">
|
||||
<form action="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>" method="post">
|
||||
<?php wp_nonce_field( Akismet_Admin::NONCE ) ?>
|
||||
<input type="hidden" name="action" value="enter-key">
|
||||
<p style="width: 100%; display: flex; flex-wrap: nowrap; box-sizing: border-box;">
|
||||
<input id="key" name="key" type="text" size="15" value="" placeholder="<?php esc_attr_e( 'Enter your API key' , 'akismet' ); ?>" class="regular-text code" style="flex-grow: 1; margin-right: 1rem;">
|
||||
<input type="submit" name="submit" id="submit" class="akismet-button" value="<?php esc_attr_e( 'Connect with API key', 'akismet' );?>">
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
//phpcs:disable VariableAnalysis
|
||||
// There are "undefined" variables here because they're defined in the code that includes this file as a template.
|
||||
|
||||
?>
|
||||
<form name="akismet_activate" action="https://akismet.com/get/" method="POST" target="_blank">
|
||||
<input type="hidden" name="passback_url" value="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>"/>
|
||||
<input type="hidden" name="blog" value="<?php echo esc_url( get_option( 'home' ) ); ?>"/>
|
||||
<input type="hidden" name="redirect" value="<?php echo isset( $redirect ) ? $redirect : 'plugin-signup'; ?>"/>
|
||||
<input type="submit" class="<?php echo isset( $classes ) && count( $classes ) > 0 ? implode( ' ', $classes ) : 'akismet-button';?>" value="<?php echo esc_attr( $text ); ?>"/>
|
||||
</form>
|
||||
@@ -1,141 +0,0 @@
|
||||
<?php
|
||||
|
||||
//phpcs:disable VariableAnalysis
|
||||
// There are "undefined" variables here because they're defined in the code that includes this file as a template.
|
||||
|
||||
?>
|
||||
<?php if ( $type == 'plugin' ) :?>
|
||||
<div class="updated" id="akismet_setup_prompt">
|
||||
<form name="akismet_activate" action="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>" method="POST">
|
||||
<div class="akismet_activate">
|
||||
<div class="aa_a">A</div>
|
||||
<div class="aa_button_container">
|
||||
<div class="aa_button_border">
|
||||
<input type="submit" class="aa_button" value="<?php esc_attr_e( 'Set up your Akismet account', 'akismet' ); ?>" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="aa_description"><?php _e('<strong>Almost done</strong> - configure Akismet and say goodbye to spam', 'akismet');?></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php elseif ( $type == 'spam-check' ) :?>
|
||||
<div class="notice notice-warning">
|
||||
<p><strong><?php esc_html_e( 'Akismet has detected a problem.', 'akismet' );?></strong></p>
|
||||
<p><?php esc_html_e( 'Some comments have not yet been checked for spam by Akismet. They have been temporarily held for moderation and will automatically be rechecked later.', 'akismet' ); ?></p>
|
||||
<?php if ( $link_text ) { ?>
|
||||
<p><?php echo $link_text; ?></p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php elseif ( $type == 'alert' ) :?>
|
||||
<div class='error'>
|
||||
<p><strong><?php printf( esc_html__( 'Akismet Error Code: %s', 'akismet' ), $code ); ?></strong></p>
|
||||
<p><?php echo esc_html( $msg ); ?></p>
|
||||
<p><?php
|
||||
|
||||
/* translators: the placeholder is a clickable URL that leads to more information regarding an error code. */
|
||||
printf( esc_html__( 'For more information: %s' , 'akismet'), '<a href="https://akismet.com/errors/' . $code . '">https://akismet.com/errors/' . $code . '</a>' );
|
||||
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'notice' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status failed"><?php echo $notice_header; ?></h3>
|
||||
<p class="akismet-description">
|
||||
<?php echo $notice_text; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'missing-functions' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status failed"><?php esc_html_e('Network functions are disabled.', 'akismet'); ?></h3>
|
||||
<p class="akismet-description"><?php printf( __('Your web host or server administrator has disabled PHP’s <code>gethostbynamel</code> function. <strong>Akismet cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet’s system requirements</a>.', 'akismet'), 'https://blog.akismet.com/akismet-hosting-faq/'); ?></p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'servers-be-down' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status failed"><?php esc_html_e("Your site can’t connect to the Akismet servers.", 'akismet'); ?></h3>
|
||||
<p class="akismet-description"><?php printf( __('Your firewall may be blocking Akismet from connecting to its API. Please contact your host and refer to <a href="%s" target="_blank">our guide about firewalls</a>.', 'akismet'), 'https://blog.akismet.com/akismet-hosting-faq/'); ?></p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'active-dunning' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status"><?php esc_html_e("Please update your payment information.", 'akismet'); ?></h3>
|
||||
<p class="akismet-description"><?php printf( __('We cannot process your payment. Please <a href="%s" target="_blank">update your payment details</a>.', 'akismet'), 'https://akismet.com/account/'); ?></p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'cancelled' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status"><?php esc_html_e("Your Akismet plan has been cancelled.", 'akismet'); ?></h3>
|
||||
<p class="akismet-description"><?php printf( __('Please visit your <a href="%s" target="_blank">Akismet account page</a> to reactivate your subscription.', 'akismet'), 'https://akismet.com/account/'); ?></p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'suspended' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status failed"><?php esc_html_e("Your Akismet subscription is suspended.", 'akismet'); ?></h3>
|
||||
<p class="akismet-description"><?php printf( __('Please contact <a href="%s" target="_blank">Akismet support</a> for assistance.', 'akismet'), 'https://akismet.com/contact/'); ?></p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'active-notice' && $time_saved ) :?>
|
||||
<div class="akismet-alert akismet-active">
|
||||
<h3 class="akismet-key-status"><?php echo esc_html( $time_saved ); ?></h3>
|
||||
<p class="akismet-description"><?php printf( __('You can help us fight spam and upgrade your account by <a href="%s" target="_blank">contributing a token amount</a>.', 'akismet'), 'https://akismet.com/account/upgrade/'); ?></p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'missing' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status failed"><?php esc_html_e( 'There is a problem with your API key.', 'akismet'); ?></h3>
|
||||
<p class="akismet-description"><?php printf( __('Please contact <a href="%s" target="_blank">Akismet support</a> for assistance.', 'akismet'), 'https://akismet.com/contact/'); ?></p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'no-sub' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status failed"><?php esc_html_e( 'You don’t have an Akismet plan.', 'akismet'); ?></h3>
|
||||
<p class="akismet-description">
|
||||
<?php printf( __( 'In 2012, Akismet began using subscription plans for all accounts (even free ones). A plan has not been assigned to your account, and we’d appreciate it if you’d <a href="%s" target="_blank">sign into your account</a> and choose one.', 'akismet'), 'https://akismet.com/account/upgrade/' ); ?>
|
||||
<br /><br />
|
||||
<?php printf( __( 'Please <a href="%s" target="_blank">contact our support team</a> with any questions.', 'akismet' ), 'https://akismet.com/contact/' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'new-key-valid' ) :
|
||||
global $wpdb;
|
||||
|
||||
$check_pending_link = false;
|
||||
|
||||
$at_least_one_comment_in_moderation = !! $wpdb->get_var( "SELECT comment_ID FROM {$wpdb->comments} WHERE comment_approved = '0' LIMIT 1" );
|
||||
|
||||
if ( $at_least_one_comment_in_moderation) {
|
||||
$check_pending_link = 'edit-comments.php?akismet_recheck=' . wp_create_nonce( 'akismet_recheck' );
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="akismet-alert akismet-active">
|
||||
<h3 class="akismet-key-status"><?php esc_html_e( 'Akismet is now protecting your site from spam. Happy blogging!', 'akismet' ); ?></h3>
|
||||
<?php if ( $check_pending_link ) { ?>
|
||||
<p class="akismet-description"><?php printf( __( 'Would you like to <a href="%s">check pending comments</a>?', 'akismet' ), esc_url( $check_pending_link ) ); ?></p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php elseif ( $type == 'new-key-invalid' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status"><?php esc_html_e( 'The key you entered is invalid. Please double-check it.' , 'akismet'); ?></h3>
|
||||
</div>
|
||||
<?php elseif ( $type == 'existing-key-invalid' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status"><?php esc_html_e( 'Your API key is no longer valid. Please enter a new key or contact support@akismet.com.' , 'akismet'); ?></h3>
|
||||
</div>
|
||||
<?php elseif ( $type == 'new-key-failed' ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<h3 class="akismet-key-status"><?php esc_html_e( 'The API key you entered could not be verified.' , 'akismet'); ?></h3>
|
||||
<p class="akismet-description"><?php printf( __('The connection to akismet.com could not be established. Please refer to <a href="%s" target="_blank">our guide about firewalls</a> and check your server configuration.', 'akismet'), 'https://blog.akismet.com/akismet-hosting-faq/'); ?></p>
|
||||
</div>
|
||||
<?php elseif ( $type == 'limit-reached' && in_array( $level, array( 'yellow', 'red' ) ) ) :?>
|
||||
<div class="akismet-alert akismet-critical">
|
||||
<?php if ( $level == 'yellow' ): ?>
|
||||
<h3 class="akismet-key-status failed"><?php esc_html_e( 'You’re using your Akismet key on more sites than your Pro subscription allows.', 'akismet' ); ?></h3>
|
||||
<p class="akismet-description">
|
||||
<?php printf( __( 'Your Pro subscription allows the use of Akismet on only one site. Please <a href="%s" target="_blank">purchase additional Pro subscriptions</a> or upgrade to an Enterprise subscription that allows the use of Akismet on unlimited sites.', 'akismet' ), 'https://docs.akismet.com/billing/add-more-sites/' ); ?>
|
||||
<br /><br />
|
||||
<?php printf( __( 'Please <a href="%s" target="_blank">contact our support team</a> with any questions.', 'akismet' ), 'https://akismet.com/contact/'); ?>
|
||||
</p>
|
||||
<?php elseif ( $level == 'red' ): ?>
|
||||
<h3 class="akismet-key-status failed"><?php esc_html_e( 'You’re using Akismet on far too many sites for your Pro subscription.', 'akismet' ); ?></h3>
|
||||
<p class="akismet-description">
|
||||
<?php printf( __( 'To continue your service, <a href="%s" target="_blank">upgrade to an Enterprise subscription</a>, which covers an unlimited number of sites.', 'akismet'), 'https://akismet.com/account/upgrade/' ); ?>
|
||||
<br /><br />
|
||||
<?php printf( __( 'Please <a href="%s" target="_blank">contact our support team</a> with any questions.', 'akismet' ), 'https://akismet.com/contact/'); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
@@ -1,11 +0,0 @@
|
||||
<div class="akismet-box">
|
||||
<h2><?php esc_html_e( 'Manual Configuration', 'akismet' ); ?></h2>
|
||||
<p>
|
||||
<?php
|
||||
|
||||
/* translators: %s is the wp-config.php file */
|
||||
echo sprintf( esc_html__( 'An Akismet API key has been defined in the %s file for this site.', 'akismet' ), '<code>wp-config.php</code>' );
|
||||
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
@@ -1,4 +0,0 @@
|
||||
<div class="akismet-setup-instructions">
|
||||
<p><?php esc_html_e( 'Set up your Akismet account to enable spam filtering on this site.', 'akismet' ); ?></p>
|
||||
<?php Akismet::view( 'get', array( 'text' => __( 'Set up your Akismet account' , 'akismet' ), 'classes' => array( 'akismet-button', 'akismet-is-primary' ) ) ); ?>
|
||||
</div>
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
//phpcs:disable VariableAnalysis
|
||||
// There are "undefined" variables here because they're defined in the code that includes this file as a template.
|
||||
|
||||
?>
|
||||
<div id="akismet-plugin-container">
|
||||
<div class="akismet-masthead">
|
||||
<div class="akismet-masthead__inside-container">
|
||||
<div class="akismet-masthead__logo-container">
|
||||
<img class="akismet-masthead__logo" src="<?php echo esc_url( plugins_url( '../_inc/img/logo-full-2x.png', __FILE__ ) ); ?>" alt="Akismet" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="akismet-lower">
|
||||
<?php Akismet_Admin::display_status();?>
|
||||
<div class="akismet-boxes">
|
||||
<?php
|
||||
|
||||
if ( Akismet::predefined_api_key() ) {
|
||||
Akismet::view( 'predefined' );
|
||||
} elseif ( $akismet_user && in_array( $akismet_user->status, array( 'active', 'active-dunning', 'no-sub', 'missing', 'cancelled', 'suspended' ) ) ) {
|
||||
Akismet::view( 'connect-jp', compact( 'akismet_user' ) );
|
||||
} else {
|
||||
Akismet::view( 'activate' );
|
||||
}
|
||||
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,11 +0,0 @@
|
||||
<div id="akismet-plugin-container">
|
||||
<div class="akismet-masthead">
|
||||
<div class="akismet-masthead__inside-container">
|
||||
<a href="<?php echo esc_url( Akismet_Admin::get_page_url() );?>" class="akismet-right"><?php esc_html_e( 'Akismet Settings' , 'akismet' ); ?></a>
|
||||
<div class="akismet-masthead__logo-container">
|
||||
<img class="akismet-masthead__logo" src="<?php echo esc_url( plugins_url( '../_inc/img/logo-full-2x.png', __FILE__ ) ); ?>" alt="Akismet" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<iframe src="<?php echo esc_url( sprintf( '//akismet.com/web/1.0/user-stats.php?blog=%s&api_key=%s&locale=%s', urlencode( get_option( 'home' ) ), Akismet::get_api_key(), get_locale() ) ); ?>" width="100%" height="2500px" frameborder="0"></iframe>
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="centered akismet-box-header">
|
||||
<h2><?php esc_html_e( 'Eliminate spam from your site', 'akismet' ); ?></h2>
|
||||
</div>
|
||||
@@ -1,214 +0,0 @@
|
||||
<?php
|
||||
|
||||
global $wpcom_api_key, $akismet_api_host, $akismet_api_port;
|
||||
|
||||
$wpcom_api_key = defined( 'WPCOM_API_KEY' ) ? constant( 'WPCOM_API_KEY' ) : '';
|
||||
$akismet_api_host = Akismet::get_api_key() . '.rest.akismet.com';
|
||||
$akismet_api_port = 80;
|
||||
|
||||
function akismet_test_mode() {
|
||||
return Akismet::is_test_mode();
|
||||
}
|
||||
|
||||
function akismet_http_post( $request, $host, $path, $port = 80, $ip = null ) {
|
||||
$path = str_replace( '/1.1/', '', $path );
|
||||
|
||||
return Akismet::http_post( $request, $path, $ip );
|
||||
}
|
||||
|
||||
function akismet_microtime() {
|
||||
return Akismet::_get_microtime();
|
||||
}
|
||||
|
||||
function akismet_delete_old() {
|
||||
return Akismet::delete_old_comments();
|
||||
}
|
||||
|
||||
function akismet_delete_old_metadata() {
|
||||
return Akismet::delete_old_comments_meta();
|
||||
}
|
||||
|
||||
function akismet_check_db_comment( $id, $recheck_reason = 'recheck_queue' ) {
|
||||
return Akismet::check_db_comment( $id, $recheck_reason );
|
||||
}
|
||||
|
||||
function akismet_rightnow() {
|
||||
if ( !class_exists( 'Akismet_Admin' ) )
|
||||
return false;
|
||||
|
||||
return Akismet_Admin::rightnow_stats();
|
||||
}
|
||||
|
||||
function akismet_admin_init() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_version_warning() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_load_js_and_css() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_nonce_field( $action = -1 ) {
|
||||
return wp_nonce_field( $action );
|
||||
}
|
||||
function akismet_plugin_action_links( $links, $file ) {
|
||||
return Akismet_Admin::plugin_action_links( $links, $file );
|
||||
}
|
||||
function akismet_conf() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_stats_display() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_stats() {
|
||||
return Akismet_Admin::dashboard_stats();
|
||||
}
|
||||
function akismet_admin_warnings() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_comment_row_action( $a, $comment ) {
|
||||
return Akismet_Admin::comment_row_actions( $a, $comment );
|
||||
}
|
||||
function akismet_comment_status_meta_box( $comment ) {
|
||||
return Akismet_Admin::comment_status_meta_box( $comment );
|
||||
}
|
||||
function akismet_comments_columns( $columns ) {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
|
||||
return $columns;
|
||||
}
|
||||
function akismet_comment_column_row( $column, $comment_id ) {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_text_add_link_callback( $m ) {
|
||||
return Akismet_Admin::text_add_link_callback( $m );
|
||||
}
|
||||
function akismet_text_add_link_class( $comment_text ) {
|
||||
return Akismet_Admin::text_add_link_class( $comment_text );
|
||||
}
|
||||
function akismet_check_for_spam_button( $comment_status ) {
|
||||
return Akismet_Admin::check_for_spam_button( $comment_status );
|
||||
}
|
||||
function akismet_submit_nonspam_comment( $comment_id ) {
|
||||
return Akismet::submit_nonspam_comment( $comment_id );
|
||||
}
|
||||
function akismet_submit_spam_comment( $comment_id ) {
|
||||
return Akismet::submit_spam_comment( $comment_id );
|
||||
}
|
||||
function akismet_transition_comment_status( $new_status, $old_status, $comment ) {
|
||||
return Akismet::transition_comment_status( $new_status, $old_status, $comment );
|
||||
}
|
||||
function akismet_spam_count( $type = false ) {
|
||||
return Akismet_Admin::get_spam_count( $type );
|
||||
}
|
||||
function akismet_recheck_queue() {
|
||||
return Akismet_Admin::recheck_queue();
|
||||
}
|
||||
function akismet_remove_comment_author_url() {
|
||||
return Akismet_Admin::remove_comment_author_url();
|
||||
}
|
||||
function akismet_add_comment_author_url() {
|
||||
return Akismet_Admin::add_comment_author_url();
|
||||
}
|
||||
function akismet_check_server_connectivity() {
|
||||
return Akismet_Admin::check_server_connectivity();
|
||||
}
|
||||
function akismet_get_server_connectivity( $cache_timeout = 86400 ) {
|
||||
return Akismet_Admin::get_server_connectivity( $cache_timeout );
|
||||
}
|
||||
function akismet_server_connectivity_ok() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
|
||||
return true;
|
||||
}
|
||||
function akismet_admin_menu() {
|
||||
return Akismet_Admin::admin_menu();
|
||||
}
|
||||
function akismet_load_menu() {
|
||||
return Akismet_Admin::load_menu();
|
||||
}
|
||||
function akismet_init() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_get_key() {
|
||||
return Akismet::get_api_key();
|
||||
}
|
||||
function akismet_check_key_status( $key, $ip = null ) {
|
||||
return Akismet::check_key_status( $key, $ip );
|
||||
}
|
||||
function akismet_update_alert( $response ) {
|
||||
return Akismet::update_alert( $response );
|
||||
}
|
||||
function akismet_verify_key( $key, $ip = null ) {
|
||||
return Akismet::verify_key( $key, $ip );
|
||||
}
|
||||
function akismet_get_user_roles( $user_id ) {
|
||||
return Akismet::get_user_roles( $user_id );
|
||||
}
|
||||
function akismet_result_spam( $approved ) {
|
||||
return Akismet::comment_is_spam( $approved );
|
||||
}
|
||||
function akismet_result_hold( $approved ) {
|
||||
return Akismet::comment_needs_moderation( $approved );
|
||||
}
|
||||
function akismet_get_user_comments_approved( $user_id, $comment_author_email, $comment_author, $comment_author_url ) {
|
||||
return Akismet::get_user_comments_approved( $user_id, $comment_author_email, $comment_author, $comment_author_url );
|
||||
}
|
||||
function akismet_update_comment_history( $comment_id, $message, $event = null ) {
|
||||
return Akismet::update_comment_history( $comment_id, $message, $event );
|
||||
}
|
||||
function akismet_get_comment_history( $comment_id ) {
|
||||
return Akismet::get_comment_history( $comment_id );
|
||||
}
|
||||
function akismet_cmp_time( $a, $b ) {
|
||||
return Akismet::_cmp_time( $a, $b );
|
||||
}
|
||||
function akismet_auto_check_update_meta( $id, $comment ) {
|
||||
return Akismet::auto_check_update_meta( $id, $comment );
|
||||
}
|
||||
function akismet_auto_check_comment( $commentdata ) {
|
||||
return Akismet::auto_check_comment( $commentdata );
|
||||
}
|
||||
function akismet_get_ip_address() {
|
||||
return Akismet::get_ip_address();
|
||||
}
|
||||
function akismet_cron_recheck() {
|
||||
return Akismet::cron_recheck();
|
||||
}
|
||||
function akismet_add_comment_nonce( $post_id ) {
|
||||
return Akismet::add_comment_nonce( $post_id );
|
||||
}
|
||||
function akismet_fix_scheduled_recheck() {
|
||||
return Akismet::fix_scheduled_recheck();
|
||||
}
|
||||
function akismet_spam_comments() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
|
||||
return array();
|
||||
}
|
||||
function akismet_spam_totals() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
|
||||
return array();
|
||||
}
|
||||
function akismet_manage_page() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_caught() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function redirect_old_akismet_urls() {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
}
|
||||
function akismet_kill_proxy_check( $option ) {
|
||||
_deprecated_function( __FUNCTION__, '3.0' );
|
||||
|
||||
return 0;
|
||||
}
|
||||
function akismet_pingback_forwarded_for( $r, $url ) {
|
||||
// This functionality is now in core.
|
||||
return false;
|
||||
}
|
||||
function akismet_pre_check_pingback( $method ) {
|
||||
return Akismet::pre_check_pingback( $method );
|
||||
}
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Do not modify the files in this folder.
|
||||
*/
|
||||
@@ -1,410 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* Inits the admin dashboard side of things.
|
||||
* Main admin file which loads all settings panels and sets up admin menus.
|
||||
*/
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Admin_Init
|
||||
{
|
||||
var $main_menu_page;
|
||||
var $dashboard_menu;
|
||||
var $settings_menu;
|
||||
var $user_accounts_menu;
|
||||
var $user_login_menu;
|
||||
var $user_registration_menu;
|
||||
var $db_security_menu;
|
||||
var $filesystem_menu;
|
||||
var $blacklist_menu;
|
||||
var $firewall_menu;
|
||||
var $brute_force_menu;
|
||||
var $maintenance_menu;
|
||||
var $spam_menu;
|
||||
var $filescan_menu;
|
||||
var $misc_menu;
|
||||
|
||||
function __construct() {
|
||||
//This class is only initialized if is_admin() is true
|
||||
$this->admin_includes();
|
||||
add_action('admin_menu', array(&$this, 'create_admin_menus'));
|
||||
//handle CSV download
|
||||
add_action('admin_init', array(&$this, 'aiowps_csv_download'));
|
||||
|
||||
//make sure we are on our plugin's menu pages
|
||||
if (isset($_GET['page']) && strpos($_GET['page'], AIOWPSEC_MENU_SLUG_PREFIX) !== false) {
|
||||
add_action('admin_print_scripts', array(&$this, 'admin_menu_page_scripts'));
|
||||
add_action('admin_print_styles', array(&$this, 'admin_menu_page_styles'));
|
||||
add_action('init', array(&$this, 'init_hook_handler_for_admin_side'));
|
||||
}
|
||||
}
|
||||
|
||||
private function aiowps_output_csv($items, $export_keys, $filename='data.csv') {
|
||||
header("Content-Type: text/csv; charset=utf-8");
|
||||
header("Content-Disposition: attachment; filename=".$filename);
|
||||
header("Pragma: no-cache");
|
||||
header("Expires: 0");
|
||||
$output = fopen('php://output', 'w'); //open output stream
|
||||
|
||||
fputcsv($output, $export_keys); //let's put column names first
|
||||
|
||||
foreach ($items as $item) {
|
||||
unset($csv_line);
|
||||
foreach ($export_keys as $key => $value) {
|
||||
if (isset($item[$key])) {
|
||||
$csv_line[] = $item[$key];
|
||||
}
|
||||
}
|
||||
fputcsv($output, $csv_line);
|
||||
}
|
||||
}
|
||||
|
||||
function aiowps_csv_download() {
|
||||
global $aio_wp_security;
|
||||
if (isset($_POST['aiowpsec_export_acct_activity_logs_to_csv'])) { //Export account activity logs
|
||||
$nonce = $_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-export-acct-activity-logs-to-csv-nonce')) {
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for export account activity logs to CSV!", 4);
|
||||
die(__('Nonce check failed for export account activity logs to CSV!', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
include_once 'wp-security-list-acct-activity.php';
|
||||
$acct_activity_list = new AIOWPSecurity_List_Account_Activity();
|
||||
$acct_activity_list->prepare_items(true);
|
||||
//Let's build a list of items we want to export and give them readable names
|
||||
$export_keys = array(
|
||||
'user_id' => 'User ID',
|
||||
'user_login' => 'Username',
|
||||
'login_date' => 'Login Date',
|
||||
'logout_date' => 'Logout Date',
|
||||
'login_ip' => 'IP'
|
||||
);
|
||||
$this->aiowps_output_csv($acct_activity_list->items, $export_keys, 'account_activity_logs.csv');
|
||||
exit();
|
||||
}
|
||||
if (isset($_POST['aiowps_export_failed_login_records_to_csv'])) {//Export failed login records
|
||||
$nonce = $_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-export-failed-login-records-to-csv-nonce')) {
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for export failed login records to CSV!", 4);
|
||||
die(__('Nonce check failed for export failed login records to CSV!', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
include_once 'wp-security-list-login-fails.php';
|
||||
$failed_login_list = new AIOWPSecurity_List_Login_Failed_Attempts();
|
||||
$failed_login_list->prepare_items(true);
|
||||
$export_keys = array(
|
||||
'login_attempt_ip' => 'Login IP Range',
|
||||
'user_id' => 'User ID',
|
||||
'user_login' => 'Username',
|
||||
'failed_login_date' => 'Date',
|
||||
);
|
||||
$this->aiowps_output_csv($failed_login_list->items, $export_keys, 'failed_login_records.csv');
|
||||
exit();
|
||||
}
|
||||
if (isset($_POST['aiowps_export_404_event_logs_to_csv'])) {//Export 404 event logs
|
||||
$nonce = $_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-export-404-event-logs-to-csv-nonce')) {
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for export 404 event logs to CSV!", 4);
|
||||
die(__('Nonce check failed for export 404 event logs to CSV!', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
include_once 'wp-security-list-404.php'; //For rendering the AIOWPSecurity_List_Table in tab1
|
||||
$event_list_404 = new AIOWPSecurity_List_404(); //For rendering the AIOWPSecurity_List_Table in tab1
|
||||
$event_list_404->prepare_items(true);
|
||||
$export_keys = array(
|
||||
'id' => 'Id',
|
||||
'event_type' => 'Event Type',
|
||||
'ip_or_host' => 'IP Address',
|
||||
'url' => 'Attempted URL',
|
||||
'referer_info' => 'Referer',
|
||||
'event_date' => 'Date',
|
||||
'status' => 'Lock Status',
|
||||
);
|
||||
$this->aiowps_output_csv($event_list_404->items, $export_keys, '404_event_logs.csv');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
function admin_includes()
|
||||
{
|
||||
include_once('wp-security-admin-menu.php');
|
||||
}
|
||||
|
||||
function admin_menu_page_scripts()
|
||||
{
|
||||
wp_enqueue_script('jquery');
|
||||
wp_enqueue_script('postbox');
|
||||
wp_enqueue_script('dashboard');
|
||||
wp_enqueue_script('thickbox');
|
||||
wp_enqueue_script('media-upload');
|
||||
wp_register_script('aiowpsec-admin-js', AIO_WP_SECURITY_URL. '/js/wp-security-admin-script.js', array('jquery'));
|
||||
wp_enqueue_script('aiowpsec-admin-js');
|
||||
wp_register_script('aiowpsec-pw-tool-js', AIO_WP_SECURITY_URL. '/js/password-strength-tool.js', array('jquery')); // We will enqueue this in the user acct menu class
|
||||
}
|
||||
|
||||
function admin_menu_page_styles()
|
||||
{
|
||||
wp_enqueue_style('dashboard');
|
||||
wp_enqueue_style('thickbox');
|
||||
wp_enqueue_style('global');
|
||||
wp_enqueue_style('wp-admin');
|
||||
wp_enqueue_style('aiowpsec-admin-css', AIO_WP_SECURITY_URL. '/css/wp-security-admin-styles.css');
|
||||
}
|
||||
|
||||
function init_hook_handler_for_admin_side()
|
||||
{
|
||||
$this->aiowps_media_uploader_modification();
|
||||
$this->initialize_feature_manager();
|
||||
$this->do_other_admin_side_init_tasks();
|
||||
}
|
||||
|
||||
function aiowps_media_uploader_modification()
|
||||
{
|
||||
//For changing button text inside media uploader (thickbox)
|
||||
global $pagenow;
|
||||
if ('media-upload.php' == $pagenow || 'async-upload.php' == $pagenow)
|
||||
{
|
||||
// Here we will customize the 'Insert into Post' Button text inside Thickbox
|
||||
add_filter( 'gettext', array($this, 'aiowps_media_uploader_replace_thickbox_text'), 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
function aiowps_media_uploader_replace_thickbox_text($translated_text, $text)
|
||||
{
|
||||
if ('Insert into Post' == $text)
|
||||
{
|
||||
$referer = strpos(wp_get_referer(), 'aiowpsec');
|
||||
if ($referer != '')
|
||||
{
|
||||
return ('Select File');
|
||||
}
|
||||
}
|
||||
return $translated_text;
|
||||
}
|
||||
|
||||
function initialize_feature_manager()
|
||||
{
|
||||
$aiowps_feature_mgr = new AIOWPSecurity_Feature_Item_Manager();
|
||||
$aiowps_feature_mgr->initialize_features();
|
||||
$aiowps_feature_mgr->check_and_set_feature_status();
|
||||
$aiowps_feature_mgr->calculate_total_points();
|
||||
$GLOBALS['aiowps_feature_mgr'] = $aiowps_feature_mgr;
|
||||
}
|
||||
|
||||
function do_other_admin_side_init_tasks()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
|
||||
//***New Feature improvement for Cookie Based Brute Force Protection***//
|
||||
//The old "test cookie" used to be too easy to guess because someone could just read the code and get the value.
|
||||
//So now we will drop a more secure test cookie using a 10 digit random string
|
||||
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')=='1'){
|
||||
// This code is for users who had this feature saved using an older release. This will drop the new more secure test cookie to the browser and will write it to the .htaccess file too
|
||||
$test_cookie = $aio_wp_security->configs->get_value('aiowps_cookie_brute_test');
|
||||
if(empty($test_cookie)){
|
||||
$random_suffix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10);
|
||||
$test_cookie_name = 'aiowps_cookie_test_'.$random_suffix;
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_brute_test',$test_cookie_name);
|
||||
$aio_wp_security->configs->save_config();//save the value
|
||||
AIOWPSecurity_Utility::set_cookie_value($test_cookie_name, "1");
|
||||
|
||||
//Write this new cookie to the .htaccess file
|
||||
$res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess();
|
||||
if( !$res ){
|
||||
$aio_wp_security->debug_logger->log_debug("Error writing new test cookie with random suffix to .htaccess file!",4);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//For cookie test form submission case
|
||||
if (isset($_GET['page']) && $_GET['page'] == AIOWPSEC_BRUTE_FORCE_MENU_SLUG && isset($_GET['tab']) && $_GET['tab'] == 'tab2')
|
||||
{
|
||||
global $aio_wp_security;
|
||||
if(isset($_POST['aiowps_do_cookie_test_for_bfla'])){
|
||||
$random_suffix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10);
|
||||
$test_cookie_name = 'aiowps_cookie_test_'.$random_suffix;
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_brute_test',$test_cookie_name);
|
||||
$aio_wp_security->configs->save_config();//save the value
|
||||
AIOWPSecurity_Utility::set_cookie_value($test_cookie_name, "1");
|
||||
$cur_url = "admin.php?page=".AIOWPSEC_BRUTE_FORCE_MENU_SLUG."&tab=tab2";
|
||||
$redirect_url = AIOWPSecurity_Utility::add_query_data_to_url($cur_url, 'aiowps_cookie_test', "1");
|
||||
AIOWPSecurity_Utility::redirect_to_url($redirect_url);
|
||||
}
|
||||
|
||||
if(isset($_POST['aiowps_enable_brute_force_attack_prevention']))//Enabling the BFLA feature so drop the cookie again
|
||||
{
|
||||
$brute_force_feature_secret_word = sanitize_text_field($_POST['aiowps_brute_force_secret_word']);
|
||||
if(empty($brute_force_feature_secret_word)){
|
||||
$brute_force_feature_secret_word = "aiowps_secret";
|
||||
}
|
||||
AIOWPSecurity_Utility::set_cookie_value($brute_force_feature_secret_word, "1");
|
||||
}
|
||||
|
||||
if(isset($_REQUEST['aiowps_cookie_test']))
|
||||
{
|
||||
$test_cookie = $aio_wp_security->configs->get_value('aiowps_cookie_brute_test');
|
||||
$cookie_val = AIOWPSecurity_Utility::get_cookie_value($test_cookie);
|
||||
if(empty($cookie_val))
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_test_success','');
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_test_success','1');
|
||||
}
|
||||
$aio_wp_security->configs->save_config();//save the value
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_POST['aiowps_save_wp_config']))//the wp-config backup operation
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-save-wp-config-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on wp_config file save!",4);
|
||||
die("Nonce check failed on wp_config file save!");
|
||||
}
|
||||
$wp_config_path = AIOWPSecurity_Utility_File::get_wp_config_file_path();
|
||||
$result = AIOWPSecurity_Utility_File::backup_and_rename_wp_config($wp_config_path); //Backup the wp_config.php file
|
||||
AIOWPSecurity_Utility_File::download_a_file_option1($wp_config_path, "wp-config-backup.txt");
|
||||
}
|
||||
|
||||
//Handle export settings
|
||||
if(isset($_POST['aiowps_export_settings']))//Do form submission tasks
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-export-settings-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on export AIOWPS settings!",4);
|
||||
die("Nonce check failed on export AIOWPS settings!");
|
||||
}
|
||||
$config_data = get_option('aio_wp_security_configs');
|
||||
$output = json_encode($config_data);
|
||||
AIOWPSecurity_Utility_File::download_content_to_a_file($output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function create_admin_menus()
|
||||
{
|
||||
$menu_icon_url = AIO_WP_SECURITY_URL.'/images/plugin-icon.png';
|
||||
$this->main_menu_page = add_menu_page(__('WP Security', 'all-in-one-wp-security-and-firewall'), __('WP Security', 'all-in-one-wp-security-and-firewall'), AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_MAIN_MENU_SLUG , array(&$this, 'handle_dashboard_menu_rendering'), $menu_icon_url);
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Dashboard', 'all-in-one-wp-security-and-firewall'), __('Dashboard', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_MAIN_MENU_SLUG, array(&$this, 'handle_dashboard_menu_rendering'));
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Settings', 'all-in-one-wp-security-and-firewall'), __('Settings', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_SETTINGS_MENU_SLUG, array(&$this, 'handle_settings_menu_rendering'));
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('User Accounts', 'all-in-one-wp-security-and-firewall'), __('User Accounts', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_USER_ACCOUNTS_MENU_SLUG, array(&$this, 'handle_user_accounts_menu_rendering'));
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('User Login', 'all-in-one-wp-security-and-firewall'), __('User Login', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_USER_LOGIN_MENU_SLUG, array(&$this, 'handle_user_login_menu_rendering'));
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('User Registration', 'all-in-one-wp-security-and-firewall'), __('User Registration', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_USER_REGISTRATION_MENU_SLUG, array(&$this, 'handle_user_registration_menu_rendering'));
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Database Security', 'all-in-one-wp-security-and-firewall'), __('Database Security', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_DB_SEC_MENU_SLUG, array(&$this, 'handle_database_menu_rendering'));
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && get_current_blog_id() != 1){
|
||||
//Suppress the Filesystem Security menu if site is a multi site AND not the main site
|
||||
}else{
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Filesystem Security', 'all-in-one-wp-security-and-firewall'), __('Filesystem Security', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_FILESYSTEM_MENU_SLUG, array(&$this, 'handle_filesystem_menu_rendering'));
|
||||
}
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && get_current_blog_id() != 1){
|
||||
//Suppress the Blacklist Manager menu if site is a multi site AND not the main site
|
||||
}else{
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Blacklist Manager', 'all-in-one-wp-security-and-firewall'), __('Blacklist Manager', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_BLACKLIST_MENU_SLUG, array(&$this, 'handle_blacklist_menu_rendering'));
|
||||
}
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && get_current_blog_id() != 1){
|
||||
//Suppress the firewall menu if site is a multi site AND not the main site
|
||||
}else{
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Firewall', 'all-in-one-wp-security-and-firewall'), __('Firewall', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_FIREWALL_MENU_SLUG, array(&$this, 'handle_firewall_menu_rendering'));
|
||||
}
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Brute Force', 'all-in-one-wp-security-and-firewall'), __('Brute Force', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_BRUTE_FORCE_MENU_SLUG, array(&$this, 'handle_brute_force_menu_rendering'));
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('SPAM Prevention', 'all-in-one-wp-security-and-firewall'), __('SPAM Prevention', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_SPAM_MENU_SLUG, array(&$this, 'handle_spam_menu_rendering'));
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && get_current_blog_id() != 1){
|
||||
//Suppress the filescan menu if site is a multi site AND not the main site
|
||||
}else{
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Scanner', 'all-in-one-wp-security-and-firewall'), __('Scanner', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_FILESCAN_MENU_SLUG, array(&$this, 'handle_filescan_menu_rendering'));
|
||||
}
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Maintenance', 'all-in-one-wp-security-and-firewall'), __('Maintenance', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_MAINTENANCE_MENU_SLUG, array(&$this, 'handle_maintenance_menu_rendering'));
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, __('Miscellaneous', 'all-in-one-wp-security-and-firewall'), __('Miscellaneous', 'all-in-one-wp-security-and-firewall') , AIOWPSEC_MANAGEMENT_PERMISSION, AIOWPSEC_MISC_MENU_SLUG, array(&$this, 'handle_misc_menu_rendering'));
|
||||
do_action('aiowpsecurity_admin_menu_created');
|
||||
}
|
||||
|
||||
function handle_dashboard_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-dashboard-menu.php');
|
||||
$this->dashboard_menu = new AIOWPSecurity_Dashboard_Menu();
|
||||
}
|
||||
|
||||
function handle_settings_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-settings-menu.php');
|
||||
$this->settings_menu = new AIOWPSecurity_Settings_Menu();
|
||||
|
||||
}
|
||||
|
||||
function handle_user_accounts_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-user-accounts-menu.php');
|
||||
$this->user_accounts_menu = new AIOWPSecurity_User_Accounts_Menu();
|
||||
}
|
||||
|
||||
function handle_user_login_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-user-login-menu.php');
|
||||
$this->user_login_menu = new AIOWPSecurity_User_Login_Menu();
|
||||
}
|
||||
|
||||
function handle_user_registration_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-user-registration-menu.php');
|
||||
$this->user_registration_menu = new AIOWPSecurity_User_Registration_Menu();
|
||||
}
|
||||
|
||||
function handle_database_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-database-menu.php');
|
||||
$this->db_security_menu = new AIOWPSecurity_Database_Menu();
|
||||
}
|
||||
|
||||
function handle_filesystem_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-filesystem-menu.php');
|
||||
$this->filesystem_menu = new AIOWPSecurity_Filesystem_Menu();
|
||||
}
|
||||
|
||||
function handle_blacklist_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-blacklist-menu.php');
|
||||
$this->blacklist_menu = new AIOWPSecurity_Blacklist_Menu();
|
||||
}
|
||||
|
||||
function handle_firewall_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-firewall-menu.php');
|
||||
$this->firewall_menu = new AIOWPSecurity_Firewall_Menu();
|
||||
}
|
||||
|
||||
function handle_brute_force_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-brute-force-menu.php');
|
||||
$this->brute_force_menu = new AIOWPSecurity_Brute_Force_Menu();
|
||||
}
|
||||
|
||||
function handle_maintenance_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-maintenance-menu.php');
|
||||
$this->maintenance_menu = new AIOWPSecurity_Maintenance_Menu();
|
||||
}
|
||||
|
||||
function handle_spam_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-spam-menu.php');
|
||||
$this->spam_menu = new AIOWPSecurity_Spam_Menu();
|
||||
}
|
||||
|
||||
function handle_filescan_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-filescan-menu.php');
|
||||
$this->filescan_menu = new AIOWPSecurity_Filescan_Menu();
|
||||
}
|
||||
|
||||
function handle_misc_menu_rendering()
|
||||
{
|
||||
include_once('wp-security-misc-options-menu.php');
|
||||
$this->misc_menu = new AIOWPSecurity_Misc_Options_Menu();
|
||||
}
|
||||
|
||||
}//End of class
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* Parent class for all admin menu classes */
|
||||
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
abstract class AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
/**
|
||||
* Shows postbox for settings menu
|
||||
*
|
||||
* @param string $id css ID for postbox
|
||||
* @param string $title title of the postbox section
|
||||
* @param string $content the content of the postbox
|
||||
**/
|
||||
function postbox_toggle($id, $title, $content)
|
||||
{
|
||||
//Always send string with translation markers in it
|
||||
?>
|
||||
<div id="<?php echo $id; ?>" class="postbox">
|
||||
<div class="handlediv" title="Click to toggle"><br /></div>
|
||||
<h3 class="hndle"><span><?php echo $title; ?></span></h3>
|
||||
<div class="inside">
|
||||
<?php echo $content; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function postbox($title, $content)
|
||||
{
|
||||
//Always send string with translation markers in it
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php echo $title; ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php echo $content; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function show_msg_settings_updated()
|
||||
{
|
||||
echo '<div id="message" class="updated fade"><p><strong>';
|
||||
_e('Settings successfully updated.','all-in-one-wp-security-and-firewall');
|
||||
echo '</strong></p></div>';
|
||||
}
|
||||
|
||||
static function show_msg_record_deleted_st()
|
||||
{
|
||||
echo '<div id="message" class="updated fade"><p><strong>';
|
||||
_e('The selected record(s) deleted successfully!','all-in-one-wp-security-and-firewall');
|
||||
echo '</strong></p></div>';
|
||||
}
|
||||
|
||||
function show_msg_updated($msg)
|
||||
{
|
||||
echo '<div id="message" class="updated fade"><p><strong>';
|
||||
echo $msg;
|
||||
echo '</strong></p></div>';
|
||||
}
|
||||
|
||||
static function show_msg_updated_st($msg)
|
||||
{
|
||||
echo '<div id="message" class="updated fade"><p><strong>';
|
||||
echo $msg;
|
||||
echo '</strong></p></div>';
|
||||
}
|
||||
|
||||
function show_msg_error($error_msg)
|
||||
{
|
||||
echo '<div id="message" class="error"><p><strong>';
|
||||
echo $error_msg;
|
||||
echo '</strong></p></div>';
|
||||
}
|
||||
|
||||
static function show_msg_error_st($error_msg)
|
||||
{
|
||||
echo '<div id="message" class="error"><p><strong>';
|
||||
echo $error_msg;
|
||||
echo '</strong></p></div>';
|
||||
}
|
||||
|
||||
function start_buffer()
|
||||
{
|
||||
ob_start();
|
||||
}
|
||||
|
||||
function end_buffer_and_collect()
|
||||
{
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $output;
|
||||
}
|
||||
|
||||
static function display_bulk_result_message()
|
||||
{
|
||||
if(isset($_GET['bulk_count'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The bulk action was successful', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
if(isset($_GET['bulk_error'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The bulk action failed', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Blacklist_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
var $menu_page_slug = AIOWPSEC_BLACKLIST_MENU_SLUG;
|
||||
|
||||
/* Specify all the tabs of this menu in the following array */
|
||||
var $menu_tabs;
|
||||
|
||||
var $menu_tabs_handler = array(
|
||||
'tab1' => 'render_tab1',
|
||||
);
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->render_menu_page();
|
||||
}
|
||||
|
||||
function set_menu_tabs()
|
||||
{
|
||||
$this->menu_tabs = array(
|
||||
'tab1' => __('Ban Users', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}
|
||||
|
||||
function get_current_tab()
|
||||
{
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
$tab = isset( $_GET['tab'] ) ? sanitize_text_field($_GET['tab']) : $tab_keys[0];
|
||||
return $tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders our tabs of this menu as nav items
|
||||
*/
|
||||
function render_menu_tabs()
|
||||
{
|
||||
$current_tab = $this->get_current_tab();
|
||||
|
||||
echo '<h2 class="nav-tab-wrapper">';
|
||||
foreach ( $this->menu_tabs as $tab_key => $tab_caption )
|
||||
{
|
||||
$active = $current_tab == $tab_key ? 'nav-tab-active' : '';
|
||||
echo '<a class="nav-tab ' . $active . '" href="?page=' . $this->menu_page_slug . '&tab=' . $tab_key . '">' . $tab_caption . '</a>';
|
||||
}
|
||||
echo '</h2>';
|
||||
}
|
||||
|
||||
/*
|
||||
* The menu rendering goes here
|
||||
*/
|
||||
function render_menu_page()
|
||||
{
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>'.__('Blacklist Manager','all-in-one-wp-security-and-firewall').'</h2>';//Interface title
|
||||
$this->set_menu_tabs();
|
||||
$tab = $this->get_current_tab();
|
||||
$this->render_menu_tabs();
|
||||
?>
|
||||
<div id="poststuff"><div id="post-body">
|
||||
<?php
|
||||
//$tab_keys = array_keys($this->menu_tabs);
|
||||
call_user_func(array(&$this, $this->menu_tabs_handler[$tab]));
|
||||
?>
|
||||
</div></div>
|
||||
</div><!-- end of wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab1()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
$result = 1;
|
||||
if (isset($_POST['aiowps_save_blacklist_settings']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-blacklist-settings-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for save blacklist settings!",4);
|
||||
die(__('Nonce check failed for save blacklist settings!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
if (isset($_POST["aiowps_enable_blacklisting"]) && empty($_POST['aiowps_banned_ip_addresses']) && empty($_POST['aiowps_banned_user_agents']))
|
||||
{
|
||||
$this->show_msg_error('You must submit at least one IP address or one User Agent value or both!','all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!empty($_POST['aiowps_banned_ip_addresses']))
|
||||
{
|
||||
$ip_addresses = $_POST['aiowps_banned_ip_addresses'];
|
||||
$ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($ip_addresses);
|
||||
$payload = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'blacklist');
|
||||
if($payload[0] == 1){
|
||||
//success case
|
||||
$result = 1;
|
||||
$list = $payload[1];
|
||||
$banned_ip_data = implode(PHP_EOL, $list);
|
||||
$aio_wp_security->configs->set_value('aiowps_banned_ip_addresses',$banned_ip_data);
|
||||
$_POST['aiowps_banned_ip_addresses'] = ''; //Clear the post variable for the banned address list
|
||||
}
|
||||
else{
|
||||
$result = -1;
|
||||
$error_msg = $payload[1][0];
|
||||
$this->show_msg_error($error_msg);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_banned_ip_addresses',''); //Clear the IP address config value
|
||||
}
|
||||
|
||||
if (!empty($_POST['aiowps_banned_user_agents']))
|
||||
{
|
||||
$result = $result * $this->validate_user_agent_list();
|
||||
}else{
|
||||
//clear the user agent list
|
||||
$aio_wp_security->configs->set_value('aiowps_banned_user_agents','');
|
||||
}
|
||||
|
||||
if ($result == 1)
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_blacklisting',isset($_POST["aiowps_enable_blacklisting"])?'1':'');
|
||||
$aio_wp_security->configs->save_config(); //Save the configuration
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
|
||||
$this->show_msg_settings_updated();
|
||||
|
||||
$write_result = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); //now let's write to the .htaccess file
|
||||
if ( !$write_result )
|
||||
{
|
||||
$this->show_msg_error(__('The plugin was unable to write to the .htaccess file. Please edit file manually.','all-in-one-wp-security-and-firewall'));
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Blacklist_Menu - The plugin was unable to write to the .htaccess file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<h2><?php _e('Ban IPs or User Agents', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('The All In One WP Security Blacklist feature gives you the option of banning certain host IP addresses or ranges and also user agents.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('This feature will deny total site access for users which have IP addresses or user agents matching those which you have configured in the settings below.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('The plugin achieves this by making appropriate modifications to your .htaccess file.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('By blocking people via the .htaccess file your are using the most secure first line of defence which denies all access to blacklisted visitors as soon as they hit your hosting server.', 'all-in-one-wp-security-and-firewall').'
|
||||
</p>';
|
||||
?>
|
||||
</div>
|
||||
<div class="aio_grey_box">
|
||||
<?php
|
||||
$addon_link = '<strong><a href="http://www.site-scanners.com/country-blocking-addon/" target="_blank">'.__('Country Blocking Addon', 'all-in-one-wp-security-and-firewall').'</a></strong>';
|
||||
$info_msg = sprintf( __('You may also be interested in our %s.', 'all-in-one-wp-security-and-firewall'), $addon_link);
|
||||
$info_msg2 = __('This addon allows you to automatically block IP addresses based on their country of origin.', 'all-in-one-wp-security-and-firewall');
|
||||
|
||||
echo '<p>'.$info_msg.
|
||||
'<br />'.$info_msg2.'</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('IP Hosts and User Agent Blacklist Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("blacklist-manager-ip-user-agent-blacklisting");
|
||||
?>
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-blacklist-settings-nonce'); ?>
|
||||
<div class="aio_orange_box">
|
||||
<p>
|
||||
<?php
|
||||
$read_link = '<a href="https://www.tipsandtricks-hq.com/wordpress-security-and-firewall-plugin#advanced_features_note" target="_blank">'.__('must read this message', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
echo sprintf(__('This feature can lock you out of admin if it doesn\'t work correctly on your site. You %s before activating this feature.', 'all-in-one-wp-security-and-firewall'), $read_link);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable IP or User Agent Blacklisting', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_blacklisting" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_blacklisting')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to enable the banning (or blacklisting) of selected IP addresses and/or user agents specified in the settings below', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enter IP Addresses:', 'all-in-one-wp-security-and-firewall')?></th>
|
||||
<td>
|
||||
<textarea name="aiowps_banned_ip_addresses" rows="5" cols="50"><?php echo ($result == -1)?htmlspecialchars($_POST['aiowps_banned_ip_addresses']):htmlspecialchars($aio_wp_security->configs->get_value('aiowps_banned_ip_addresses')); ?></textarea>
|
||||
<br />
|
||||
<span class="description"><?php _e('Enter one or more IP addresses or IP ranges.','all-in-one-wp-security-and-firewall');?></span>
|
||||
<span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php _e('More Info', 'all-in-one-wp-security-and-firewall'); ?></span></span>
|
||||
<div class="aiowps_more_info_body">
|
||||
<?php
|
||||
echo '<p class="description">'.__('Each IP address must be on a new line.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('To specify an IP range use a wildcard "*" character. Acceptable ways to use wildcards is shown in the examples below:', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example 1: 195.47.89.*', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example 2: 195.47.*.*', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example 3: 195.*.*.*', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enter User Agents:', 'all-in-one-wp-security-and-firewall')?></th>
|
||||
<td>
|
||||
<textarea name="aiowps_banned_user_agents" rows="5" cols="50"><?php echo ($result == -1)?$_POST['aiowps_banned_user_agents']:$aio_wp_security->configs->get_value('aiowps_banned_user_agents'); ?></textarea>
|
||||
<br />
|
||||
<span class="description">
|
||||
<?php _e('Enter one or more user agent strings.','all-in-one-wp-security-and-firewall');?></span>
|
||||
<span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php _e('More Info', 'all-in-one-wp-security-and-firewall'); ?></span></span>
|
||||
<div class="aiowps_more_info_body">
|
||||
<?php
|
||||
echo '<p class="description">'.__('Each user agent string must be on a new line.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example 1 - A single user agent string to block:', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">SquigglebotBot</p>';
|
||||
echo '<p class="description">'.__('Example 2 - A list of more than 1 user agent strings to block', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">baiduspider<br />SquigglebotBot<br />SurveyBot<br />VoidEYE<br />webcrawl.net<br />YottaShopping_Bot</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_save_blacklist_settings" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function validate_user_agent_list()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
@ini_set('auto_detect_line_endings', true);
|
||||
//$errors = '';
|
||||
|
||||
$submitted_agents = explode(PHP_EOL, $_POST['aiowps_banned_user_agents']);
|
||||
$agents = array();
|
||||
if (!empty($submitted_agents))
|
||||
{
|
||||
foreach ($submitted_agents as $agent)
|
||||
{
|
||||
$text = sanitize_text_field($agent);
|
||||
$agents[] = $text;
|
||||
}
|
||||
}
|
||||
|
||||
if (sizeof($agents) > 1)
|
||||
{
|
||||
sort( $agents );
|
||||
$agents = array_unique($agents, SORT_STRING);
|
||||
}
|
||||
|
||||
$banned_user_agent_data = implode(PHP_EOL, $agents);
|
||||
$aio_wp_security->configs->set_value('aiowps_banned_user_agents',$banned_user_agent_data);
|
||||
$_POST['aiowps_banned_user_agents'] = ''; //Clear the post variable for the banned address list
|
||||
return 1;
|
||||
}
|
||||
} //end class
|
||||
@@ -1,913 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Brute_Force_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
var $menu_page_slug = AIOWPSEC_BRUTE_FORCE_MENU_SLUG;
|
||||
|
||||
/* Specify all the tabs of this menu in the following array */
|
||||
var $menu_tabs;
|
||||
|
||||
var $menu_tabs_handler = array(
|
||||
'tab1' => 'render_tab1',
|
||||
'tab2' => 'render_tab2',
|
||||
'tab3' => 'render_tab3',
|
||||
'tab4' => 'render_tab4',
|
||||
'tab5' => 'render_tab5',
|
||||
);
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->render_menu_page();
|
||||
}
|
||||
|
||||
function set_menu_tabs()
|
||||
{
|
||||
$this->menu_tabs = array(
|
||||
'tab1' => __('Rename Login Page','all-in-one-wp-security-and-firewall'),
|
||||
'tab2' => __('Cookie Based Brute Force Prevention', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab3' => __('Login Captcha', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab4' => __('Login Whitelist', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab5' => __('Honeypot', 'all-in-one-wp-security-and-firewall'),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
function get_current_tab()
|
||||
{
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
$tab = isset( $_GET['tab'] ) ? sanitize_text_field($_GET['tab']) : $tab_keys[0];
|
||||
return $tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders our tabs of this menu as nav items
|
||||
*/
|
||||
function render_menu_tabs()
|
||||
{
|
||||
$current_tab = $this->get_current_tab();
|
||||
|
||||
echo '<h2 class="nav-tab-wrapper">';
|
||||
foreach ( $this->menu_tabs as $tab_key => $tab_caption )
|
||||
{
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && get_current_blog_id() != 1
|
||||
&& stristr($tab_caption, "Rename Login Page") === false && stristr($tab_caption, "Login Captcha") === false){
|
||||
//Suppress the all Brute Force menu tabs if site is a multi site AND not the main site except "rename login" and "captcha"
|
||||
}else{
|
||||
$active = $current_tab == $tab_key ? 'nav-tab-active' : '';
|
||||
echo '<a class="nav-tab ' . $active . '" href="?page=' . $this->menu_page_slug . '&tab=' . $tab_key . '">' . $tab_caption . '</a>';
|
||||
}
|
||||
}
|
||||
echo '</h2>';
|
||||
}
|
||||
|
||||
/*
|
||||
* The menu rendering goes here
|
||||
*/
|
||||
function render_menu_page()
|
||||
{
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>'.__('Brute Force','all-in-one-wp-security-and-firewall').'</h2>';//Interface title
|
||||
$this->set_menu_tabs();
|
||||
$tab = $this->get_current_tab();
|
||||
$this->render_menu_tabs();
|
||||
?>
|
||||
<div id="poststuff"><div id="post-body">
|
||||
<?php
|
||||
//$tab_keys = array_keys($this->menu_tabs);
|
||||
call_user_func(array(&$this, $this->menu_tabs_handler[$tab]));
|
||||
?>
|
||||
</div></div>
|
||||
</div><!-- end of wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab1()
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_login_page_slug = '';
|
||||
|
||||
if (get_option('permalink_structure')){
|
||||
$home_url = trailingslashit(home_url());
|
||||
}else{
|
||||
$home_url = trailingslashit(home_url()) . '?';
|
||||
}
|
||||
|
||||
if(isset($_POST['aiowps_save_rename_login_page_settings']))//Do form submission tasks
|
||||
{
|
||||
$error = '';
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-rename-login-page-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for rename login page save!",4);
|
||||
die("Nonce check failed for rename login page save!");
|
||||
}
|
||||
|
||||
if (empty($_POST['aiowps_login_page_slug']) && isset($_POST["aiowps_enable_rename_login_page"])){
|
||||
$error .= '<br />'.__('Please enter a value for your login page slug.','all-in-one-wp-security-and-firewall');
|
||||
}else if (!empty($_POST['aiowps_login_page_slug'])){
|
||||
$aiowps_login_page_slug = sanitize_text_field($_POST['aiowps_login_page_slug']);
|
||||
if($aiowps_login_page_slug == 'wp-admin'){
|
||||
$error .= '<br />'.__('You cannot use the value "wp-admin" for your login page slug.','all-in-one-wp-security-and-firewall');
|
||||
}elseif(preg_match('/[^a-z_\-0-9]/i', $aiowps_login_page_slug)){
|
||||
$error .= '<br />'.__('You must use alpha numeric characters for your login page slug.','all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
}
|
||||
|
||||
if($error){
|
||||
$this->show_msg_error(__('Attention!','all-in-one-wp-security-and-firewall').$error);
|
||||
}else{
|
||||
$htaccess_res = '';
|
||||
$cookie_feature_active = false;
|
||||
//Save all the form values to the options
|
||||
if (isset($_POST["aiowps_enable_rename_login_page"])){
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_rename_login_page', '1');
|
||||
// check if the cookie based feature was active and deactivate it and delete the directives in .htaccess
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')){
|
||||
$cookie_feature_active = true;
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_brute_force_attack_prevention', '');//deactivate cookie based feature
|
||||
}
|
||||
}else{
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_rename_login_page', '');
|
||||
}
|
||||
$aio_wp_security->configs->set_value('aiowps_login_page_slug',$aiowps_login_page_slug);
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
// if cookie based feature was active previously need to clear those rules out of .htaccess
|
||||
if($cookie_feature_active){
|
||||
$htaccess_res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); //Delete the cookie based directives
|
||||
}
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
if ($htaccess_res === false) {
|
||||
$this->show_msg_error(__('Could not delete the Cookie-based directives from the .htaccess file. Please check the file permissions.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
else {
|
||||
$this->show_msg_settings_updated();
|
||||
}
|
||||
|
||||
/** The following is a fix/workaround for the following issue:
|
||||
* https://wordpress.org/support/topic/applying-brute-force-rename-login-page-not-working/
|
||||
* ie, when saving the rename login config, the logout link does not update on the first page load after the $_POST submit to reflect the new rename login setting.
|
||||
* Added a page refresh to fix this for now until I figure out a better solution.
|
||||
*
|
||||
**/
|
||||
$cur_url = "admin.php?page=".AIOWPSEC_BRUTE_FORCE_MENU_SLUG."&tab=tab1";
|
||||
AIOWPSecurity_Utility::redirect_to_url($cur_url);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
$cookie_based_feature_url = '<a href="admin.php?page='.AIOWPSEC_BRUTE_FORCE_MENU_SLUG.'&tab=tab2" target="_blank">'.__('Cookie Based Brute Force Prevention', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
$white_list_feature_url = '<a href="admin.php?page='.AIOWPSEC_BRUTE_FORCE_MENU_SLUG.'&tab=tab4" target="_blank">'.__('Login Page White List', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
echo '<p>'.__('An effective Brute Force prevention technique is to change the default WordPress login page URL.', 'all-in-one-wp-security-and-firewall').'</p>'.
|
||||
'<p>'.__('Normally if you wanted to login to WordPress you would type your site\'s home URL followed by wp-login.php.', 'all-in-one-wp-security-and-firewall').'</p>'.
|
||||
'<p>'.__('This feature allows you to change the login URL by setting your own slug and renaming the last portion of the login URL which contains the <strong>wp-login.php</strong> to any string that you like.', 'all-in-one-wp-security-and-firewall').'</p>'.
|
||||
'<p>'.__('By doing this, malicious bots and hackers will not be able to access your login page because they will not know the correct login page URL.', 'all-in-one-wp-security-and-firewall').'</p>'.
|
||||
'<div class="aio_section_separator_1"></div>'.
|
||||
'<p>'.__('You may also be interested in the following alternative brute force prevention features:', 'all-in-one-wp-security-and-firewall').'</p>'.
|
||||
'<p>'.$cookie_based_feature_url.'</p>'.
|
||||
'<p>'.$white_list_feature_url.'</p>';
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
//Show the user the new login URL if this feature is active
|
||||
if ($aio_wp_security->configs->get_value('aiowps_enable_rename_login_page')=='1')
|
||||
{
|
||||
?>
|
||||
<div class="aio_yellow_box">
|
||||
<p><?php _e('Your WordPress login page URL has been renamed.', 'all-in-one-wp-security-and-firewall'); ?></p>
|
||||
<p><?php _e('Your current login URL is:', 'all-in-one-wp-security-and-firewall'); ?></p>
|
||||
<p><strong><?php echo $home_url.$aio_wp_security->configs->get_value('aiowps_login_page_slug'); ?></strong></p>
|
||||
<p><strong><?php _e('NOTE: If you already had the Cookie-Based Brute Force Prevention feature active, the plugin has automatically deactivated it because only one of these features can be active at any one time.', 'all-in-one-wp-security-and-firewall'); ?></strong></p>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Rename Login Page Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("bf-rename-login-page");
|
||||
?>
|
||||
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-rename-login-page-nonce'); ?>
|
||||
<div class="aio_orange_box">
|
||||
<?php
|
||||
$read_link = '<a href="https://www.tipsandtricks-hq.com/wordpress-security-and-firewall-plugin#advanced_features_note" target="_blank">'.__('must read this message', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
echo '<p>'.sprintf(__('This feature can lock you out of admin if it doesn\'t work correctly on your site. You %s before activating this feature.', 'all-in-one-wp-security-and-firewall'), $read_link).'</p>';
|
||||
echo '<p>'.__("NOTE: If you are hosting your site on WPEngine or a provider which performs server caching, you will need to ask the host support people to NOT cache your renamed login page.", "all-in-one-wp-security-and-firewall").'</p>';
|
||||
?>
|
||||
</div>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Rename Login Page Feature', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_rename_login_page" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_rename_login_page')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to enable the rename login page feature', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Login Page URL', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><code><?php echo $home_url; ?></code><input type="text" size="5" name="aiowps_login_page_slug" value="<?php echo $aio_wp_security->configs->get_value('aiowps_login_page_slug'); ?>" />
|
||||
<span class="description"><?php _e('Enter a string which will represent your secure login page slug. You are enouraged to choose something which is hard to guess and only you will remember.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_save_rename_login_page_settings" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab2()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
$error = false;
|
||||
|
||||
//Save settings for brute force cookie method
|
||||
if(isset($_POST['aiowps_apply_cookie_based_bruteforce_firewall']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-enable-cookie-based-brute-force-prevention'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on enable cookie based brute force prevention feature!",4);
|
||||
die("Nonce check failed on enable cookie based brute force prevention feature!");
|
||||
}
|
||||
|
||||
if(isset($_POST['aiowps_enable_brute_force_attack_prevention']))
|
||||
{
|
||||
$brute_force_feature_secret_word = sanitize_text_field($_POST['aiowps_brute_force_secret_word']);
|
||||
if(empty($brute_force_feature_secret_word)){
|
||||
$brute_force_feature_secret_word = "aiowps_secret";
|
||||
}else if(!ctype_alnum($brute_force_feature_secret_word)){
|
||||
$msg = '<p>'.__('Settings have not been saved - your secret word must consist only of alphanumeric characters, ie, letters and/or numbers only!', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if(filter_var($_POST['aiowps_cookie_based_brute_force_redirect_url'], FILTER_VALIDATE_URL))
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_based_brute_force_redirect_url',esc_url_raw($_POST['aiowps_cookie_based_brute_force_redirect_url']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_based_brute_force_redirect_url','http://127.0.0.1');
|
||||
}
|
||||
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_brute_force_attack_prevention','1');
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_rename_login_page',''); //Disable the Rename Login Page feature
|
||||
|
||||
if (!$error)
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_brute_force_secret_word',$brute_force_feature_secret_word);
|
||||
$msg = '<p>'.__('You have successfully enabled the cookie based brute force prevention feature', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
$msg .= '<p>'.__('From now on you will need to log into your WP Admin using the following URL:', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
$msg .= '<p><strong>'.AIOWPSEC_WP_URL.'/?'.$brute_force_feature_secret_word.'=1</strong></p>';
|
||||
$msg .= '<p>'.__('It is important that you save this URL value somewhere in case you forget it, OR,', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
$msg .= '<p>'.sprintf( __('simply remember to add a "?%s=1" to your current site URL address.', 'all-in-one-wp-security-and-firewall'), $brute_force_feature_secret_word).'</p>';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_brute_force_attack_prevention','');
|
||||
$msg = __('You have successfully saved cookie based brute force prevention feature settings.', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
|
||||
if(isset($_POST['aiowps_brute_force_attack_prevention_pw_protected_exception']))
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_brute_force_attack_prevention_pw_protected_exception','1');
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_brute_force_attack_prevention_pw_protected_exception','');
|
||||
}
|
||||
|
||||
if(isset($_POST['aiowps_brute_force_attack_prevention_ajax_exception']))
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_brute_force_attack_prevention_ajax_exception','1');
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_brute_force_attack_prevention_ajax_exception','');
|
||||
}
|
||||
|
||||
if (!$error)
|
||||
{
|
||||
$aio_wp_security->configs->save_config();//save the value
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
|
||||
$res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess();
|
||||
if ($res) {
|
||||
echo '<div id="message" class="updated fade"><p>';
|
||||
echo $msg;
|
||||
echo '</p></div>';
|
||||
}
|
||||
else {
|
||||
$this->show_msg_error(__('Could not write to the .htaccess file. Please check the file permissions.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->show_msg_error($msg);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<h2><?php _e('Brute Force Prevention Firewall Settings', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
//TODO - need to fix the following message
|
||||
echo '<p>'.__('A Brute Force Attack is when a hacker tries many combinations of usernames and passwords until they succeed in guessing the right combination.', 'all-in-one-wp-security-and-firewall').
|
||||
'<br />'.__('Due to the fact that at any one time there may be many concurrent login attempts occurring on your site via malicious automated robots, this also has a negative impact on your server\'s memory and performance.', 'all-in-one-wp-security-and-firewall').
|
||||
'<br />'.__('The features in this tab will stop the majority of Brute Force Login Attacks at the .htaccess level thus providing even better protection for your WP login page and also reducing the load on your server because the system does not have to run PHP code to process the login attempts.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
<div class="aio_yellow_box">
|
||||
<?php
|
||||
$backup_tab_link = '<a href="admin.php?page='.AIOWPSEC_SETTINGS_MENU_SLUG.'&tab=tab2" target="_blank">'.__('backup', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
$video_link = '<a href="https://www.tipsandtricks-hq.com/all-in-one-wp-security-plugin-cookie-based-brute-force-login-attack-prevention-feature-5994" target="_blank">'.__('video tutorial', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
$info_msg = sprintf( __('Even though this feature should not have any impact on your site\'s general functionality <strong>you are strongly encouraged to take a %s of your .htaccess file before proceeding</strong>.', 'all-in-one-wp-security-and-firewall'), $backup_tab_link);
|
||||
$info_msg1 = __('If this feature is not used correctly, you can get locked out of your site. A backed up .htaccess file will come in handy if that happens.', 'all-in-one-wp-security-and-firewall');
|
||||
$info_msg2 = sprintf( __('To learn more about how to use this feature please watch the following %s.', 'all-in-one-wp-security-and-firewall'), $video_link);
|
||||
$brute_force_login_feature_link = '<a href="admin.php?page='.AIOWPSEC_FIREWALL_MENU_SLUG.'&tab=tab4" target="_blank">'.__('Cookie-Based Brute Force Login Prevention', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
echo '<p>'.$info_msg.
|
||||
'<br />'.$info_msg1.
|
||||
'<br />'.$info_msg2.'</p>';
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
//Show the user the new login URL if this feature is active
|
||||
if ($aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')=='1')
|
||||
{
|
||||
?>
|
||||
<div class="aio_yellow_box">
|
||||
<p><strong><?php _e('NOTE: If you already had the Rename Login Page feature active, the plugin has automatically deactivated it because only one of these features can be active at any one time.', 'all-in-one-wp-security-and-firewall'); ?></strong></p>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Cookie Based Brute Force Login Prevention', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("firewall-enable-brute-force-attack-prevention");
|
||||
?>
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-enable-cookie-based-brute-force-prevention'); ?>
|
||||
<div class="aio_orange_box">
|
||||
<p>
|
||||
<?php _e('This feature can lock you out of admin if it doesn\'t work correctly on your site. You <a href="https://www.tipsandtricks-hq.com/wordpress-security-and-firewall-plugin#advanced_features_note" target="_blank">'.__('must read this message', 'all-in-one-wp-security-and-firewall').'</a> before activating this feature.', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
</div>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Brute Force Attack Prevention', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_brute_force_attack_prevention" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to protect your login page from Brute Force Attack.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
<span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php _e('More Info', 'all-in-one-wp-security-and-firewall'); ?></span></span>
|
||||
<div class="aiowps_more_info_body">
|
||||
<p class="description">
|
||||
<?php
|
||||
_e('This feature will deny access to your WordPress login page for all people except those who have a special cookie in their browser.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('To use this feature do the following:', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('1) Enable the checkbox.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('2) Enter a secret word consisting of alphanumeric characters which will be difficult to guess. This secret word will be useful whenever you need to know the special URL which you will use to access the login page (see point below).', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('3) You will then be provided with a special login URL. You will need to use this URL to login to your WordPress site instead of the usual login URL. NOTE: The system will deposit a special cookie in your browser which will allow you access to the WordPress administration login page.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('Any person trying to access your login page who does not have the special cookie in their browser will be automatically blocked.', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Secret Word', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><input type="text" size="40" name="aiowps_brute_force_secret_word" value="<?php echo $aio_wp_security->configs->get_value('aiowps_brute_force_secret_word'); ?>" />
|
||||
<span class="description"><?php _e('Choose a secret word consisting of alphanumeric characters which you can use to access your special URL. Your are highly encouraged to choose a word which will be difficult to guess.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Re-direct URL', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><input type="text" size="40" name="aiowps_cookie_based_brute_force_redirect_url" value="<?php echo $aio_wp_security->configs->get_value('aiowps_cookie_based_brute_force_redirect_url'); ?>" />
|
||||
<span class="description">
|
||||
<?php
|
||||
_e('Specify a URL to redirect a hacker to when they try to access your WordPress login page.', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</span>
|
||||
<span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php _e('More Info', 'all-in-one-wp-security-and-firewall'); ?></span></span>
|
||||
<div class="aiowps_more_info_body">
|
||||
<p class="description">
|
||||
<?php
|
||||
_e('The URL specified here can be any site\'s URL and does not have to be your own. For example you can be as creative as you like and send hackers to the CIA or NSA home page.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('This field will default to: http://127.0.0.1 if you do not enter a value.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('Useful Tip:', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('It\'s a good idea to not redirect attempted brute force login attempts to your site because it increases the load on your server.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('Redirecting a hacker or malicious bot back to "http://127.0.0.1" is ideal because it deflects them back to their own local host and puts the load on their server instead of yours.', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('My Site Has Posts Or Pages Which Are Password Protected', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_brute_force_attack_prevention_pw_protected_exception" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_brute_force_attack_prevention_pw_protected_exception')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you are using the native WordPress password protection feature for some or all of your blog posts or pages.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
<span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php _e('More Info', 'all-in-one-wp-security-and-firewall'); ?></span></span>
|
||||
<div class="aiowps_more_info_body">
|
||||
<p class="description">
|
||||
<?php
|
||||
_e('In the cases where you are protecting some of your posts or pages using the in-built WordPress password protection feature, a few extra lines of directives and exceptions need to be added to your .htacces file so that people trying to access pages are not automatically blocked.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('By enabling this checkbox the plugin will add the necessary rules and exceptions to your .htacces file so that people trying to access these pages are not automatically blocked.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
echo "<strong>".__('Helpful Tip:', 'all-in-one-wp-security-and-firewall')."</strong>";
|
||||
echo '<br />';
|
||||
_e('If you do not use the WordPress password protection feature for your posts or pages then it is highly recommended that you leave this checkbox disabled.', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('My Site Has a Theme or Plugins Which Use AJAX', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_brute_force_attack_prevention_ajax_exception" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_brute_force_attack_prevention_ajax_exception')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if your site uses AJAX functionality.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
<span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php _e('More Info', 'all-in-one-wp-security-and-firewall'); ?></span></span>
|
||||
<div class="aiowps_more_info_body">
|
||||
<p class="description">
|
||||
<?php
|
||||
_e('In the cases where your WordPress installation has a theme or plugins which use AJAX, a few extra lines of directives and exceptions need to be added to your .htacces file to prevent AJAX requests from being automatically blocked by the brute force prevention feature.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<br />';
|
||||
_e('By enabling this checkbox the plugin will add the necessary rules and exceptions to your .htacces file so that AJAX operations will work as expected.', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
$cookie_test_value = $aio_wp_security->configs->get_value('aiowps_cookie_test_success');
|
||||
$bfla_feature_enabled = $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention');
|
||||
if($cookie_test_value == '1' || $bfla_feature_enabled == '1')//If the cookie test is successful or if the feature is already enabled then go ahead as normal
|
||||
{
|
||||
if (isset($_REQUEST['aiowps_cookie_test']))
|
||||
{//Cookie test was just performed and the test succeded
|
||||
echo '<div class="aio_green_box"><p>';
|
||||
_e('The cookie test was successful. You can now enable this feature.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '</p></div>';
|
||||
}
|
||||
echo '<input type="submit" name="aiowps_apply_cookie_based_bruteforce_firewall" value="'.__('Save Feature Settings', 'all-in-one-wp-security-and-firewall').'" class="button-primary" />';
|
||||
}
|
||||
else
|
||||
{
|
||||
//Cookie test needs to be performed
|
||||
if(isset($_REQUEST['aiowps_cookie_test']) && $cookie_test_value != '1'){//Test failed
|
||||
echo '<div class="aio_red_box"><p>';
|
||||
_e('The cookie test failed on this server. So this feature cannot be used on this site.', 'all-in-one-wp-security-and-firewall');
|
||||
echo '</p></div>';
|
||||
}
|
||||
|
||||
echo '<div class="aio_yellow_box"><p>';
|
||||
_e("Before using this feature you are required to perform a cookie test first. This is to make sure that your browser cookie is working correctly and that you won't lock yourself out.", 'all-in-one-wp-security-and-firewall');
|
||||
echo '</p></div>';
|
||||
echo '<input type="submit" name="aiowps_do_cookie_test_for_bfla" value="'.__('Perform Cookie Test', 'all-in-one-wp-security-and-firewall').'" class="button-primary" />';
|
||||
}
|
||||
?>
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab3()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
|
||||
if(isset($_POST['aiowpsec_save_captcha_settings']))//Do form submission tasks
|
||||
{
|
||||
$error = '';
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-captcha-settings-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on captcha settings save!",4);
|
||||
die("Nonce check failed on captcha settings save!");
|
||||
}
|
||||
|
||||
|
||||
//Save all the form values to the options
|
||||
$random_20_digit_string = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(20); //Generate random 20 char string for use during captcha encode/decode
|
||||
$aio_wp_security->configs->set_value('aiowps_captcha_secret_key', $random_20_digit_string);
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_login_captcha',isset($_POST["aiowps_enable_login_captcha"])?'1':'');
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_woo_login_captcha',isset($_POST["aiowps_enable_woo_login_captcha"])?'1':'');
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_woo_register_captcha',isset($_POST["aiowps_enable_woo_register_captcha"])?'1':'');
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_woo_lostpassword_captcha',isset($_POST["aiowps_enable_woo_lostpassword_captcha"])?'1':'');
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_custom_login_captcha',isset($_POST["aiowps_enable_custom_login_captcha"])?'1':'');
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_lost_password_captcha',isset($_POST["aiowps_enable_lost_password_captcha"])?'1':'');
|
||||
|
||||
// if secret key is masked then don't resave it or the site key
|
||||
$secret_key = sanitize_text_field($_POST["aiowps_recaptcha_secret_key"]);
|
||||
if(strpos($secret_key, '********') === false){
|
||||
$aio_wp_security->configs->set_value('aiowps_recaptcha_site_key',sanitize_text_field($_POST["aiowps_recaptcha_site_key"]));
|
||||
$aio_wp_security->configs->set_value('aiowps_recaptcha_secret_key',sanitize_text_field($_POST["aiowps_recaptcha_secret_key"]));
|
||||
}
|
||||
|
||||
$aio_wp_security->configs->set_value('aiowps_default_recaptcha',isset($_POST["aiowps_default_recaptcha"])?'1':'');//Checkbox
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
|
||||
$this->show_msg_settings_updated();
|
||||
}
|
||||
|
||||
$secret_key_masked = AIOWPSecurity_Utility::mask_string($aio_wp_security->configs->get_value('aiowps_recaptcha_secret_key'));
|
||||
?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
$recaptcha_link = '<a href="https://www.google.com/recaptcha" target="_blank">Google reCAPTCHA v2</a>';
|
||||
echo sprintf('<p>'.__('This feature allows you to add a captcha form on various WordPress login pages and forms.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('Adding a captcha form on a login page or form is another effective yet simple "Brute Force" prevention technique.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('You have the option of using either %s or a plain maths captcha form.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('If you enable Google reCAPTCHA the reCAPTCHA widget will be displayed for all forms the captcha settings below.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('If Google reCAPTCHA is disabled the simple maths captcha form will apply and users will need to enter the answer to a simple mathematical question.', 'all-in-one-wp-security-and-firewall').'
|
||||
</p>', $recaptcha_link);
|
||||
?>
|
||||
</div>
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-captcha-settings-nonce'); ?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Google reCAPTCHA Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<div class="aio_orange_box">
|
||||
<p>
|
||||
<?php
|
||||
echo __('By enabling these settings the Google reCAPTCHA v2 widget will be applied by default for all forms with captcha enabled.', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Use Google reCAPTCHA as default', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_default_recaptcha" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_default_recaptcha')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to default to Google reCAPTCHA for all settings below. (If this is left unchecked, all captcha forms will revert to the plain maths captcha)', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Site Key', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><input type="text" size="50" name="aiowps_recaptcha_site_key" value="<?php echo esc_html( $aio_wp_security->configs->get_value('aiowps_recaptcha_site_key') ); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Secret Key', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><input type="text" size="50" name="aiowps_recaptcha_secret_key" value="<?php echo esc_html( $secret_key_masked ); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div></div>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Login Form Captcha Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("user-login-captcha");
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Captcha On Login Page', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_login_captcha" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_login_captcha')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to insert a captcha form on the login page', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div></div>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Lost Password Form Captcha Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("lost-password-captcha");
|
||||
?>
|
||||
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Captcha On Lost Password Page', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_lost_password_captcha" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_lost_password_captcha')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to insert a captcha form on the lost password page', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div></div>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Custom Login Form Captcha Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("custom-login-captcha");
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Captcha On Custom Login Form', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_custom_login_captcha" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_custom_login_captcha')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to insert captcha on a custom login form generated by the following WP function: wp_login_form()', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div></div>
|
||||
<?php
|
||||
// Only display woocommerce captcha settings if woo is active
|
||||
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Woocommerce Forms Captcha Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("woo-login-captcha");
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Captcha On Woocommerce Login Form', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_woo_login_captcha" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_woo_login_captcha')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to insert captcha on a Woocommerce login form', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<?php
|
||||
$aiowps_feature_mgr->output_feature_details_badge("woo-lostpassword-captcha");
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Captcha On Woocommerce Lost Password Form', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_woo_lostpassword_captcha" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_woo_lostpassword_captcha')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to insert captcha on a Woocommerce lost password form', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<?php
|
||||
$aiowps_feature_mgr->output_feature_details_badge("woo-register-captcha");
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Captcha On Woocommerce Registration Form', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_woo_register_captcha" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_woo_register_captcha')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to insert captcha on a Woocommerce registration form', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<input type="submit" name="aiowpsec_save_captcha_settings" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab4()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
$result = 1;
|
||||
$your_ip_address = AIOWPSecurity_Utility_IP::get_user_ip_address();
|
||||
if (isset($_POST['aiowps_save_whitelist_settings']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-whitelist-settings-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for save whitelist settings!",4);
|
||||
die(__('Nonce check failed for save whitelist settings!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
if (isset($_POST["aiowps_enable_whitelisting"]) && empty($_POST['aiowps_allowed_ip_addresses']))
|
||||
{
|
||||
$this->show_msg_error('You must submit at least one IP address!','all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!empty($_POST['aiowps_allowed_ip_addresses']))
|
||||
{
|
||||
$ip_addresses = $_POST['aiowps_allowed_ip_addresses'];
|
||||
$ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($ip_addresses);
|
||||
$payload = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'whitelist');
|
||||
if($payload[0] == 1){
|
||||
//success case
|
||||
$result = 1;
|
||||
$list = $payload[1];
|
||||
$whitelist_ip_data = implode(PHP_EOL, $list);
|
||||
$aio_wp_security->configs->set_value('aiowps_allowed_ip_addresses',$whitelist_ip_data);
|
||||
$_POST['aiowps_allowed_ip_addresses'] = ''; //Clear the post variable for the banned address list
|
||||
}
|
||||
else{
|
||||
$result = -1;
|
||||
$error_msg = htmlspecialchars($payload[1][0]);
|
||||
$this->show_msg_error($error_msg);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_allowed_ip_addresses',''); //Clear the IP address config value
|
||||
}
|
||||
|
||||
if ($result == 1)
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_whitelisting',isset($_POST["aiowps_enable_whitelisting"])?'1':'');
|
||||
$aio_wp_security->configs->save_config(); //Save the configuration
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
|
||||
$this->show_msg_settings_updated();
|
||||
|
||||
$write_result = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); //now let's write to the .htaccess file
|
||||
if ( !$write_result )
|
||||
{
|
||||
$this->show_msg_error(__('The plugin was unable to write to the .htaccess file. Please edit file manually.','all-in-one-wp-security-and-firewall'));
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_whitelist_Menu - The plugin was unable to write to the .htaccess file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<h2><?php _e('Login Whitelist', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('The All In One WP Security Whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('The plugin achieves this by writing the appropriate directives to your .htaccess file.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('By allowing/blocking IP addresses via the .htaccess file your are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page.', 'all-in-one-wp-security-and-firewall').'
|
||||
</p>';
|
||||
?>
|
||||
</div>
|
||||
<div class="aio_yellow_box">
|
||||
<?php
|
||||
$brute_force_login_feature_link = '<a href="admin.php?page='.AIOWPSEC_BRUTE_FORCE_MENU_SLUG.'&tab=tab2" target="_blank">Cookie-Based Brute Force Login Prevention</a>';
|
||||
$rename_login_feature_link = '<a href="admin.php?page='.AIOWPSEC_BRUTE_FORCE_MENU_SLUG.'&tab=tab1" target="_blank">'.__('Rename Login Page', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
echo '<p>'.sprintf( __('Attention: If in addition to enabling the white list feature, you also have one of the %s or %s features enabled, <strong>you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page</strong>.', 'all-in-one-wp-security-and-firewall'), $brute_force_login_feature_link, $rename_login_feature_link).'</p>
|
||||
<p>'.__('These features are NOT functionally related. Having both of them enabled on your site means you are creating 2 layers of security.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Login IP Whitelist Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("whitelist-manager-ip-login-whitelisting");
|
||||
?>
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-whitelist-settings-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable IP Whitelisting', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_whitelisting" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_whitelisting')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to enable the whitelisting of selected IP addresses specified in the settings below', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Your Current IP Address', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input size="20" name="aiowps_user_ip" type="text" value="<?php echo $your_ip_address; ?>" readonly="readonly"/>
|
||||
<span class="description"><?php _e('You can copy and paste this address in the text box below if you want to include it in your login whitelist.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enter Whitelisted IP Addresses:', 'all-in-one-wp-security-and-firewall')?></th>
|
||||
<td>
|
||||
<textarea name="aiowps_allowed_ip_addresses" rows="5" cols="50"><?php echo ($result == -1)?htmlspecialchars($_POST['aiowps_allowed_ip_addresses']):htmlspecialchars($aio_wp_security->configs->get_value('aiowps_allowed_ip_addresses')); ?></textarea>
|
||||
<br />
|
||||
<span class="description"><?php _e('Enter one or more IP addresses or IP ranges you wish to include in your whitelist. Only the addresses specified here will have access to the WordPress login page.','all-in-one-wp-security-and-firewall');?></span>
|
||||
<span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php _e('More Info', 'all-in-one-wp-security-and-firewall'); ?></span></span>
|
||||
<div class="aiowps_more_info_body">
|
||||
<?php
|
||||
echo '<p class="description"><strong>'.__('Each IP address must be on a new line.', 'all-in-one-wp-security-and-firewall').'</strong></p>';
|
||||
echo '<p class="description">'.__('To specify an IPv4 range use a wildcard "*" character. Acceptable ways to use wildcards is shown in the examples below:', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example 1: 195.47.89.*', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example 2: 195.47.*.*', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example 3: 195.*.*.*', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Or you can enter an IPv6 address (NOTE: ranges/wildcards are currently not supported for ipv6)', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example 4: 4102:0:3ea6:79fd:b:46f8:230f:bb05', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example 5: 2205:0:1ca2:810d::', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_save_whitelist_settings" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab5()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
|
||||
if(isset($_POST['aiowpsec_save_honeypot_settings']))//Do form submission tasks
|
||||
{
|
||||
$error = '';
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-honeypot-settings-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on honeypot settings save!",4);
|
||||
die("Nonce check failed on honeypot settings save!");
|
||||
}
|
||||
|
||||
//Save all the form values to the options
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_login_honeypot',isset($_POST["aiowps_enable_login_honeypot"])?'1':'');
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
|
||||
$this->show_msg_settings_updated();
|
||||
}
|
||||
?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('This feature allows you to add a special hidden "honeypot" field on the WordPress login page. This will only be visible to robots and not humans.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('Since robots usually fill in every input field from a login form, they will also submit a value for the special hidden honeypot field.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('The way honeypots work is that a hidden field is placed somewhere inside a form which only robots will submit. If that field contains a value when the form is submitted then a robot has most likely submitted the form and it is consequently dealt with.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('Therefore, if the plugin detects that this field has a value when the login form is submitted, then the robot which is attempting to login to your site will be redirected to its localhost address - http://127.0.0.1.', 'all-in-one-wp-security-and-firewall').'
|
||||
</p>';
|
||||
?>
|
||||
</div>
|
||||
<form action="" method="POST">
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Login Form Honeypot Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("login-honeypot");
|
||||
?>
|
||||
|
||||
<?php wp_nonce_field('aiowpsec-honeypot-settings-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Honeypot On Login Page', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_login_honeypot" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_login_honeypot')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to enable the honeypot feature for the login page', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div></div>
|
||||
|
||||
<input type="submit" name="aiowpsec_save_honeypot_settings" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
} //end class
|
||||
@@ -1,833 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Dashboard_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
var $dashboard_menu_page_slug = AIOWPSEC_MAIN_MENU_SLUG;
|
||||
|
||||
var $menu_tabs;
|
||||
|
||||
var $menu_tabs_handler = array(
|
||||
'tab1' => 'render_tab1',
|
||||
'tab2' => 'render_tab2',
|
||||
'tab3' => 'render_tab3',
|
||||
'tab4' => 'render_tab4',
|
||||
'tab5' => 'render_tab5',
|
||||
);
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->render_menu_page();
|
||||
}
|
||||
|
||||
function set_menu_tabs()
|
||||
{
|
||||
$this->menu_tabs = array(
|
||||
'tab1' => __('Dashboard', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab2' => __('System Info', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab3' => __('Locked IP Addresses', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab4' => __('Permanent Block List', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab5' => __('AIOWPS Logs', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}
|
||||
|
||||
function get_current_tab()
|
||||
{
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
$tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : $tab_keys[0];
|
||||
return $tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders our tabs of this menu as nav items
|
||||
*/
|
||||
function render_menu_tabs()
|
||||
{
|
||||
$current_tab = $this->get_current_tab();
|
||||
|
||||
echo '<h2 class="nav-tab-wrapper">';
|
||||
foreach ($this->menu_tabs as $tab_key => $tab_caption) {
|
||||
$active = $current_tab == $tab_key ? 'nav-tab-active' : '';
|
||||
echo '<a class="nav-tab ' . $active . '" href="?page=' . $this->dashboard_menu_page_slug . '&tab=' . $tab_key . '">' . $tab_caption . '</a>';
|
||||
}
|
||||
echo '</h2>';
|
||||
}
|
||||
|
||||
/*
|
||||
* The menu rendering goes here
|
||||
*/
|
||||
function render_menu_page()
|
||||
{
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>' . __('Dashboard', 'all-in-one-wp-security-and-firewall') . '</h2>';//Interface title
|
||||
$this->set_menu_tabs();
|
||||
$tab = $this->get_current_tab();
|
||||
$this->render_menu_tabs();
|
||||
?>
|
||||
<div id="poststuff"><div id="post-body">
|
||||
<?php
|
||||
call_user_func(array(&$this, $this->menu_tabs_handler[$tab]));
|
||||
?>
|
||||
</div></div>
|
||||
</div><!-- end of wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab1()
|
||||
{
|
||||
/** Load WordPress dashboard API */
|
||||
require_once(ABSPATH . 'wp-admin/includes/dashboard.php');
|
||||
$this->wp_dashboard_setup();
|
||||
|
||||
wp_enqueue_script( 'dashboard' );
|
||||
if ( wp_is_mobile() )
|
||||
wp_enqueue_script( 'jquery-touch-punch' );
|
||||
?>
|
||||
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
|
||||
<div id="dashboard-widgets-wrap">
|
||||
<?php $this->wp_dashboard(); ?>
|
||||
</div><!-- dashboard-widgets-wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab2()
|
||||
{
|
||||
global $wpdb;
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Site Info', 'all-in-one-wp-security-and-firewall');?></label>
|
||||
</h3>
|
||||
|
||||
<div class="inside">
|
||||
<strong><?php _e('Plugin Version', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php echo AIO_WP_SECURITY_VERSION;?></code><br/>
|
||||
<strong><?php _e('WP Version', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php echo get_bloginfo("version"); ?></code><br/>
|
||||
<strong>WPMU: </strong><code><?php echo (!defined('MULTISITE') || !MULTISITE) ? "No" : "Yes"; ?></code><br/>
|
||||
<strong>MySQL <?php _e('Version', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php echo $wpdb->db_version();?></code><br/>
|
||||
<strong>WP <?php _e('Table Prefix', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php echo $wpdb->prefix; ?></code><br/>
|
||||
<strong>PHP <?php _e('Version', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php echo phpversion(); ?></code><br/>
|
||||
<strong><?php _e('Session Save Path', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php echo ini_get("session.save_path"); ?></code><br/>
|
||||
<strong>WP URL: </strong><code><?php echo get_bloginfo('wpurl'); ?></code><br/>
|
||||
<strong><?php _e('Server Name', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php echo $_SERVER['SERVER_NAME']; ?></code><br/>
|
||||
<strong><?php _e('Cookie Domain', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php $cookieDomain = parse_url(strtolower(get_bloginfo('wpurl')));
|
||||
echo $cookieDomain['host']; ?></code><br/>
|
||||
<strong>CURL <?php _e('Library Present', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php echo (function_exists('curl_init')) ? "Yes" : "No"; ?></code><br/>
|
||||
<strong><?php _e('Debug File Write Permissions', 'all-in-one-wp-security-and-firewall');?>
|
||||
: </strong><code><?php echo (is_writable(AIO_WP_SECURITY_PATH)) ? "Writable" : "Not Writable"; ?></code><br/>
|
||||
</div>
|
||||
</div><!-- End of Site Info -->
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('PHP Info', 'all-in-one-wp-security-and-firewall');?></label>
|
||||
</h3>
|
||||
|
||||
<div class="inside">
|
||||
<strong><?php _e('PHP Version', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
: </strong><code><?php echo PHP_VERSION; ?></code><br/>
|
||||
<strong><?php _e('PHP Memory Usage', 'all-in-one-wp-security-and-firewall'); ?>:
|
||||
</strong><code><?php echo round(memory_get_usage() / 1024 / 1024, 2) . __(' MB', 'all-in-one-wp-security-and-firewall'); ?></code>
|
||||
<br/>
|
||||
<?php
|
||||
if (ini_get('memory_limit')) {
|
||||
$memory_limit = filter_var(ini_get('memory_limit'), FILTER_SANITIZE_STRING);
|
||||
} else {
|
||||
$memory_limit = __('N/A', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
?>
|
||||
<strong><?php _e('PHP Memory Limit', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
: </strong><code><?php echo $memory_limit; ?></code><br/>
|
||||
<?php
|
||||
if (ini_get('upload_max_filesize')) {
|
||||
$upload_max = filter_var(ini_get('upload_max_filesize'), FILTER_SANITIZE_STRING);
|
||||
} else {
|
||||
$upload_max = __('N/A', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
?>
|
||||
<strong><?php _e('PHP Max Upload Size', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
: </strong><code><?php echo $upload_max; ?></code><br/>
|
||||
<?php
|
||||
if (ini_get('post_max_size')) {
|
||||
$post_max = filter_var(ini_get('post_max_size'), FILTER_SANITIZE_STRING);
|
||||
} else {
|
||||
$post_max = __('N/A', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
?>
|
||||
<strong><?php _e('PHP Max Post Size', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
: </strong><code><?php echo $post_max; ?></code><br/>
|
||||
<?php
|
||||
if (ini_get('allow_url_fopen')) {
|
||||
$allow_url_fopen = __('On', 'all-in-one-wp-security-and-firewall');
|
||||
} else {
|
||||
$allow_url_fopen = __('Off', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
?>
|
||||
<strong><?php _e('PHP Allow URL fopen', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
: </strong><code><?php echo $allow_url_fopen; ?></code>
|
||||
<br/>
|
||||
<?php
|
||||
if (ini_get('allow_url_include')) {
|
||||
$allow_url_include = __('On', 'all-in-one-wp-security-and-firewall');
|
||||
} else {
|
||||
$allow_url_include = __('Off', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
?>
|
||||
<strong><?php _e('PHP Allow URL Include'); ?>
|
||||
: </strong><code><?php echo $allow_url_include; ?></code><br/>
|
||||
<?php
|
||||
if (ini_get('display_errors')) {
|
||||
$display_errors = __('On', 'all-in-one-wp-security-and-firewall');
|
||||
} else {
|
||||
$display_errors = __('Off', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
?>
|
||||
<strong><?php _e('PHP Display Errors', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
: </strong><code><?php echo $display_errors; ?></code>
|
||||
<br/>
|
||||
<?php
|
||||
if (ini_get('max_execution_time')) {
|
||||
$max_execute = filter_var(ini_get('max_execution_time'));
|
||||
} else {
|
||||
$max_execute = __('N/A', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
?>
|
||||
<strong><?php _e('PHP Max Script Execution Time', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
: </strong><code><?php echo $max_execute; ?> <?php _e('Seconds'); ?></code><br/>
|
||||
</div>
|
||||
</div><!-- End of PHP Info -->
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label
|
||||
for="title"><?php _e('Active Plugins', 'all-in-one-wp-security-and-firewall');?></label></h3>
|
||||
|
||||
<div class="inside">
|
||||
<?php
|
||||
$all_plugins = get_plugins();
|
||||
$active_plugins = get_option('active_plugins');
|
||||
//var_dump($all_plugins);
|
||||
?>
|
||||
<table class="widefat aio_spacer_10_tb">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Name', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('Version', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('Plugin URL', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
foreach ($active_plugins as $plugin_key) {
|
||||
$plugin_details = $all_plugins[$plugin_key];
|
||||
echo '<tr><td>' . $plugin_details['Name'] . '</td><td>' . $plugin_details['Version'] . '</td><td>' . $plugin_details['PluginURI'] . '</td></tr>';
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div><!-- End of Active Plugins -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab3()
|
||||
{
|
||||
global $wpdb;
|
||||
include_once 'wp-security-list-locked-ip.php'; //For rendering the AIOWPSecurity_List_Table in tab1
|
||||
$locked_ip_list = new AIOWPSecurity_List_Locked_IP(); //For rendering the AIOWPSecurity_List_Table in tab1
|
||||
|
||||
if (isset($_REQUEST['action'])) //Do list table form row action tasks
|
||||
{
|
||||
if ($_REQUEST['action'] == 'delete_blocked_ip') { //Delete link was clicked for a row in list table
|
||||
$locked_ip_list->delete_lockdown_records(strip_tags($_REQUEST['lockdown_id']));
|
||||
}
|
||||
|
||||
if ($_REQUEST['action'] == 'unlock_ip') { //Unlock link was clicked for a row in list table
|
||||
$locked_ip_list->unlock_ip_range(strip_tags($_REQUEST['lockdown_id']));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
$login_lockdown_feature_url = '<a href="admin.php?page=' . AIOWPSEC_USER_LOGIN_MENU_SLUG . '&tab=tab1" target="_blank">Login Lockdown</a>';
|
||||
echo '<p>' . __('This tab displays the list of all IP addresses which are currently temporarily locked out due to the Login Lockdown feature:', 'all-in-one-wp-security-and-firewall') . '</p>' .
|
||||
'<p>' . $login_lockdown_feature_url . '</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label
|
||||
for="title"><?php _e('Currently Locked Out IP Addresses and Ranges', 'all-in-one-wp-security-and-firewall');?></label>
|
||||
</h3>
|
||||
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Fetch, prepare, sort, and filter our data...
|
||||
$locked_ip_list->prepare_items();
|
||||
//echo "put table of locked entries here";
|
||||
?>
|
||||
<form id="tables-filter" method="get"
|
||||
onSubmit="return confirm('Are you sure you want to perform this bulk operation on the selected entries?');">
|
||||
<!-- For plugins, we also need to ensure that the form posts back to our current page -->
|
||||
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>"/>
|
||||
<?php
|
||||
if (isset($_REQUEST["tab"])) {
|
||||
echo '<input type="hidden" name="tab" value="' . esc_attr($_REQUEST["tab"]) . '" />';
|
||||
}
|
||||
?>
|
||||
<!-- Now we can render the completed list table -->
|
||||
<?php $locked_ip_list->display(); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab4()
|
||||
{
|
||||
global $wpdb;
|
||||
include_once 'wp-security-list-permanent-blocked-ip.php'; //For rendering the AIOWPSecurity_List_Table
|
||||
$blocked_ip_list = new AIOWPSecurity_List_Blocked_IP(); //For rendering the AIOWPSecurity_List_Table
|
||||
|
||||
if (isset($_REQUEST['action'])) //Do list table form row action tasks
|
||||
{
|
||||
if ($_REQUEST['action'] == 'unblock_ip') { //Unblock link was clicked for a row in list table
|
||||
$blocked_ip_list->unblock_ip_address(strip_tags($_REQUEST['blocked_id']));
|
||||
}
|
||||
}
|
||||
AIOWPSecurity_Admin_Menu::display_bulk_result_message();
|
||||
|
||||
?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>' . __('This tab displays the list of all permanently blocked IP addresses.', 'all-in-one-wp-security-and-firewall') . '</p>' .
|
||||
'<p>' . __('NOTE: This feature does NOT use the .htaccess file to permanently block the IP addresses so it should be compatible with all web servers running WordPress.', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label
|
||||
for="title"><?php _e('Permanently Blocked IP Addresses', 'all-in-one-wp-security-and-firewall');?></label>
|
||||
</h3>
|
||||
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Fetch, prepare, sort, and filter our data...
|
||||
$blocked_ip_list->prepare_items();
|
||||
?>
|
||||
<form id="tables-filter" method="get">
|
||||
<!-- For plugins, we also need to ensure that the form posts back to our current page -->
|
||||
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>"/>
|
||||
<?php
|
||||
$blocked_ip_list->search_box(__('Search', 'all-in-one-wp-security-and-firewall'), 'search_permanent_block');
|
||||
if (isset($_REQUEST["tab"])) {
|
||||
echo '<input type="hidden" name="tab" value="' . esc_attr($_REQUEST["tab"]) . '" />';
|
||||
}
|
||||
?>
|
||||
<!-- Now we can render the completed list table -->
|
||||
<?php $blocked_ip_list->display(); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab5()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
$file_selected = filter_input(INPUT_POST, 'aiowps_log_file'); // Get the selected file
|
||||
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label
|
||||
for="title"><?php _e('View Logs for All In WP Security & Firewall Plugin', 'all-in-one-wp-security-and-firewall');?></label>
|
||||
</h3>
|
||||
|
||||
<div class="inside">
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-dashboard-logs-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Log File', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<select id="aiowps_log_file" name="aiowps_log_file">
|
||||
<option
|
||||
value=""><?php _e('--Select a file--', 'all-in-one-wp-security-and-firewall')?></option>
|
||||
<option
|
||||
value="wp-security-log.txt" <?php selected($file_selected, 'wp-security-log.txt'); ?>>
|
||||
wp-security-log
|
||||
</option>
|
||||
<option
|
||||
value="wp-security-log-cron-job.txt" <?php selected($file_selected, 'wp-security-log-cron-job.txt'); ?>>
|
||||
wp-security-log-cron-job
|
||||
</option>
|
||||
</select>
|
||||
<span
|
||||
class="description"><?php _e('Select one of the log files to view the contents', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_view_logs"
|
||||
value="<?php _e('View Logs', 'all-in-one-wp-security-and-firewall')?>"
|
||||
class="button-primary"/>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if (isset($_POST['aiowps_view_logs']) && $file_selected)//Do form submission tasks
|
||||
{
|
||||
//Check nonce before doing anything
|
||||
$nonce = $_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-dashboard-logs-nonce')) {
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on dashboard view logs!", 4);
|
||||
wp_die("Error! Nonce check failed on dashboard view logs!");
|
||||
}
|
||||
|
||||
//Let's make sure that the file selected can only ever be the correct log file of this plugin.
|
||||
$valid_aiowps_log_files = array('wp-security-log.txt', 'wp-security-log-cron-job.txt');
|
||||
if(!in_array($file_selected, $valid_aiowps_log_files)){
|
||||
$file_selected = '';
|
||||
unset($_POST['aiowps_view_logs']);
|
||||
wp_die(__('Error! The file you selected is not a permitted file. You can only view log files created by this plugin.','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
if (!empty($file_selected)) {
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label
|
||||
for="title"><?php echo __('Log File Contents For', 'all-in-one-wp-security-and-firewall') . ': ' . $file_selected;?></label>
|
||||
</h3>
|
||||
|
||||
<div class="inside">
|
||||
<?php
|
||||
$aiowps_log_dir = AIO_WP_SECURITY_PATH . '/logs';
|
||||
$log_file = $aiowps_log_dir . '/' . $file_selected;
|
||||
if (file_exists($log_file)) {
|
||||
$log_contents = AIOWPSecurity_Utility_File::get_file_contents($log_file);
|
||||
} else {
|
||||
$log_contents = '';
|
||||
}
|
||||
|
||||
if (empty($log_contents)) {
|
||||
$log_contents = $file_selected . ': ' . __('Log file is empty!', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
?>
|
||||
<textarea class="aio_text_area_file_output aio_half_width aio_spacer_10_tb" rows="15" readonly><?php echo esc_textarea($log_contents); ?></textarea>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
function wp_dashboard() {
|
||||
$screen = get_current_screen();
|
||||
$columns = absint( $screen->get_columns() );
|
||||
$columns_css = '';
|
||||
if ( $columns ) {
|
||||
$columns_css = " columns-$columns";
|
||||
}
|
||||
|
||||
?>
|
||||
<div id="dashboard-widgets" class="metabox-holder<?php echo $columns_css; ?>">
|
||||
<div id="postbox-container-1" class="postbox-container">
|
||||
<?php do_meta_boxes( $screen->id, 'normal', '' ); ?>
|
||||
</div>
|
||||
<div id="postbox-container-2" class="postbox-container">
|
||||
<?php do_meta_boxes( $screen->id, 'side', '' ); ?>
|
||||
</div>
|
||||
<div id="postbox-container-3" class="postbox-container">
|
||||
<?php do_meta_boxes( $screen->id, 'column3', '' ); ?>
|
||||
</div>
|
||||
<div id="postbox-container-4" class="postbox-container">
|
||||
<?php do_meta_boxes( $screen->id, 'column4', '' ); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
|
||||
wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
|
||||
}
|
||||
|
||||
function wp_dashboard_setup() {
|
||||
global $aio_wp_security;
|
||||
global $wp_registered_widgets, $wp_registered_widget_controls, $wp_dashboard_control_callbacks;
|
||||
$wp_dashboard_control_callbacks = array();
|
||||
$screen = get_current_screen();
|
||||
|
||||
// Add widgets
|
||||
wp_add_dashboard_widget( 'security_strength_meter', __( 'Security Strength Meter', 'all-in-one-wp-security-and-firewall' ), array(&$this, 'widget_security_strength_meter') );
|
||||
wp_add_dashboard_widget( 'security_points_breakdown', __( 'Security Points Breakdown', 'all-in-one-wp-security-and-firewall' ), array(&$this, 'widget_security_points_breakdown') );
|
||||
wp_add_dashboard_widget( 'spread_the_word', __( 'Spread the Word', 'all-in-one-wp-security-and-firewall' ), array(&$this, 'widget_spread_the_word') );
|
||||
wp_add_dashboard_widget( 'know_developers', __( 'Get To Know The Developers', 'all-in-one-wp-security-and-firewall' ), array(&$this, 'widget_know_developers') );
|
||||
wp_add_dashboard_widget( 'critical_feature_status', __( 'Critical Feature Status', 'all-in-one-wp-security-and-firewall' ), array(&$this, 'widget_critical_feature_status') );
|
||||
wp_add_dashboard_widget( 'last_5_logins', __( 'Last 5 Logins', 'all-in-one-wp-security-and-firewall' ), array(&$this, 'widget_last_5_logins') );
|
||||
wp_add_dashboard_widget( 'maintenance_mode_status', __( 'Maintenance Mode Status', 'all-in-one-wp-security-and-firewall' ), array(&$this, 'widget_maintenance_mode_status') );
|
||||
if ($aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention') == '1' ||
|
||||
$aio_wp_security->configs->get_value('aiowps_enable_rename_login_page') == '1') {
|
||||
wp_add_dashboard_widget( 'brute_force', __( 'Brute Force Prevention Login Page' ), array(&$this, 'widget_brute_force') );
|
||||
}
|
||||
wp_add_dashboard_widget( 'logged_in_users', __( 'Logged In Users', 'all-in-one-wp-security-and-firewall' ), array(&$this, 'widget_logged_in_users') );
|
||||
wp_add_dashboard_widget( 'locked_ip_addresses', __( 'Locked IP Addresses', 'all-in-one-wp-security-and-firewall' ), array(&$this, 'widget_locked_ip_addresses') );
|
||||
|
||||
do_action( 'aiowps_dashboard_setup' );
|
||||
$dashboard_widgets = apply_filters( 'aiowps_dashboard_widgets', array() );
|
||||
|
||||
foreach ( $dashboard_widgets as $widget_id ) {
|
||||
$name = empty( $wp_registered_widgets[$widget_id]['all_link'] ) ? $wp_registered_widgets[$widget_id]['name'] : $wp_registered_widgets[$widget_id]['name'] . " <a href='{$wp_registered_widgets[$widget_id]['all_link']}' class='edit-box open-box'>" . __('View all') . '</a>';
|
||||
wp_add_dashboard_widget( $widget_id, $name, $wp_registered_widgets[$widget_id]['callback'], $wp_registered_widget_controls[$widget_id]['callback'] );
|
||||
}
|
||||
}
|
||||
|
||||
function widget_security_strength_meter() {
|
||||
global $aiowps_feature_mgr;
|
||||
global $aio_wp_security;
|
||||
$total_site_security_points = $aiowps_feature_mgr->get_total_site_points();
|
||||
$total_security_points_achievable = $aiowps_feature_mgr->get_total_achievable_points();
|
||||
|
||||
?>
|
||||
<script type='text/javascript'>
|
||||
google.load('visualization', '1', {packages: ['gauge']});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
var data = google.visualization.arrayToDataTable([
|
||||
['Label', 'Value'],
|
||||
['Strength', <?php echo $total_site_security_points; ?>]
|
||||
]);
|
||||
|
||||
var options = {
|
||||
width: 320, height: 200, max: <?php echo $total_security_points_achievable; ?>,
|
||||
greenColor: '8EFA9B', yellowColor: 'F5EE90', redColor: 'FA7373',
|
||||
redFrom: 0, redTo: 10,
|
||||
yellowFrom: 10, yellowTo: 50,
|
||||
greenFrom: 50, greenTo: <?php echo $total_security_points_achievable; ?>,
|
||||
minorTicks: 5
|
||||
};
|
||||
|
||||
var chart = new google.visualization.Gauge(document.getElementById('security_strength_chart_div'));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id='security_strength_chart_div'></div>
|
||||
<div class="aiowps_dashboard_widget_footer">
|
||||
<?php
|
||||
_e('Total Achievable Points: ', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<strong>' . $total_security_points_achievable . '</strong><br />';
|
||||
_e('Current Score of Your Site: ', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<strong>' . $total_site_security_points . '</strong>';
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function widget_security_points_breakdown() {
|
||||
global $aiowps_feature_mgr;
|
||||
global $aio_wp_security;
|
||||
$feature_mgr = $aiowps_feature_mgr;
|
||||
$total_site_security_points = $feature_mgr->get_total_site_points();
|
||||
$total_security_points_achievable = $feature_mgr->get_total_achievable_points();
|
||||
|
||||
$feature_items = $feature_mgr->feature_items;
|
||||
$pt_src_chart_data = "";
|
||||
$pt_src_chart_data .= "['Feature Name', 'Points'],";
|
||||
foreach ($feature_items as $item) {
|
||||
if ($item->feature_status == $feature_mgr->feature_active) {
|
||||
$pt_src_chart_data .= "['" . $item->feature_name . "', " . $item->item_points . "],";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
google.load("visualization", "1", {packages: ["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
var data = google.visualization.arrayToDataTable([
|
||||
<?php echo $pt_src_chart_data; ?>
|
||||
]);
|
||||
|
||||
var options = {
|
||||
// height: '250',
|
||||
// width: '450',
|
||||
backgroundColor: 'F6F6F6',
|
||||
pieHole: 0.4,
|
||||
chartArea: {
|
||||
width: '95%',
|
||||
height: '95%',
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new google.visualization.PieChart(document.getElementById('points_source_breakdown_chart_div'));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id='points_source_breakdown_chart_div'></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function widget_spread_the_word() {
|
||||
?>
|
||||
<p><?php _e('We are working hard to make your WordPress site more secure. Please support us, here is how:', 'all-in-one-wp-security-and-firewall');?></p>
|
||||
<p><a href="https://www.facebook.com/tipsntrickshq/" target="_blank"><?php _e('Follow us on', 'all-in-one-wp-security-and-firewall');?> Facebook</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="http://twitter.com/intent/tweet?url=https://www.tipsandtricks-hq.com/wordpress-security-and-firewall-plugin&text=I love the All In One WP Security and Firewall plugin!"
|
||||
target="_blank" class="aio_tweet_link"><?php _e('Post to Twitter', 'all-in-one-wp-security-and-firewall');?></a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="http://wordpress.org/support/view/plugin-reviews/all-in-one-wp-security-and-firewall/"
|
||||
target="_blank" class="aio_rate_us_link"><?php _e('Give us a Good Rating', 'all-in-one-wp-security-and-firewall');?></a>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
function widget_know_developers() {
|
||||
?>
|
||||
<p><?php _e('Wanna know more about the developers behind this plugin?', 'all-in-one-wp-security-and-firewall');?></p>
|
||||
<p><a href="https://wpsolutions-hq.com/" target="_blank">WPSolutions</a></p>
|
||||
<p><a href="https://www.tipsandtricks-hq.com/" target="_blank">Tips and Tricks HQ</a></p>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
function widget_critical_feature_status() {
|
||||
global $aiowps_feature_mgr;
|
||||
global $aio_wp_security;
|
||||
$feature_mgr = $aiowps_feature_mgr;
|
||||
|
||||
_e('Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security', 'all-in-one-wp-security-and-firewall');
|
||||
$feature_items = $aiowps_feature_mgr->feature_items;
|
||||
$username_admin_feature = $aiowps_feature_mgr->get_feature_item_by_id("user-accounts-change-admin-user");
|
||||
echo '<div class="aiowps_feature_status_container">';
|
||||
echo '<div class="aiowps_feature_status_name">' . __('Admin Username', 'all-in-one-wp-security-and-firewall') . '</div>';
|
||||
echo '<a href="admin.php?page=' . AIOWPSEC_USER_ACCOUNTS_MENU_SLUG . '">';
|
||||
echo '<div class="aiowps_feature_status_bar">';
|
||||
if ($username_admin_feature->feature_status == $aiowps_feature_mgr->feature_active) {
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_on">On</div>';
|
||||
echo '<div class="aiowps_feature_status_label">Off</div>';
|
||||
} else {
|
||||
echo '<div class="aiowps_feature_status_label">On</div>';
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_off">Off</div>';
|
||||
}
|
||||
echo '</div></div></a>';
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
|
||||
$login_lockdown_feature = $aiowps_feature_mgr->get_feature_item_by_id("user-login-login-lockdown");
|
||||
echo '<div class="aiowps_feature_status_container">';
|
||||
echo '<div class="aiowps_feature_status_name">' . __('Login Lockdown', 'all-in-one-wp-security-and-firewall') . '</div>';
|
||||
echo '<a href="admin.php?page=' . AIOWPSEC_USER_LOGIN_MENU_SLUG . '">';
|
||||
echo '<div class="aiowps_feature_status_bar">';
|
||||
if ($login_lockdown_feature->feature_status == $aiowps_feature_mgr->feature_active) {
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_on">On</div>';
|
||||
echo '<div class="aiowps_feature_status_label">Off</div>';
|
||||
} else {
|
||||
echo '<div class="aiowps_feature_status_label">On</div>';
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_off">Off</div>';
|
||||
}
|
||||
echo '</div></div></a>';
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
|
||||
$filesystem_feature = $aiowps_feature_mgr->get_feature_item_by_id("filesystem-file-permissions");
|
||||
echo '<div class="aiowps_feature_status_container">';
|
||||
echo '<div class="aiowps_feature_status_name">' . __('File Permission', 'all-in-one-wp-security-and-firewall') . '</div>';
|
||||
echo '<a href="admin.php?page=' . AIOWPSEC_FILESYSTEM_MENU_SLUG . '">';
|
||||
echo '<div class="aiowps_feature_status_bar">';
|
||||
if ($filesystem_feature->feature_status == $aiowps_feature_mgr->feature_active) {
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_on">On</div>';
|
||||
echo '<div class="aiowps_feature_status_label">Off</div>';
|
||||
} else {
|
||||
echo '<div class="aiowps_feature_status_label">On</div>';
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_off">Off</div>';
|
||||
}
|
||||
echo '</div></div></a>';
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
|
||||
$basic_firewall_feature = $aiowps_feature_mgr->get_feature_item_by_id("firewall-basic-rules");
|
||||
echo '<div class="aiowps_feature_status_container">';
|
||||
echo '<div class="aiowps_feature_status_name">' . __('Basic Firewall', 'all-in-one-wp-security-and-firewall') . '</div>';
|
||||
echo '<a href="admin.php?page=' . AIOWPSEC_FIREWALL_MENU_SLUG . '">';
|
||||
echo '<div class="aiowps_feature_status_bar">';
|
||||
if ($basic_firewall_feature->feature_status == $aiowps_feature_mgr->feature_active) {
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_on">On</div>';
|
||||
echo '<div class="aiowps_feature_status_label">Off</div>';
|
||||
} else {
|
||||
echo '<div class="aiowps_feature_status_label">On</div>';
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_off">Off</div>';
|
||||
}
|
||||
echo '</div></div></a>';
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
}
|
||||
|
||||
function widget_last_5_logins() {
|
||||
global $wpdb;
|
||||
$login_activity_table = AIOWPSEC_TBL_USER_LOGIN_ACTIVITY;
|
||||
|
||||
/* -- Ordering parameters -- */
|
||||
//Parameters that are going to be used to order the result
|
||||
isset($_GET["orderby"]) ? $orderby = strip_tags($_GET["orderby"]) : $orderby = '';
|
||||
isset($_GET["order"]) ? $order = strip_tags($_GET["order"]) : $order = '';
|
||||
|
||||
$orderby = !empty($orderby) ? $orderby : 'login_date';
|
||||
$order = !empty($order) ? $order : 'DESC';
|
||||
|
||||
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM $login_activity_table ORDER BY login_date DESC LIMIT %d", 5), ARRAY_A); //Get the last 5 records
|
||||
|
||||
if ($data == NULL) {
|
||||
echo '<p>' . __('No data found!', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
|
||||
} else {
|
||||
$login_summary_table = '';
|
||||
echo '<p>' . __('Last 5 logins summary:', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
$login_summary_table .= '<table class="widefat aiowps_dashboard_table">';
|
||||
$login_summary_table .= '<thead>';
|
||||
$login_summary_table .= '<tr>';
|
||||
$login_summary_table .= '<th>' . __('User', 'all-in-one-wp-security-and-firewall') . '</th>';
|
||||
$login_summary_table .= '<th>' . __('Date', 'all-in-one-wp-security-and-firewall') . '</th>';
|
||||
$login_summary_table .= '<th>' . __('IP', 'all-in-one-wp-security-and-firewall') . '</th>';
|
||||
$login_summary_table .= '</tr>';
|
||||
$login_summary_table .= '</thead>';
|
||||
foreach ($data as $entry) {
|
||||
$login_summary_table .= '<tr>';
|
||||
$login_summary_table .= '<td>' . $entry['user_login'] . '</td>';
|
||||
$login_summary_table .= '<td>' . $entry['login_date'] . '</td>';
|
||||
$login_summary_table .= '<td>' . $entry['login_ip'] . '</td>';
|
||||
$login_summary_table .= '</tr>';
|
||||
}
|
||||
$login_summary_table .= '</table>';
|
||||
echo $login_summary_table;
|
||||
}
|
||||
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
|
||||
}
|
||||
|
||||
function widget_maintenance_mode_status() {
|
||||
global $aio_wp_security;
|
||||
if ($aio_wp_security->configs->get_value('aiowps_site_lockout') == '1') {
|
||||
echo '<p>' . __('Maintenance mode is currently enabled. Remember to turn it off when you are done', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
} else {
|
||||
echo '<p>' . __('Maintenance mode is currently off.', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
}
|
||||
|
||||
echo '<div class="aiowps_feature_status_container">';
|
||||
echo '<div class="aiowps_feature_status_name">' . __('Maintenance Mode', 'all-in-one-wp-security-and-firewall') . '</div>';
|
||||
echo '<a href="admin.php?page=' . AIOWPSEC_MAINTENANCE_MENU_SLUG . '">';
|
||||
echo '<div class="aiowps_feature_status_bar">';
|
||||
if ($aio_wp_security->configs->get_value('aiowps_site_lockout') == '1') {//Maintenance mode is enabled
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_off">On</div>';//If enabled show red by usign the "off" class
|
||||
echo '<div class="aiowps_feature_status_label">Off</div>';
|
||||
} else {
|
||||
echo '<div class="aiowps_feature_status_label">On</div>';
|
||||
echo '<div class="aiowps_feature_status_label aiowps_feature_status_on">Off</div>';
|
||||
}
|
||||
echo '</div></div></a>';
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
|
||||
}
|
||||
|
||||
function widget_brute_force() {
|
||||
global $aio_wp_security;
|
||||
if ($aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention') == '1') {
|
||||
$brute_force_login_feature_link = '<a href="admin.php?page=' . AIOWPSEC_BRUTE_FORCE_MENU_SLUG . '&tab=tab2" target="_blank">' . __('Cookie-Based Brute Force', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
$brute_force_feature_secret_word = $aio_wp_security->configs->get_value('aiowps_brute_force_secret_word');
|
||||
echo '<div class="aio_yellow_box">';
|
||||
|
||||
echo '<p>' . sprintf(__('The %s feature is currently active.', 'all-in-one-wp-security-and-firewall'), $brute_force_login_feature_link) . '</p>';
|
||||
echo '<p>' . __('Your new WordPress login URL is now:', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
echo '<p><strong>' . AIOWPSEC_WP_URL . '/?' . $brute_force_feature_secret_word . '=1</strong></p>';
|
||||
echo '</div>'; //yellow box div
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
}//End if statement for Cookie Based Brute Prevention box
|
||||
|
||||
//Insert Rename Login Page feature box if this feature is active
|
||||
if ($aio_wp_security->configs->get_value('aiowps_enable_rename_login_page') == '1') {
|
||||
if (get_option('permalink_structure')) {
|
||||
$home_url = trailingslashit(home_url());
|
||||
} else {
|
||||
$home_url = trailingslashit(home_url()) . '?';
|
||||
}
|
||||
|
||||
$rename_login_feature_link = '<a href="admin.php?page=' . AIOWPSEC_BRUTE_FORCE_MENU_SLUG . '&tab=tab1" target="_blank">' . __('Rename Login Page', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
echo '<div class="aio_yellow_box">';
|
||||
|
||||
echo '<p>' . sprintf(__('The %s feature is currently active.', 'all-in-one-wp-security-and-firewall'), $rename_login_feature_link) . '</p>';
|
||||
echo '<p>' . __('Your new WordPress login URL is now:', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
echo '<p><strong>' . $home_url . $aio_wp_security->configs->get_value('aiowps_login_page_slug') . '</strong></p>';
|
||||
echo '</div>'; //yellow box div
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
}//End if statement for Rename Login box
|
||||
|
||||
}
|
||||
|
||||
function widget_logged_in_users() {
|
||||
$users_online_link = '<a href="admin.php?page=' . AIOWPSEC_USER_LOGIN_MENU_SLUG . '&tab=tab5">Logged In Users</a>';
|
||||
// default display messages
|
||||
$multiple_users_info_msg = __('Number of users currently logged into your site (including you) is:', 'all-in-one-wp-security-and-firewall');
|
||||
$single_user_info_msg = __('There are no other users currently logged in.', 'all-in-one-wp-security-and-firewall');
|
||||
if (AIOWPSecurity_Utility::is_multisite_install()) {
|
||||
$current_blog_id = get_current_blog_id();
|
||||
$is_main = is_main_site($current_blog_id);
|
||||
|
||||
if(empty($is_main)) {
|
||||
// subsite - only get logged in users for this blog_id
|
||||
$logged_in_users = AIOWPSecurity_User_Login::get_subsite_logged_in_users($current_blog_id);
|
||||
} else {
|
||||
// main site - get sitewide users
|
||||
$logged_in_users = get_site_transient('users_online');
|
||||
|
||||
// If viewing aiowps from multisite main network dashboard then display a different message
|
||||
$multiple_users_info_msg = __('Number of users currently logged in site-wide (including you) is:', 'all-in-one-wp-security-and-firewall');
|
||||
$single_user_info_msg = __('There are no other site-wide users currently logged in.', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
} else {
|
||||
$logged_in_users = get_transient('users_online');
|
||||
}
|
||||
|
||||
if (empty($logged_in_users)) {
|
||||
$num_users = 0;
|
||||
} else {
|
||||
$num_users = count($logged_in_users);
|
||||
}
|
||||
if ($num_users > 1) {
|
||||
echo '<div class="aio_red_box"><p>' . $multiple_users_info_msg . ' <strong>' . $num_users . '</strong></p>';
|
||||
$info_msg = '<p>' . sprintf(__('Go to the %s menu to see more details', 'all-in-one-wp-security-and-firewall'), $users_online_link) . '</p>';
|
||||
echo $info_msg . '</div>';
|
||||
} else {
|
||||
echo '<div class="aio_green_box"><p>' . $single_user_info_msg . '</p></div>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function widget_locked_ip_addresses() {
|
||||
$locked_ips_link = '<a href="admin.php?page=' . AIOWPSEC_MAIN_MENU_SLUG . '&tab=tab3">Locked IP Addresses</a>';
|
||||
|
||||
$locked_ips = AIOWPSecurity_Utility::get_locked_ips();
|
||||
if ($locked_ips === FALSE) {
|
||||
echo '<div class="aio_green_box"><p>' . __('There are no IP addresses currently locked out.', 'all-in-one-wp-security-and-firewall') . '</p></div>';
|
||||
} else {
|
||||
$num_ips = count($locked_ips);
|
||||
echo '<div class="aio_red_box"><p>' . __('Number of temporarily locked out IP addresses: ', 'all-in-one-wp-security-and-firewall') . ' <strong>' . $num_ips . '</strong></p>';
|
||||
$info_msg = '<p>' . sprintf(__('Go to the %s menu to see more details', 'all-in-one-wp-security-and-firewall'), $locked_ips_link) . '</p>';
|
||||
echo $info_msg . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
} //end class
|
||||
@@ -1,609 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Database_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
var $menu_page_slug = AIOWPSEC_DB_SEC_MENU_SLUG;
|
||||
|
||||
/* Specify all the tabs of this menu in the following array */
|
||||
var $menu_tabs;
|
||||
|
||||
var $menu_tabs_handler = array(
|
||||
'tab1' => 'render_tab1',
|
||||
'tab2' => 'render_tab2',
|
||||
);
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->render_menu_page();
|
||||
}
|
||||
|
||||
function set_menu_tabs()
|
||||
{
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && get_current_blog_id() != 1){
|
||||
//Suppress the DB prefix change tab if site is a multi site AND not the main site
|
||||
$this->menu_tabs = array(
|
||||
//'tab1' => __('DB Prefix', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab2' => __('DB Backup', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}else{
|
||||
$this->menu_tabs = array(
|
||||
'tab1' => __('DB Prefix', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab2' => __('DB Backup', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function get_current_tab()
|
||||
{
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
$tab = isset( $_GET['tab'] ) ? sanitize_text_field($_GET['tab']) : $tab_keys[0];
|
||||
return $tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders our tabs of this menu as nav items
|
||||
*/
|
||||
function render_menu_tabs()
|
||||
{
|
||||
$current_tab = $this->get_current_tab();
|
||||
|
||||
echo '<h2 class="nav-tab-wrapper">';
|
||||
foreach ( $this->menu_tabs as $tab_key => $tab_caption )
|
||||
{
|
||||
$active = $current_tab == $tab_key ? 'nav-tab-active' : '';
|
||||
echo '<a class="nav-tab ' . $active . '" href="?page=' . $this->menu_page_slug . '&tab=' . $tab_key . '">' . $tab_caption . '</a>';
|
||||
}
|
||||
echo '</h2>';
|
||||
}
|
||||
|
||||
/*
|
||||
* The menu rendering goes here
|
||||
*/
|
||||
function render_menu_page()
|
||||
{
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>'.__('Database Security','all-in-one-wp-security-and-firewall').'</h2>';//Interface title
|
||||
$this->set_menu_tabs();
|
||||
$tab = $this->get_current_tab();
|
||||
$this->render_menu_tabs();
|
||||
?>
|
||||
<div id="poststuff"><div id="post-body">
|
||||
<?php
|
||||
//$tab_keys = array_keys($this->menu_tabs);
|
||||
call_user_func(array(&$this, $this->menu_tabs_handler[$tab]));
|
||||
?>
|
||||
</div></div>
|
||||
</div><!-- end of wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab1()
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
$old_db_prefix = $wpdb->prefix;
|
||||
$new_db_prefix = '';
|
||||
$perform_db_change = false;
|
||||
|
||||
if (isset($_POST['aiowps_db_prefix_change']))//Do form submission tasks
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-db-prefix-change-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for DB prefix change operation!",4);
|
||||
die(__('Nonce check failed for DB prefix change operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
//Let's first check if user's system allows writing to wp-config.php file. If plugin cannot write to wp-config we will not do the prefix change.
|
||||
$config_file = AIOWPSecurity_Utility_File::get_wp_config_file_path();
|
||||
$file_write = AIOWPSecurity_Utility_File::is_file_writable($config_file);
|
||||
if (!$file_write)
|
||||
{
|
||||
$this->show_msg_error(__('The plugin has detected that it cannot write to the wp-config.php file. This feature can only be used if the plugin can successfully write to the wp-config.php file.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
else
|
||||
{
|
||||
if( isset($_POST['aiowps_enable_random_prefix']))
|
||||
{//User has elected to generate a random DB prefix
|
||||
$string = AIOWPSecurity_Utility::generate_alpha_random_string('5');
|
||||
$new_db_prefix = $string . '_';
|
||||
$perform_db_change = true;
|
||||
}else
|
||||
{
|
||||
if (empty($_POST['aiowps_new_manual_db_prefix']))
|
||||
{
|
||||
$this->show_msg_error(__('Please enter a value for the DB prefix.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
else
|
||||
{
|
||||
//User has chosen their own DB prefix value
|
||||
$new_db_prefix = wp_strip_all_tags( trim( $_POST['aiowps_new_manual_db_prefix'] ) );
|
||||
$error = $wpdb->set_prefix( $new_db_prefix ); //validate the user chosen prefix
|
||||
if(is_wp_error($error))
|
||||
{
|
||||
wp_die( __('<strong>ERROR</strong>: The table prefix can only contain numbers, letters, and underscores.', 'all-in-one-wp-security-and-firewall') );
|
||||
}
|
||||
$wpdb->set_prefix( $old_db_prefix );
|
||||
$perform_db_change = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<h2><?php _e('Change Database Prefix', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('Your WordPress DB is the most important asset of your website because it contains a lot of your site\'s precious information.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('The DB is also a target for hackers via methods such as SQL injections and malicious and automated code which targets certain tables.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('One way to add a layer of protection for your DB is to change the default WordPress table prefix from "wp_" to something else which will be difficult for hackers to guess.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('This feature allows you to easily change the prefix to a value of your choice or to a random value set by this plugin.', 'all-in-one-wp-security-and-firewall').'
|
||||
</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('DB Prefix Options', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("db-security-db-prefix");
|
||||
?>
|
||||
|
||||
<div class="aio_red_box">
|
||||
<?php
|
||||
$backup_tab_link = '<a href="admin.php?page='.AIOWPSEC_DB_SEC_MENU_SLUG.'&tab=tab2">DB Backup</a>';
|
||||
$info_msg = '<p><strong>'.sprintf( __('It is recommended that you perform a %s before using this feature', 'all-in-one-wp-security-and-firewall'), $backup_tab_link).'</strong></p>';
|
||||
echo $info_msg;
|
||||
?>
|
||||
</div>
|
||||
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-db-prefix-change-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Current DB Table Prefix', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<span class="aiowpsec_field_value"><strong><?php echo $wpdb->prefix; ?></strong></span>
|
||||
<?php
|
||||
//now let's display a warning notification if default prefix is used
|
||||
if ($old_db_prefix == 'wp_') {
|
||||
echo ' <span class="aio_error_with_icon">'.__('Your site is currently using the default WordPress DB prefix value of "wp_".
|
||||
To increase your site\'s security you should consider changing the DB prefix value to another value.', 'all-in-one-wp-security-and-firewall').'</span>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Generate New DB Table Prefix', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_random_prefix" type="checkbox" <?php if($aio_wp_security->configs->get_value('aiowps_enable_random_prefix')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want the plugin to generate a random 6 character string for the table prefix', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
<br /><?php _e('OR', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
<br /><input type="text" size="10" name="aiowps_new_manual_db_prefix" value="<?php //echo $aio_wp_security->configs->get_value('aiowps_new_manual_db_prefix'); ?>" />
|
||||
<span class="description"><?php _e('Choose your own DB prefix by specifying a string which contains letters and/or numbers and/or underscores. Example: xyz_', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_db_prefix_change" value="<?php _e('Change DB Prefix', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
if ($perform_db_change)
|
||||
{
|
||||
//Do the DB prefix change operations
|
||||
$this->change_db_prefix($old_db_prefix,$new_db_prefix);
|
||||
}
|
||||
}
|
||||
|
||||
function render_tab2()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
if (isset($_POST['aiowps_manual_db_backup']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-db-manual-change-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for manual DB backup operation!",4);
|
||||
die(__('Nonce check failed for manual DB backup operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
$result = $aio_wp_security->backup_obj->execute_backup();
|
||||
if ($result)
|
||||
{
|
||||
$backup_file_name = $aio_wp_security->backup_obj->last_backup_file_name;
|
||||
if (function_exists('is_multisite') && is_multisite())
|
||||
{
|
||||
$aiowps_backup_file_path = $aio_wp_security->backup_obj->last_backup_file_dir_multisite . '/' . $backup_file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aiowps_backup_dir = WP_CONTENT_DIR.'/'.AIO_WP_SECURITY_BACKUPS_DIR_NAME;
|
||||
$aiowps_backup_file_path = $aiowps_backup_dir. '/' . $backup_file_name;
|
||||
}
|
||||
echo '<div id="message" class="updated fade"><p>';
|
||||
_e('DB Backup was successfully completed! You will receive the backup file via email if you have enabled "Send Backup File Via Email", otherwise you can retrieve it via FTP from the following directory:','all-in-one-wp-security-and-firewall');
|
||||
echo '</p><p>';
|
||||
_e('Your DB Backup File location: ');
|
||||
echo '<strong>'.$aiowps_backup_file_path.'</strong>';
|
||||
echo '</p></div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("DB Backup - Backup operation failed!",4);
|
||||
$this->show_msg_error(__('DB Backup failed. Please check the permissions of the backup directory.','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_POST['aiowps_schedule_backups']))//Do form submission tasks
|
||||
{
|
||||
$error = '';
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-scheduled-backup-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on scheduled DB backup options save!",4);
|
||||
die("Nonce check failed on scheduled DB backup options save!");
|
||||
}
|
||||
|
||||
$backup_frequency = sanitize_text_field($_POST['aiowps_db_backup_frequency']);
|
||||
if(!is_numeric($backup_frequency))
|
||||
{
|
||||
$error .= '<br />'.__('You entered a non numeric value for the "backup time interval" field. It has been set to the default value.','all-in-one-wp-security-and-firewall');
|
||||
$backup_frequency = '4';//Set it to the default value for this field
|
||||
}
|
||||
|
||||
$files_to_keep = sanitize_text_field($_POST['aiowps_backup_files_stored']);
|
||||
if(!is_numeric($files_to_keep))
|
||||
{
|
||||
$error .= '<br />'.__('You entered a non numeric value for the "number of backup files to keep" field. It has been set to the default value.','all-in-one-wp-security-and-firewall');
|
||||
$files_to_keep = '2';//Set it to the default value for this field
|
||||
}
|
||||
|
||||
$email_address = sanitize_email($_POST['aiowps_backup_email_address']);
|
||||
if(!is_email($email_address))
|
||||
{
|
||||
$error .= '<br />'.__('You have entered an incorrect email address format. It has been set to your WordPress admin email as default.','all-in-one-wp-security-and-firewall');
|
||||
$email_address = get_bloginfo('admin_email'); //Set the default value to the blog admin email
|
||||
}
|
||||
|
||||
if($error)
|
||||
{
|
||||
$this->show_msg_error(__('Attention!','all-in-one-wp-security-and-firewall').$error);
|
||||
}
|
||||
|
||||
//Save all the form values to the options
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_automated_backups',isset($_POST["aiowps_enable_automated_backups"])?'1':'');
|
||||
$aio_wp_security->configs->set_value('aiowps_db_backup_frequency',absint($backup_frequency));
|
||||
$aio_wp_security->configs->set_value('aiowps_db_backup_interval',$_POST["aiowps_db_backup_interval"]);
|
||||
$aio_wp_security->configs->set_value('aiowps_backup_files_stored',absint($files_to_keep));
|
||||
$aio_wp_security->configs->set_value('aiowps_send_backup_email_address',isset($_POST["aiowps_send_backup_email_address"])?'1':'');
|
||||
$aio_wp_security->configs->set_value('aiowps_backup_email_address',$email_address);
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
$this->show_msg_settings_updated();
|
||||
|
||||
//Let's check if backup interval was set to less than 24 hours
|
||||
if (isset($_POST["aiowps_enable_automated_backups"]) && ($backup_frequency < 24) && $_POST["aiowps_db_backup_interval"]==0)
|
||||
{
|
||||
$alert_user_msg = 'ATTENTION: You have configured your backups to occur at least once daily. For most websites we recommended that you choose a less frequent backup
|
||||
schedule such as once every few days, once a week or once a month. Choosing a less frequent schedule will also help reduce your server load.';
|
||||
$this->show_msg_updated_st(__($alert_user_msg, 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Manual Backup', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-db-manual-change-nonce'); ?>
|
||||
<p>
|
||||
<span class="description"><?php _e('To create a new DB backup just click on the button below.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</p>
|
||||
<input type="submit" name="aiowps_manual_db_backup" value="<?php _e('Create DB Backup Now', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Automated Scheduled Backups', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("db-security-db-backup");
|
||||
?>
|
||||
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-scheduled-backup-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Automated Scheduled Backups', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_automated_backups" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_automated_backups')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want the system to automatically generate backups periodically based on the settings below', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Backup Time Interval', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><input type="text" size="5" name="aiowps_db_backup_frequency" value="<?php echo $aio_wp_security->configs->get_value('aiowps_db_backup_frequency'); ?>" />
|
||||
<select id="backup_interval" name="aiowps_db_backup_interval">
|
||||
<option value="0" <?php selected( $aio_wp_security->configs->get_value('aiowps_db_backup_interval'), '0' ); ?>><?php _e( 'Hours', 'all-in-one-wp-security-and-firewall' ); ?></option>
|
||||
<option value="1" <?php selected( $aio_wp_security->configs->get_value('aiowps_db_backup_interval'), '1' ); ?>><?php _e( 'Days', 'all-in-one-wp-security-and-firewall' ); ?></option>
|
||||
<option value="2" <?php selected( $aio_wp_security->configs->get_value('aiowps_db_backup_interval'), '2' ); ?>><?php _e( 'Weeks', 'all-in-one-wp-security-and-firewall' ); ?></option>
|
||||
</select>
|
||||
<span class="description"><?php _e('Set the value for how often you would like an automated backup to occur', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Number of Backup Files To Keep', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><input type="text" size="5" name="aiowps_backup_files_stored" value="<?php echo $aio_wp_security->configs->get_value('aiowps_backup_files_stored'); ?>" />
|
||||
<span class="description"><?php _e('Thie field allows you to choose the number of backup files you would like to keep in the backup directory', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Send Backup File Via Email', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_send_backup_email_address" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_send_backup_email_address')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want the system to email you the backup file after a DB backup has been performed', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
<br /><input type="text" size="30" name="aiowps_backup_email_address" value="<?php echo $aio_wp_security->configs->get_value('aiowps_backup_email_address'); ?>" />
|
||||
<span class="description"><?php _e('Enter an email address', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_schedule_backups" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/*
|
||||
* Changes the DB prefix
|
||||
*/
|
||||
function change_db_prefix($table_old_prefix, $table_new_prefix)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
$old_prefix_length = strlen( $table_old_prefix );
|
||||
$error = 0;
|
||||
|
||||
//Config file path
|
||||
$config_file = AIOWPSecurity_Utility_File::get_wp_config_file_path();
|
||||
|
||||
//Get the table resource
|
||||
//$result = mysql_list_tables(DB_NAME);
|
||||
$result = $this->get_mysql_tables(DB_NAME); //Fix for deprecated php mysql_list_tables function
|
||||
|
||||
//Count the number of tables
|
||||
if (is_array($result) && count($result) > 0){
|
||||
$num_rows = count($result);
|
||||
}else{
|
||||
echo '<div class="aio_red_box"><p>'.__('Error - Could not get tables or no tables found!', 'all-in-one-wp-security-and-firewall').'</p></div>';
|
||||
return;
|
||||
}
|
||||
$table_count = 0;
|
||||
$info_msg_string = '<p class="aio_info_with_icon">'.__('Starting DB prefix change operations.....', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
|
||||
$info_msg_string .= '<p class="aio_info_with_icon">'.sprintf( __('Your WordPress system has a total of %s tables and your new DB prefix will be: %s', 'all-in-one-wp-security-and-firewall'), '<strong>'.$num_rows.'</strong>', '<strong>'.$table_new_prefix.'</strong>').'</p>';
|
||||
echo ($info_msg_string);
|
||||
|
||||
//Do a back of the config file
|
||||
if(!AIOWPSecurity_Utility_File::backup_and_rename_wp_config($config_file))
|
||||
{
|
||||
echo '<div class="aio_red_box"><p>'.__('Failed to make a backup of the wp-config.php file. This operation will not go ahead.', 'all-in-one-wp-security-and-firewall').'</p></div>';
|
||||
return;
|
||||
}
|
||||
else{
|
||||
echo '<p class="aio_success_with_icon">'.__('A backup copy of your wp-config.php file was created successfully!', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
}
|
||||
|
||||
//Get multisite blog_ids if applicable
|
||||
if (AIOWPSecurity_Utility::is_multisite_install()) {
|
||||
$blog_ids = AIOWPSecurity_Utility::get_blog_ids();
|
||||
}
|
||||
|
||||
//Rename all the table names
|
||||
foreach ($result as $db_table)
|
||||
{
|
||||
//Get table name with old prefix
|
||||
$table_old_name = $db_table;
|
||||
|
||||
if ( strpos( $table_old_name, $table_old_prefix ) === 0 )
|
||||
{
|
||||
//Get table name with new prefix
|
||||
$table_new_name = $table_new_prefix . substr( $table_old_name, $old_prefix_length );
|
||||
|
||||
//Write query to rename tables name
|
||||
$sql = "RENAME TABLE `".$table_old_name."` TO `".$table_new_name."`";
|
||||
//$sql = "RENAME TABLE %s TO %s";
|
||||
|
||||
//Execute the query
|
||||
if ( false === $wpdb->query($sql) )
|
||||
{
|
||||
$error = 1;
|
||||
echo '<p class="aio_error_with_icon">'.sprintf( __('%s table name update failed', 'all-in-one-wp-security-and-firewall'), '<strong>'.$table_old_name.'</strong>').'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("DB Security Feature - Unable to change prefix of table ".$table_old_name,4);
|
||||
} else {
|
||||
$table_count++;
|
||||
}
|
||||
} else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( $error == 1 )
|
||||
{
|
||||
echo '<p class="aio_error_with_icon">'.sprintf( __('Please change the prefix manually for the above tables to: %s', 'all-in-one-wp-security-and-firewall'), '<strong>'.$table_new_prefix.'</strong>').'</p>';
|
||||
} else
|
||||
{
|
||||
echo '<p class="aio_success_with_icon">'.sprintf( __('%s tables had their prefix updated successfully!', 'all-in-one-wp-security-and-firewall'), '<strong>'.$table_count.'</strong>').'</p>';
|
||||
}
|
||||
|
||||
//Let's check for mysql tables of type "view"
|
||||
$this->alter_table_views($table_old_prefix, $table_new_prefix);
|
||||
|
||||
//Get wp-config.php file contents and modify it with new info
|
||||
$config_contents = file($config_file);
|
||||
$prefix_match_string = '$table_prefix='; //this is our search string for the wp-config.php file
|
||||
foreach ($config_contents as $line_num => $line) {
|
||||
$no_ws_line = preg_replace( '/\s+/', '', $line ); //Strip white spaces
|
||||
if(strpos($no_ws_line, $prefix_match_string) !== FALSE){
|
||||
$config_contents[$line_num] = str_replace($table_old_prefix, $table_new_prefix, $line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Now let's modify the wp-config.php file
|
||||
if (AIOWPSecurity_Utility_File::write_content_to_file($config_file, $config_contents))
|
||||
{
|
||||
echo '<p class="aio_success_with_icon">'. __('wp-config.php file was updated successfully!', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
}else
|
||||
{
|
||||
echo '<p class="aio_error_with_icon">'.sprintf( __('The "wp-config.php" file was not able to be modified. Please modify this file manually using your favourite editor and search
|
||||
for variable "$table_prefix" and assign the following value to that variable: %s', 'all-in-one-wp-security-and-firewall'), '<strong>'.$table_new_prefix.'</strong>').'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("DB Security Feature - Unable to modify wp-config.php",4);
|
||||
}
|
||||
|
||||
//Now let's update the options table
|
||||
$update_option_table_query = $wpdb->prepare("UPDATE " . $table_new_prefix . "options
|
||||
SET option_name = '".$table_new_prefix ."user_roles'
|
||||
WHERE option_name = %s LIMIT 1", $table_old_prefix."user_roles");
|
||||
|
||||
if ( false === $wpdb->query($update_option_table_query) )
|
||||
{
|
||||
echo '<p class="aio_error_with_icon">'.sprintf( __('Update of table %s failed: unable to change %s to %s', 'all-in-one-wp-security-and-firewall'),$table_new_prefix.'options', $table_old_prefix.'user_roles', $table_new_prefix.'user_roles').'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("DB Security Feature - Error when updating the options table",4);//Log the highly unlikely event of DB error
|
||||
} else
|
||||
{
|
||||
echo '<p class="aio_success_with_icon">'.sprintf( __('The options table records which had references to the old DB prefix were updated successfully!', 'all-in-one-wp-security-and-firewall')).'</p>';
|
||||
}
|
||||
|
||||
//Now let's update the options tables for the multisite subsites if applicable
|
||||
if (AIOWPSecurity_Utility::is_multisite_install()) {
|
||||
if(!empty($blog_ids)){
|
||||
foreach ($blog_ids as $blog_id) {
|
||||
if ($blog_id == 1){continue;} //skip main site
|
||||
$new_pref_and_site_id = $table_new_prefix.$blog_id.'_';
|
||||
$old_pref_and_site_id = $table_old_prefix.$blog_id.'_';
|
||||
$update_ms_option_table_query = $wpdb->prepare("UPDATE " . $new_pref_and_site_id . "options
|
||||
SET option_name = '".$new_pref_and_site_id."user_roles'
|
||||
WHERE option_name = %s LIMIT 1", $old_pref_and_site_id."user_roles");
|
||||
if ( false === $wpdb->query($update_ms_option_table_query) )
|
||||
{
|
||||
echo '<p class="aio_error_with_icon">'.sprintf( __('Update of table %s failed: unable to change %s to %s', 'all-in-one-wp-security-and-firewall'),$new_pref_and_site_id.'options', $old_pref_and_site_id.'user_roles', $new_pref_and_site_id.'user_roles').'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("DB change prefix feature - Error when updating the subsite options table: ".$new_pref_and_site_id.'options',4);//Log the highly unlikely event of DB error
|
||||
} else
|
||||
{
|
||||
echo '<p class="aio_success_with_icon">'.sprintf( __('The %s table records which had references to the old DB prefix were updated successfully!', 'all-in-one-wp-security-and-firewall'),$new_pref_and_site_id.'options').'</p>';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Now let's update the user meta table
|
||||
$custom_sql = "SELECT user_id, meta_key
|
||||
FROM " . $table_new_prefix . "usermeta
|
||||
WHERE meta_key
|
||||
LIKE '" . $table_old_prefix . "%'";
|
||||
|
||||
$meta_keys = $wpdb->get_results( $custom_sql );
|
||||
|
||||
$error_update_usermeta = '';
|
||||
|
||||
//Update all meta_key field values which have the old table prefix in user_meta table
|
||||
foreach ($meta_keys as $meta_key ) {
|
||||
//Create new meta key
|
||||
$new_meta_key = $table_new_prefix . substr( $meta_key->meta_key, $old_prefix_length );
|
||||
|
||||
$update_user_meta_sql = $wpdb->prepare("UPDATE " . $table_new_prefix . "usermeta
|
||||
SET meta_key='" . $new_meta_key . "'
|
||||
WHERE meta_key=%s AND user_id=%s", $meta_key->meta_key, $meta_key->user_id);
|
||||
|
||||
if (false === $wpdb->query($update_user_meta_sql))
|
||||
{
|
||||
$error_update_usermeta .= '<p class="aio_error_with_icon">'.sprintf( __('Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s.', 'all-in-one-wp-security-and-firewall'),$new_meta_key,$meta_key->meta_key,$meta_key->user_id).'</p>';
|
||||
echo $error_update_usermeta;
|
||||
$aio_wp_security->debug_logger->log_debug("DB Security Feature - Error updating user_meta table where new meta_key = ".$new_meta_key." old meta_key = ".$meta_key->meta_key." and user_id = ".$meta_key->user_id,4);//Log the highly unlikely event of DB error
|
||||
}
|
||||
}
|
||||
echo '<p class="aio_success_with_icon">'.__('The usermeta table records which had references to the old DB prefix were updated successfully!', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
//Display tasks finished message
|
||||
$tasks_finished_msg_string = '<p class="aio_info_with_icon">'. __('DB prefix change tasks have been completed.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo ($tasks_finished_msg_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an alternative to the deprecated "mysql_list_tables"
|
||||
* Returns an array of table names
|
||||
*/
|
||||
function get_mysql_tables($database='')
|
||||
{
|
||||
global $aio_wp_security;
|
||||
$tables = array();
|
||||
$list_tables_sql = "SHOW TABLES FROM `{$database}`;";
|
||||
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
|
||||
|
||||
if ($mysqli->connect_errno) {
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Database_Menu->get_mysql_tables() - DB connection error.",4);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($result = $mysqli->query($list_tables_sql, MYSQLI_USE_RESULT)) {
|
||||
//Alternative way to get the tables
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
foreach( $row AS $value ) {
|
||||
$tables[] = $value;
|
||||
}
|
||||
}
|
||||
$result->close();
|
||||
}
|
||||
$mysqli->close();
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will modify existing table view definitions to reflect the new DB prefix change
|
||||
*
|
||||
* @param type $old_prefix
|
||||
* @param type $new_prefix
|
||||
*/
|
||||
function alter_table_views($old_db_prefix, $new_db_prefix)
|
||||
{
|
||||
global $wpdb;
|
||||
$table_count = 0;
|
||||
$db_name = $wpdb->dbname;
|
||||
$info_msg_string = '<p class="aio_info_with_icon">'.__('Checking for MySQL tables of type "view".....', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo ($info_msg_string);
|
||||
|
||||
//get tables which are views
|
||||
$query = "SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA LIKE '".$db_name."'";
|
||||
$res = $wpdb->get_results($query);
|
||||
if(empty($res)) return;
|
||||
$view_count = 0;
|
||||
foreach ($res as $item){
|
||||
$old_def = $item->VIEW_DEFINITION;
|
||||
$new_def = str_replace($old_db_prefix, $new_db_prefix, $old_def);
|
||||
$new_def_no_bt = str_replace("`", "", $new_def); //remove any backticks because these will cause the "ALTER" command used later to fail
|
||||
|
||||
$view_name = $item->TABLE_NAME;
|
||||
$chg_view_sql = "ALTER VIEW $view_name AS $new_def_no_bt"; //Note: cannot use $wpdb->prepare because it adds single quotes which cause the ALTER query to fail
|
||||
$view_res = $wpdb->query($chg_view_sql);
|
||||
if($view_res === false){
|
||||
echo '<p class="aio_error_with_icon">'.sprintf( __('Update of the following MySQL view definition failed: %s', 'all-in-one-wp-security-and-firewall'),$old_def).'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("Update of the following MySQL view definition failed: ".$old_def,4);//Log the highly unlikely event of DB error
|
||||
}else{
|
||||
$view_count++;
|
||||
}
|
||||
}
|
||||
if($view_count > 0){
|
||||
echo '<p class="aio_success_with_icon">'.sprintf( __('%s view definitions were updated successfully!', 'all-in-one-wp-security-and-firewall'), '<strong>'.$view_count.'</strong>').'</p>';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} //end class
|
||||
@@ -1,490 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Filescan_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
var $menu_page_slug = AIOWPSEC_FILESCAN_MENU_SLUG;
|
||||
|
||||
/* Specify all the tabs of this menu in the following array */
|
||||
var $menu_tabs;
|
||||
|
||||
var $menu_tabs_handler = array(
|
||||
'tab1' => 'render_tab1',
|
||||
'tab2' => 'render_tab2',
|
||||
);
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->render_menu_page();
|
||||
}
|
||||
|
||||
function set_menu_tabs()
|
||||
{
|
||||
$this->menu_tabs = array(
|
||||
'tab1' => __('File Change Detection','all-in-one-wp-security-and-firewall'),
|
||||
'tab2' => __('Malware Scan','all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}
|
||||
|
||||
function get_current_tab()
|
||||
{
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
$tab = isset( $_GET['tab'] ) ? sanitize_text_field($_GET['tab']) : $tab_keys[0];
|
||||
return $tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders our tabs of this menu as nav items
|
||||
*/
|
||||
function render_menu_tabs()
|
||||
{
|
||||
$current_tab = $this->get_current_tab();
|
||||
|
||||
echo '<h2 class="nav-tab-wrapper">';
|
||||
foreach ( $this->menu_tabs as $tab_key => $tab_caption )
|
||||
{
|
||||
$active = $current_tab == $tab_key ? 'nav-tab-active' : '';
|
||||
echo '<a class="nav-tab ' . $active . '" href="?page=' . $this->menu_page_slug . '&tab=' . $tab_key . '">' . $tab_caption . '</a>';
|
||||
}
|
||||
echo '</h2>';
|
||||
}
|
||||
|
||||
/*
|
||||
* The menu rendering goes here
|
||||
*/
|
||||
function render_menu_page()
|
||||
{
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>'.__('Scanner','all-in-one-wp-security-and-firewall').'</h2>';//Interface title
|
||||
$this->set_menu_tabs();
|
||||
$tab = $this->get_current_tab();
|
||||
$this->render_menu_tabs();
|
||||
?>
|
||||
<div id="poststuff"><div id="post-body">
|
||||
<?php
|
||||
//$tab_keys = array_keys($this->menu_tabs);
|
||||
call_user_func(array(&$this, $this->menu_tabs_handler[$tab]));
|
||||
?>
|
||||
</div></div>
|
||||
</div><!-- end of wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab1()
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
if (isset($_POST['fcd_scan_info']))
|
||||
{
|
||||
//Display scan file change info and clear the global alert variable
|
||||
|
||||
//Clear the global variable
|
||||
$aio_wp_security->configs->set_value('aiowps_fcds_change_detected', FALSE);
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
//Display the last scan results
|
||||
$this->display_last_scan_results();
|
||||
}
|
||||
|
||||
if (isset($_POST['aiowps_view_last_fcd_results']))
|
||||
{
|
||||
//Display the last scan results
|
||||
if (!$this->display_last_scan_results()){
|
||||
$this->show_msg_updated(__('There have been no file changes since the last scan.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['aiowps_manual_fcd_scan']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-fcd-manual-scan-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for manual file change detection scan operation!",4);
|
||||
die(__('Nonce check failed for manual file change detection scan operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
$result = $aio_wp_security->scan_obj->execute_file_change_detection_scan();
|
||||
if ($result === false) {
|
||||
// error case
|
||||
$this->show_msg_error(__('There was an error during the file change detection scan. Please check the aiowps logs.','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
//If this is first scan display special message
|
||||
if ($result['initial_scan'] == 1)
|
||||
{
|
||||
$this->show_msg_updated(__('The plugin has detected that this is your first file change detection scan. The file details from this scan will be used to detect file changes for future scans.','all-in-one-wp-security-and-firewall'));
|
||||
}else if(!$aio_wp_security->configs->get_value('aiowps_fcds_change_detected')){
|
||||
$this->show_msg_updated(__('Scan Complete - There were no file changes detected!', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_POST['aiowps_schedule_fcd_scan']))//Do form submission tasks
|
||||
{
|
||||
$error = '';
|
||||
$reset_scan_data = FALSE;
|
||||
$file_types = '';
|
||||
$files = '';
|
||||
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-scheduled-fcd-scan-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for file change detection scan options save!",4);
|
||||
die("Nonce check failed for file change detection scan options save!");
|
||||
}
|
||||
|
||||
$fcd_scan_frequency = sanitize_text_field($_POST['aiowps_fcd_scan_frequency']);
|
||||
if(!is_numeric($fcd_scan_frequency))
|
||||
{
|
||||
$error .= '<br />'.__('You entered a non numeric value for the "backup time interval" field. It has been set to the default value.','all-in-one-wp-security-and-firewall');
|
||||
$fcd_scan_frequency = '4';//Set it to the default value for this field
|
||||
}
|
||||
|
||||
if (!empty($_POST['aiowps_fcd_exclude_filetypes']))
|
||||
{
|
||||
$file_types = trim($_POST['aiowps_fcd_exclude_filetypes']);
|
||||
//$file_types_array = preg_split( '/\r\n|\r|\n/', $file_types );
|
||||
|
||||
//Get the currently saved config value and check if this has changed. If so do another scan to reset the scan data so it omits these filetypes
|
||||
if ($file_types != $aio_wp_security->configs->get_value('aiowps_fcd_exclude_filetypes'))
|
||||
{
|
||||
$reset_scan_data = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_POST['aiowps_fcd_exclude_files']))
|
||||
{
|
||||
$files = trim($_POST['aiowps_fcd_exclude_files']);
|
||||
//Get the currently saved config value and check if this has changed. If so do another scan to reset the scan data so it omits these files/dirs
|
||||
if ($files != $aio_wp_security->configs->get_value('aiowps_fcd_exclude_files'))
|
||||
{
|
||||
$reset_scan_data = TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Explode by end-of-line character, then trim and filter empty lines
|
||||
$email_list_array = array_filter(array_map('trim', explode(PHP_EOL, $_POST['aiowps_fcd_scan_email_address'])), 'strlen');
|
||||
$errors = array();
|
||||
foreach($email_list_array as $key=>$value){
|
||||
$email_sane = sanitize_email($value);
|
||||
if(!is_email($email_sane))
|
||||
{
|
||||
$errors[] = __('The following address was removed because it is not a valid email address: ', 'all-in-one-wp-security-and-firewall')
|
||||
. htmlspecialchars($value);
|
||||
unset($email_list_array[$key]);
|
||||
}
|
||||
}
|
||||
$email_address = implode(PHP_EOL, $email_list_array);
|
||||
if ( !empty($errors) )
|
||||
{
|
||||
$this->show_msg_error(__('Attention!','all-in-one-wp-security-and-firewall') . '<br/>' . implode('<br />', $errors));
|
||||
}
|
||||
|
||||
//Save all the form values to the options
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_automated_fcd_scan',isset($_POST["aiowps_enable_automated_fcd_scan"])?'1':'');
|
||||
$aio_wp_security->configs->set_value('aiowps_fcd_scan_frequency',absint($fcd_scan_frequency));
|
||||
$aio_wp_security->configs->set_value('aiowps_fcd_scan_interval',$_POST["aiowps_fcd_scan_interval"]);
|
||||
$aio_wp_security->configs->set_value('aiowps_fcd_exclude_filetypes',$file_types);
|
||||
$aio_wp_security->configs->set_value('aiowps_fcd_exclude_files',$files);
|
||||
$aio_wp_security->configs->set_value('aiowps_send_fcd_scan_email',isset($_POST["aiowps_send_fcd_scan_email"])?'1':'');
|
||||
$aio_wp_security->configs->set_value('aiowps_fcd_scan_email_address',$email_address);
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
$this->show_msg_settings_updated();
|
||||
|
||||
//Let's check if backup interval was set to less than 24 hours
|
||||
if (isset($_POST["aiowps_enable_automated_fcd_scan"]) && ($fcd_scan_frequency < 24) && $_POST["aiowps_fcd_scan_interval"]==0)
|
||||
{
|
||||
$alert_user_msg = 'ATTENTION: You have configured your file change detection scan to occur at least once daily. For most websites we recommended that you choose a less frequent
|
||||
schedule such as once every few days, once a week or once a month. Choosing a less frequent schedule will also help reduce your server load.';
|
||||
$this->show_msg_updated(__($alert_user_msg, 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
if($reset_scan_data)
|
||||
{
|
||||
//Clear old scan row and ask user to perform a fresh scan to reset the data
|
||||
$aiowps_global_meta_tbl_name = AIOWPSEC_TBL_GLOBAL_META_DATA;
|
||||
$where = array('meta_key1' => 'file_change_detection', 'meta_value1' => 'file_scan_data');
|
||||
$wpdb->delete( $aiowps_global_meta_tbl_name, $where);
|
||||
$result = $aio_wp_security->scan_obj->execute_file_change_detection_scan();
|
||||
$new_scan_alert = __('NEW SCAN COMPLETED: The plugin has detected that you have made changes to the "File Types To Ignore" or "Files To Ignore" fields.
|
||||
In order to ensure that future scan results are accurate, the old scan data has been refreshed.', 'all-in-one-wp-security-and-firewall');
|
||||
$this->show_msg_updated($new_scan_alert);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Display an alert warning message if a file change was detected
|
||||
if ($aio_wp_security->configs->get_value('aiowps_fcds_change_detected'))
|
||||
{
|
||||
$error_msg = __('All In One WP Security & Firewall has detected that there was a change in your host\'s files.', 'all-in-one-wp-security-and-firewall');
|
||||
|
||||
$button = '<div><form action="" method="POST"><input type="submit" name="fcd_scan_info" value="'.__('View Scan Details & Clear This Message', 'all-in-one-wp-security-and-firewall').'" class="button-secondary" /></form></div>';
|
||||
$error_msg .= $button;
|
||||
$this->show_msg_error($error_msg);
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('If given an opportunity hackers can insert their code or files into your system which they can then use to carry out malicious acts on your site.', 'all-in-one-wp-security-and-firewall').
|
||||
'<br />'.__('Being informed of any changes in your files can be a good way to quickly prevent a hacker from causing damage to your website.', 'all-in-one-wp-security-and-firewall').
|
||||
'<br />'.__('In general, WordPress core and plugin files and file types such as ".php" or ".js" should not change often and when they do, it is important that you are made aware when a change occurs and which file was affected.', 'all-in-one-wp-security-and-firewall').
|
||||
'<br />'.__('The "File Change Detection Feature" will notify you of any file change which occurs on your system, including the addition and deletion of files by performing a regular automated or manual scan of your system\'s files.', 'all-in-one-wp-security-and-firewall').
|
||||
'<br />'.__('This feature also allows you to exclude certain files or folders from the scan in cases where you know that they change often as part of their normal operation. (For example log files and certain caching plugin files may change often and hence you may choose to exclude such files from the file change detection scan)', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if (!class_exists ( "FilesystemIterator" )){
|
||||
?>
|
||||
<div class="aio_orange_box">
|
||||
<p>
|
||||
<?php
|
||||
$read_link = '<a href="https://secure.php.net/manual/en/class.filesystemiterator.php" target="_blank">the FilesystemIterator class</a>';
|
||||
echo sprintf(__('It appears that your server is using an old PHP version which is missing the %s. The file scanner feature needs this class in order to work. If you would like to use this feature please upgrade your server PHP version to 5.3 or greater.', 'all-in-one-wp-security-and-firewall'), $read_link);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Manual File Change Detection Scan', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-fcd-manual-scan-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<span class="description"><?php _e('To perform a manual file change detection scan click on the button below.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_manual_fcd_scan" value="<?php _e('Perform Scan Now', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('View Last Saved File Change Results', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-view-last-fcd-results-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<span class="description"><?php _e('Click the button below to view the saved file change results from the last scan.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_view_last_fcd_results" value="<?php _e('View Last File Change', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('File Change Detection Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("scan-file-change-detection");
|
||||
?>
|
||||
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-scheduled-fcd-scan-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Automated File Change Detection Scan', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_enable_automated_fcd_scan" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_enable_automated_fcd_scan')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want the system to automatically/periodically scan your files to check for file changes based on the settings below', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Scan Time Interval', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><input type="text" size="5" name="aiowps_fcd_scan_frequency" value="<?php echo $aio_wp_security->configs->get_value('aiowps_fcd_scan_frequency'); ?>" />
|
||||
<select id="backup_interval" name="aiowps_fcd_scan_interval">
|
||||
<option value="0" <?php selected( $aio_wp_security->configs->get_value('aiowps_fcd_scan_interval'), '0' ); ?>><?php _e( 'Hours', 'all-in-one-wp-security-and-firewall' ); ?></option>
|
||||
<option value="1" <?php selected( $aio_wp_security->configs->get_value('aiowps_fcd_scan_interval'), '1' ); ?>><?php _e( 'Days', 'all-in-one-wp-security-and-firewall' ); ?></option>
|
||||
<option value="2" <?php selected( $aio_wp_security->configs->get_value('aiowps_fcd_scan_interval'), '2' ); ?>><?php _e( 'Weeks', 'all-in-one-wp-security-and-firewall' ); ?></option>
|
||||
</select>
|
||||
<span class="description"><?php _e('Set the value for how often you would like a scan to occur', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('File Types To Ignore', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><textarea name="aiowps_fcd_exclude_filetypes" rows="5" cols="50"><?php echo htmlspecialchars($aio_wp_security->configs->get_value('aiowps_fcd_exclude_filetypes')); ?></textarea>
|
||||
<br />
|
||||
<span class="description"><?php _e('Enter each file type or extension on a new line which you wish to exclude from the file change detection scan.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
<span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php _e('More Info', 'all-in-one-wp-security-and-firewall'); ?></span></span>
|
||||
<div class="aiowps_more_info_body">
|
||||
<?php
|
||||
echo '<p class="description">'.__('You can exclude file types from the scan which would not normally pose any security threat if they were changed. These can include things such as image files.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example: If you want the scanner to ignore files of type jpg, png, and bmp, then you would enter the following:', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('jpg', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('png', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('bmp', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Files/Directories To Ignore', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td><textarea name="aiowps_fcd_exclude_files" rows="5" cols="50"><?php echo htmlspecialchars($aio_wp_security->configs->get_value('aiowps_fcd_exclude_files')); ?></textarea>
|
||||
<br />
|
||||
<span class="description"><?php _e('Enter each file or directory on a new line which you wish to exclude from the file change detection scan.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
<span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php _e('More Info', 'all-in-one-wp-security-and-firewall'); ?></span></span>
|
||||
<div class="aiowps_more_info_body">
|
||||
<?php
|
||||
echo '<p class="description">'.__('You can exclude specific files/directories from the scan which would not normally pose any security threat if they were changed. These can include things such as log files.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('Example: If you want the scanner to ignore certain files in different directories or whole directories, then you would enter the following:', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('cache/config/master.php', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p class="description">'.__('somedirectory', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Send Email When Change Detected', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_send_fcd_scan_email" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_send_fcd_scan_email')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want the system to email you if a file change was detected', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
<br />
|
||||
<textarea name="aiowps_fcd_scan_email_address" rows="5" cols="50"><?php echo htmlspecialchars($aio_wp_security->configs->get_value('aiowps_fcd_scan_email_address')); ?></textarea>
|
||||
<br />
|
||||
<span class="description"><?php _e('Enter one or more email addresses on a new line.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_schedule_fcd_scan" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
function render_tab2()
|
||||
{
|
||||
?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<h2>'.__('What is Malware?', 'all-in-one-wp-security-and-firewall').'</h2>';
|
||||
echo '<p>'.__('The word Malware stands for Malicious Software. It can consist of things like trojan horses, adware, worms, spyware and any other undesirable code which a hacker will try to inject into your website.', 'all-in-one-wp-security-and-firewall').'</p>'.
|
||||
'<p>'.__('Often when malware code has been inserted into your site you will normally not notice anything out of the ordinary based on appearances, but it can have a dramatic effect on your site\'s search ranking.', 'all-in-one-wp-security-and-firewall').'</p>'.
|
||||
'<p>'.__('This is because the bots and spiders from search engines such as Google have the capability to detect malware when they are indexing the pages on your site, and consequently they can blacklist your website which will in turn affect your search rankings.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
|
||||
$site_scanners_link = '<a href="http://www.site-scanners.com" target="_blank">'.__('CLICK HERE', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
|
||||
echo '<h2>'.__('Scanning For Malware', 'all-in-one-wp-security-and-firewall').'</h2>';
|
||||
echo '<p>'.__('Due to the constantly changing and complex nature of Malware, scanning for such things using a standalone plugin will not work reliably. This is something best done via an external scan of your site regularly.', 'all-in-one-wp-security-and-firewall').'</p>'.
|
||||
'<p>'.__('This is why we have created an easy-to-use scanning service which is hosted off our own server which will scan your site for malware once every day and notify you if it finds anything.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p>'.__('When you sign up for this service you will get the following:', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<ul class="aiowps_admin_ul_grp1">
|
||||
<li>'.__('Automatic Daily Scan of 1 Website','all-in-one-wp-security-and-firewall').'</li>
|
||||
<li>'.__('Automatic Malware & Blacklist Monitoring','all-in-one-wp-security-and-firewall').'</li>
|
||||
<li>'.__('Automatic Email Alerting','all-in-one-wp-security-and-firewall').'</li>
|
||||
<li>'.__('Site uptime monitoring','all-in-one-wp-security-and-firewall').'</li>
|
||||
<li>'.__('Site response time monitoring','all-in-one-wp-security-and-firewall').'</li>
|
||||
<li>'.__('We provide advice for malware cleanup','all-in-one-wp-security-and-firewall').'</li>
|
||||
<li>'.__('Blacklist Removal','all-in-one-wp-security-and-firewall').'</li>
|
||||
<li>'.__('No Contract (Cancel Anytime)','all-in-one-wp-security-and-firewall').'</li>
|
||||
</ul>';
|
||||
echo '<p>'.sprintf(__('To learn more please %s.', 'all-in-one-wp-security-and-firewall'), $site_scanners_link).'</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Outputs the last scan results in a postbox
|
||||
*/
|
||||
function display_last_scan_results()
|
||||
{
|
||||
$fcd_data = AIOWPSecurity_Scan::get_fcd_data();
|
||||
if (!$fcd_data || !isset($fcd_data['last_scan_result']))
|
||||
{
|
||||
// no fcd data found
|
||||
return false;
|
||||
}
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Latest File Change Scan Results', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
$files_added_output = "";
|
||||
$files_removed_output = "";
|
||||
$files_changed_output = "";
|
||||
$last_scan_results = $fcd_data['last_scan_result'];
|
||||
if (!empty($last_scan_results['files_added']))
|
||||
{
|
||||
//Output table of files added
|
||||
echo '<div class="aio_info_with_icon aio_spacer_10_tb">'.__('The following files were added to your host.', 'all-in-one-wp-security-and-firewall').'</div>';
|
||||
$files_added_output .= '<table class="widefat">';
|
||||
$files_added_output .= '<tr>';
|
||||
$files_added_output .= '<th>'.__('File','all-in-one-wp-security-and-firewall').'</th>';
|
||||
$files_added_output .= '<th>'.__('File Size','all-in-one-wp-security-and-firewall').'</th>';
|
||||
$files_added_output .= '<th>'.__('File Modified','all-in-one-wp-security-and-firewall').'</th>';
|
||||
$files_added_output .= '</tr>';
|
||||
foreach ($last_scan_results['files_added'] as $key=>$value) {
|
||||
$files_added_output .= '<tr>';
|
||||
$files_added_output .= '<td>'.$key.'</td>';
|
||||
$files_added_output .= '<td>'.$value['filesize'].'</td>';
|
||||
$files_added_output .= '<td>'.date('Y-m-d H:i:s',$value['last_modified']).'</td>';
|
||||
$files_added_output .= '</tr>';
|
||||
}
|
||||
$files_added_output .= '</table>';
|
||||
echo $files_added_output;
|
||||
}
|
||||
echo '<div class="aio_spacer_15"></div>';
|
||||
if (!empty($last_scan_results['files_removed']))
|
||||
{
|
||||
//Output table of files removed
|
||||
echo '<div class="aio_info_with_icon aio_spacer_10_tb">'.__('The following files were removed from your host.', 'all-in-one-wp-security-and-firewall').'</div>';
|
||||
$files_removed_output .= '<table class="widefat">';
|
||||
$files_removed_output .= '<tr>';
|
||||
$files_removed_output .= '<th>'.__('File','all-in-one-wp-security-and-firewall').'</th>';
|
||||
$files_removed_output .= '<th>'.__('File Size','all-in-one-wp-security-and-firewall').'</th>';
|
||||
$files_removed_output .= '<th>'.__('File Modified','all-in-one-wp-security-and-firewall').'</th>';
|
||||
$files_removed_output .= '</tr>';
|
||||
foreach ($last_scan_results['files_removed'] as $key=>$value) {
|
||||
$files_removed_output .= '<tr>';
|
||||
$files_removed_output .= '<td>'.$key.'</td>';
|
||||
$files_removed_output .= '<td>'.$value['filesize'].'</td>';
|
||||
$files_removed_output .= '<td>'.date('Y-m-d H:i:s',$value['last_modified']).'</td>';
|
||||
$files_removed_output .= '</tr>';
|
||||
}
|
||||
$files_removed_output .= '</table>';
|
||||
echo $files_removed_output;
|
||||
|
||||
}
|
||||
|
||||
echo '<div class="aio_spacer_15"></div>';
|
||||
|
||||
if (!empty($last_scan_results['files_changed']))
|
||||
{
|
||||
//Output table of files changed
|
||||
echo '<div class="aio_info_with_icon aio_spacer_10_tb">'.__('The following files were changed on your host.', 'all-in-one-wp-security-and-firewall').'</div>';
|
||||
$files_changed_output .= '<table class="widefat">';
|
||||
$files_changed_output .= '<tr>';
|
||||
$files_changed_output .= '<th>'.__('File','all-in-one-wp-security-and-firewall').'</th>';
|
||||
$files_changed_output .= '<th>'.__('File Size','all-in-one-wp-security-and-firewall').'</th>';
|
||||
$files_changed_output .= '<th>'.__('File Modified','all-in-one-wp-security-and-firewall').'</th>';
|
||||
$files_changed_output .= '</tr>';
|
||||
foreach ($last_scan_results['files_changed'] as $key=>$value) {
|
||||
$files_changed_output .= '<tr>';
|
||||
$files_changed_output .= '<td>'.$key.'</td>';
|
||||
$files_changed_output .= '<td>'.$value['filesize'].'</td>';
|
||||
$files_changed_output .= '<td>'.date('Y-m-d H:i:s',$value['last_modified']).'</td>';
|
||||
$files_changed_output .= '</tr>';
|
||||
}
|
||||
$files_changed_output .= '</table>';
|
||||
echo $files_changed_output;
|
||||
}
|
||||
|
||||
?>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
} //end class
|
||||
@@ -1,505 +0,0 @@
|
||||
<?php
|
||||
if ( !defined( 'ABSPATH' ) ) { exit; } // Prevent direct access to file
|
||||
class AIOWPSecurity_Filesystem_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
var $menu_page_slug = AIOWPSEC_FILESYSTEM_MENU_SLUG;
|
||||
|
||||
/* Specify all the tabs of this menu in the following array */
|
||||
var $menu_tabs;
|
||||
|
||||
var $menu_tabs_handler = array(
|
||||
'tab1' => 'render_tab1',
|
||||
'tab2' => 'render_tab2',
|
||||
'tab3' => 'render_tab3',
|
||||
'tab4' => 'render_tab4',
|
||||
);
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->render_menu_page();
|
||||
add_action( 'admin_footer', array( &$this, 'filesystem_menu_footer_code' ) );
|
||||
}
|
||||
|
||||
function set_menu_tabs()
|
||||
{
|
||||
$this->menu_tabs = array(
|
||||
'tab1' => __('File Permissions','all-in-one-wp-security-and-firewall'),
|
||||
'tab2' => __('PHP File Editing','all-in-one-wp-security-and-firewall'),
|
||||
'tab3' => __('WP File Access','all-in-one-wp-security-and-firewall'),
|
||||
'tab4' => __('Host System Logs','all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}
|
||||
|
||||
function get_current_tab()
|
||||
{
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
$tab = isset( $_GET['tab'] ) ? sanitize_text_field($_GET['tab']) : $tab_keys[0];
|
||||
return $tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders our tabs of this menu as nav items
|
||||
*/
|
||||
function render_menu_tabs()
|
||||
{
|
||||
$current_tab = $this->get_current_tab();
|
||||
|
||||
echo '<h2 class="nav-tab-wrapper">';
|
||||
foreach ( $this->menu_tabs as $tab_key => $tab_caption )
|
||||
{
|
||||
$active = $current_tab == $tab_key ? 'nav-tab-active' : '';
|
||||
echo '<a class="nav-tab ' . $active . '" href="?page=' . $this->menu_page_slug . '&tab=' . $tab_key . '">' . $tab_caption . '</a>';
|
||||
}
|
||||
echo '</h2>';
|
||||
}
|
||||
|
||||
/*
|
||||
* The menu rendering goes here
|
||||
*/
|
||||
function render_menu_page()
|
||||
{
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>'.__('Filesystem Security','all-in-one-wp-security-and-firewall').'</h2>';//Interface title
|
||||
$this->set_menu_tabs();
|
||||
$tab = $this->get_current_tab();
|
||||
$this->render_menu_tabs();
|
||||
?>
|
||||
<div id="poststuff"><div id="post-body">
|
||||
<?php
|
||||
//$tab_keys = array_keys($this->menu_tabs);
|
||||
call_user_func(array(&$this, $this->menu_tabs_handler[$tab]));
|
||||
?>
|
||||
</div></div>
|
||||
</div><!-- end of wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab1()
|
||||
{
|
||||
//if this is the case there is no need to display a "fix permissions" button
|
||||
global $wpdb, $aio_wp_security;
|
||||
if (isset($_POST['aiowps_fix_permissions']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-fix-permissions-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for manual DB backup operation!",4);
|
||||
die(__('Nonce check failed for manual DB backup operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
if (isset($_POST['aiowps_permission_chg_file']))
|
||||
{
|
||||
$folder_or_file = $_POST['aiowps_permission_chg_file'];
|
||||
$rec_perm_oct_string = $_POST['aiowps_recommended_permissions']; //Convert the octal string to dec so the chmod func will accept it
|
||||
$rec_perm_dec = octdec($rec_perm_oct_string); //Convert the octal string to dec so the chmod func will accept it
|
||||
$perm_result = @chmod($_POST['aiowps_permission_chg_file'], $rec_perm_dec);
|
||||
if ($perm_result === true)
|
||||
{
|
||||
$msg = sprintf( __('The permissions for %s were succesfully changed to %s', 'all-in-one-wp-security-and-firewall'), $folder_or_file, $rec_perm_oct_string);
|
||||
$this->show_msg_updated($msg);
|
||||
}else if($perm_result === false)
|
||||
{
|
||||
$msg = sprintf( __('Unable to change permissions for %s!', 'all-in-one-wp-security-and-firewall'), $folder_or_file);
|
||||
$this->show_msg_error($msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<h2><?php _e('File Permissions Scan', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('Your WordPress file and folder permission settings govern the accessability and read/write privileges of the files and folders which make up your WP installation.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('Your WP installation already comes with reasonably secure file permission settings for the filesystem.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('However, sometimes people or other plugins modify the various permission settings of certain core WP folders or files such that they end up making their site less secure because they chose the wrong permission values.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('This feature will scan the critical WP core folders and files and will highlight any permission settings which are insecure.', 'all-in-one-wp-security-and-firewall').'
|
||||
</p>';
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
$detected_os = strtoupper(PHP_OS);
|
||||
if(strpos($detected_os, "WIN") !== false && $detected_os != "DARWIN"){
|
||||
echo '<div class="aio_yellow_box">';
|
||||
echo '<p>'.__('This plugin has detected that your site is running on a Windows server.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('This feature is not applicable for Windows server installations.', 'all-in-one-wp-security-and-firewall').'
|
||||
</p>';
|
||||
echo '</div>';
|
||||
}else{
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('WP Directory and File Permissions Scan Results', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("filesystem-file-permissions");
|
||||
?>
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-fix-permissions-nonce'); ?>
|
||||
<table class="widefat file_permission_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Name', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('File/Folder', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('Current Permissions', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('Recommended Permissions', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('Recommended Action', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$util = new AIOWPSecurity_Utility_File;
|
||||
$files_dirs_to_check = $util->files_and_dirs_to_check;
|
||||
foreach ($files_dirs_to_check as $file_or_dir)
|
||||
{
|
||||
$this->show_wp_filesystem_permission_status($file_or_dir['name'],$file_or_dir['path'],$file_or_dir['permissions']);
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th><?php _e('Name', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('File/Folder', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('Current Permissions', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('Recommended Permissions', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
<th><?php _e('Recommended Action', 'all-in-one-wp-security-and-firewall') ?></th>
|
||||
</tfoot>
|
||||
</table>
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
function render_tab2()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
|
||||
if(isset($_POST['aiowps_disable_file_edit']))//Do form submission tasks
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-disable-file-edit-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on disable PHP file edit options save!",4);
|
||||
die("Nonce check failed on disable PHP file edit options save!");
|
||||
}
|
||||
|
||||
if(isset($_POST['aiowps_disable_file_editing']))
|
||||
{
|
||||
|
||||
$res = AIOWPSecurity_Utility::disable_file_edits();//$this->disable_file_edits();
|
||||
} else
|
||||
{
|
||||
$res = AIOWPSecurity_Utility::enable_file_edits();//$this->enable_file_edits();
|
||||
}
|
||||
if ($res)
|
||||
{
|
||||
//Save settings if no errors
|
||||
$aio_wp_security->configs->set_value('aiowps_disable_file_editing',isset($_POST["aiowps_disable_file_editing"])?'1':'');
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
$this->show_msg_updated(__('Your PHP file editing settings were saved successfully.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->show_msg_error(__('Operation failed! Unable to modify or make a backup of wp-config.php file!', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
//$this->show_msg_settings_updated();
|
||||
|
||||
}
|
||||
else {
|
||||
// Make sure the setting value is up-to-date with current value in WP config
|
||||
$aio_wp_security->configs->set_value('aiowps_disable_file_editing', defined('DISALLOW_FILE_EDIT') && DISALLOW_FILE_EDIT ? '1' : '');
|
||||
$aio_wp_security->configs->save_config();
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
}
|
||||
?>
|
||||
<h2><?php _e('File Editing', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('The Wordpress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('This is often the first tool an attacker will use if able to login, since it allows code execution.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('This feature will disable the ability for people to edit PHP files via the dashboard.', 'all-in-one-wp-security-and-firewall').'
|
||||
</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Disable PHP File Editing', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("filesystem-file-editing");
|
||||
?>
|
||||
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-disable-file-edit-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Disable Ability To Edit PHP Files', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_disable_file_editing" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_disable_file_editing')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to remove the ability for people to edit PHP files via the WP dashboard', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_disable_file_edit" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab3()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
if(isset($_POST['aiowps_save_wp_file_access_settings']))//Do form submission tasks
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-prevent-default-wp-file-access-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on enable basic firewall settings!",4);
|
||||
die("Nonce check failed on enable basic firewall settings!");
|
||||
}
|
||||
|
||||
//Save settings
|
||||
if(isset($_POST['aiowps_prevent_default_wp_file_access']))
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_prevent_default_wp_file_access','1');
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->configs->set_value('aiowps_prevent_default_wp_file_access','');
|
||||
}
|
||||
|
||||
//Commit the config settings
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
//Recalculate points after the feature status/options have been altered
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
|
||||
//Now let's write the applicable rules to the .htaccess file
|
||||
$res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess();
|
||||
|
||||
if ($res)
|
||||
{
|
||||
$this->show_msg_updated(__('You have successfully saved the Prevent Access to Default WP Files configuration.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->show_msg_error(__('Could not write to the .htaccess file. Please check the file permissions.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<h2><?php _e('WordPress Files', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
$info_msg = sprintf( __('This feature allows you to prevent access to files such as %s, %s and %s which are delivered with all WP installations.', 'all-in-one-wp-security-and-firewall'), 'readme.html', 'license.txt', 'wp-config-sample.php');
|
||||
echo '<p>'.$info_msg.'</p>'.'<p>'.__('By preventing access to these files you are hiding some key pieces of information (such as WordPress version info) from potential hackers.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Prevent Access to Default WP Files', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
//Display security info badge
|
||||
global $aiowps_feature_mgr;
|
||||
$aiowps_feature_mgr->output_feature_details_badge("block-wp-files-access");
|
||||
?>
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-prevent-default-wp-file-access-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Prevent Access to WP Default Install Files', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_prevent_default_wp_file_access" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_prevent_default_wp_file_access')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to prevent access to readme.html, license.txt and wp-config-sample.php.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_save_wp_file_access_settings" value="<?php _e('Save Setting', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab4()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
|
||||
if (isset($_POST['aiowps_system_log_file'])){
|
||||
if ($_POST['aiowps_system_log_file'] != NULL){
|
||||
$sys_log_file = esc_html($_POST['aiowps_system_log_file']);
|
||||
$aio_wp_security->configs->set_value('aiowps_system_log_file',$sys_log_file);
|
||||
}else{
|
||||
$sys_log_file = 'error_log';
|
||||
$aio_wp_security->configs->set_value('aiowps_system_log_file',$sys_log_file);
|
||||
}
|
||||
$aio_wp_security->configs->save_config();
|
||||
}else{
|
||||
$sys_log_file = $aio_wp_security->configs->get_value('aiowps_system_log_file');
|
||||
}
|
||||
|
||||
?>
|
||||
<h2><?php _e('System Logs', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('Sometimes your hosting platform will produce error or warning logs in a file called "error_log".', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('Depending on the nature and cause of the error or warning, your hosting server can create multiple instances of this file in numerous directory locations of your WordPress installation.', 'all-in-one-wp-security-and-firewall').'
|
||||
<br />'.__('By occassionally viewing the contents of these logs files you can keep informed of any underlying problems on your system which you might need to address.', 'all-in-one-wp-security-and-firewall').'
|
||||
</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('View System Logs', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<p><?php _e('Please click the button below to view the latest system logs', 'all-in-one-wp-security-and-firewall'); ?>:</p>
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-view-system-logs-nonce'); ?>
|
||||
<div><?php _e('Enter System Log File Name', 'all-in-one-wp-security-and-firewall')?>:
|
||||
<input type="text" size="25" name="aiowps_system_log_file" value="<?php echo esc_html($sys_log_file); ?>" />
|
||||
<span class="description"><?php _e('Enter your system log file name. (Defaults to error_log)', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</div>
|
||||
<div class="aio_spacer_15"></div>
|
||||
<input type="submit" name="aiowps_search_error_files" value="<?php _e('View Latest System Logs', 'all-in-one-wp-security-and-firewall'); ?>" class="button-primary search-error-files" />
|
||||
<span class="aiowps_loading_1">
|
||||
<img src="<?php echo AIO_WP_SECURITY_URL.'/images/loading.gif'; ?>" alt="<?php __('Loading...', 'all-in-one-wp-security-and-firewall'); ?>" />
|
||||
</span>
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
if (isset($_POST['aiowps_search_error_files']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-view-system-logs-nonce'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on view system log operation!",4);
|
||||
die("Nonce check failed on view system log operation!");
|
||||
}
|
||||
|
||||
$logResults = AIOWPSecurity_Utility_File::recursive_file_search($sys_log_file, 0, ABSPATH);
|
||||
if (empty($logResults) || $logResults == NULL || $logResults == '' || $logResults === FALSE)
|
||||
{
|
||||
$this->show_msg_updated(__('No system logs were found!', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($logResults as $file)
|
||||
{
|
||||
$this->display_system_logs_in_table($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Scans WP key core files and directory permissions and populates a wp wide_fat table
|
||||
* Displays a red background entry with a "Fix" button for permissions which are "777"
|
||||
* Displays a yellow background entry with a "Fix" button for permissions which are less secure than the recommended
|
||||
* Displays a green entry for permissions which are as secure or better than the recommended
|
||||
*/
|
||||
function show_wp_filesystem_permission_status($name,$path,$recommended)
|
||||
{
|
||||
$fix = false;
|
||||
$configmod = AIOWPSecurity_Utility_File::get_file_permission($path);
|
||||
if ($configmod == "0777"){
|
||||
$trclass = "aio_table_row_red"; //Display a red background if permissions are set as least secure ("777")
|
||||
$fix = true;
|
||||
}
|
||||
else if($configmod != $recommended)
|
||||
{
|
||||
//$res = $this->is_file_permission_secure($recommended, $configmod);
|
||||
$res = AIOWPSecurity_Utility_File::is_file_permission_secure($recommended, $configmod);
|
||||
if ($res)
|
||||
{
|
||||
$trclass = "aio_table_row_green"; //If the current permissions are even tighter than recommended then display a green row
|
||||
$fix = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$trclass = "aio_table_row_yellow"; //Display a yellow background if permissions are set to something different than recommended
|
||||
$fix = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$trclass = "aio_table_row_green";
|
||||
}
|
||||
echo "<tr class=".$trclass.">";
|
||||
echo '<td>' . $name . "</td>";
|
||||
echo '<td>'. $path ."</td>";
|
||||
echo '<td>' . $configmod . '</td>';
|
||||
echo '<td>' . $recommended . '</td>';
|
||||
if ($fix)
|
||||
{
|
||||
echo '<td>
|
||||
<input type="submit" name="aiowps_fix_permissions" value="'.__('Set Recommended Permissions','all-in-one-wp-security-and-firewall').'" class="button-secondary" />
|
||||
<input type="hidden" name="aiowps_permission_chg_file" value="'.$path.'"/>
|
||||
<input type="hidden" name="aiowps_recommended_permissions" value="'.$recommended.'"/>
|
||||
</td>';
|
||||
} else
|
||||
{
|
||||
echo '<td>'.__('No Action Required', 'all-in-one-wp-security-and-firewall').'</td>';
|
||||
}
|
||||
echo "</tr>";
|
||||
}
|
||||
|
||||
|
||||
|
||||
function filesystem_menu_footer_code()
|
||||
{
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
/* <![CDATA[ */
|
||||
jQuery(document).ready(function($) {
|
||||
loading_span = $('.aiowps_loading_1');
|
||||
loading_span.hide(); //hide the spinner gif after page has successfully loaded
|
||||
$('.search-error-files').on("click",function(){
|
||||
loading_span.show();
|
||||
});
|
||||
});
|
||||
/* ]]> */
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
function display_system_logs_in_table($filepath)
|
||||
{
|
||||
global $aio_wp_security;
|
||||
//Get contents of the error_log file
|
||||
$error_file_contents = file($filepath);
|
||||
if (!$error_file_contents)
|
||||
{
|
||||
//TODO - error could not read file, display notice???
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Filesystem_Menu - Unable to read file: ".$filepath,4);
|
||||
|
||||
}
|
||||
$last_50_entries = array_slice($error_file_contents, -50); //extract the last 50 entries
|
||||
?>
|
||||
<table class="widefat file_permission_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo(sprintf(__('Showing latest entries of error_log file: %s', 'all-in-one-wp-security-and-firewall'),'<strong>'.$filepath.'</strong>')); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
foreach ($last_50_entries as $entry)
|
||||
{
|
||||
echo "<tr>";
|
||||
echo '<td>' . $entry . "</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
|
||||
}
|
||||
} //end class
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,324 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_404 extends AIOWPSecurity_List_Table {
|
||||
|
||||
function __construct() {
|
||||
global $status, $page;
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
));
|
||||
}
|
||||
|
||||
function column_default($item, $column_name) {
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
function column_id($item) {
|
||||
$tab = strip_tags($_REQUEST['tab']);
|
||||
$ip = $item['ip_or_host'];
|
||||
|
||||
$blocked_ips_tab = 'tab3';
|
||||
//Check if this IP address is locked
|
||||
$is_locked = AIOWPSecurity_Utility::check_locked_ip($ip);
|
||||
$delete_url = sprintf('admin.php?page=%s&tab=%s&action=%s&id=%s', AIOWPSEC_FIREWALL_MENU_SLUG, $tab, 'delete_event_log', $item['id']);
|
||||
//Add nonce to delete URL
|
||||
$delete_url_nonce = wp_nonce_url($delete_url, "delete_404_log", "aiowps_nonce");
|
||||
if ($is_locked) {
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'unblock' => sprintf('<a href="admin.php?page=%s&tab=%s">Unblock</a>', AIOWPSEC_MAIN_MENU_SLUG, $blocked_ips_tab),
|
||||
'delete' => '<a href="'.$delete_url_nonce.'" onclick="return confirm(\'Are you sure you want to delete this item?\')">Delete</a>',
|
||||
);
|
||||
} else {
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'temp_block' => sprintf('<a href="admin.php?page=%s&tab=%s&action=%s&ip_address=%s&username=%s" onclick="return confirm(\'Are you sure you want to block this IP address?\')">Temp Block</a>', AIOWPSEC_FIREWALL_MENU_SLUG, $tab, 'temp_block', $item['ip_or_host'], $item['username']),
|
||||
'blacklist_ip' => sprintf('<a href="admin.php?page=%s&tab=%s&action=%s&ip_address=%s&username=%s" onclick="return confirm(\'Are you sure you want to permanently block this IP address?\')">Blacklist IP</a>', AIOWPSEC_FIREWALL_MENU_SLUG, $tab, 'blacklist_ip', $item['ip_or_host'], $item['username']),
|
||||
'delete' => '<a href="'.$delete_url_nonce.'" onclick="return confirm(\'Are you sure you want to delete this item?\')">Delete</a>',
|
||||
);
|
||||
}
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/* $1%s */ $item['id'],
|
||||
/* $2%s */ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
function column_status($item) {
|
||||
global $aio_wp_security;
|
||||
$ip = $item['ip_or_host'];
|
||||
//Check if this IP address is locked
|
||||
$is_locked = AIOWPSecurity_Utility::check_locked_ip($ip);
|
||||
$blacklisted_string = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses');
|
||||
$banned = strpos($blacklisted_string, $ip);
|
||||
|
||||
if ($banned !== false) {
|
||||
return 'blacklisted';
|
||||
} else if ($is_locked) {
|
||||
return 'temporarily blocked';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function column_cb($item) {
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/* $1%s */ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/* $2%s */ $item['id'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
function get_columns() {
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'id' => 'ID',
|
||||
'event_type' => __('Event Type','all-in-one-wp-security-and-firewall'),
|
||||
'ip_or_host' => __('IP Address','all-in-one-wp-security-and-firewall'),
|
||||
'url' => __('Attempted URL','all-in-one-wp-security-and-firewall'),
|
||||
'referer_info' => __('Referer','all-in-one-wp-security-and-firewall'),
|
||||
'event_date' => __('Date','all-in-one-wp-security-and-firewall'),
|
||||
'status' => __('Lock Status','all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
$columns = apply_filters('list_404_get_columns', $columns);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
'id' => array('id', false),
|
||||
'event_type' => array('event_type', false),
|
||||
'ip_or_host' => array('ip_or_host', false),
|
||||
'url' => array('url', false),
|
||||
'referer_info' => array('referer_info', false),
|
||||
'event_date' => array('event_date', false),
|
||||
);
|
||||
$sortable_columns = apply_filters('list_404_get_sortable_columns', $sortable_columns);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
function get_bulk_actions() {
|
||||
$actions = array(
|
||||
//'unlock' => 'Unlock',
|
||||
'bulk_block_ip' => 'Temp Block IP',
|
||||
'bulk_blacklist_ip' => 'Blacklist IP',
|
||||
'delete' => 'Delete'
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
function process_bulk_action() {
|
||||
if ('bulk_block_ip' === $this->current_action()) {//Process delete bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
$this->block_ip(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
|
||||
if ('bulk_blacklist_ip' === $this->current_action()) {//Process delete bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
$this->blacklist_ip_address(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
if ('delete' === $this->current_action()) {//Process delete bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
$this->delete_404_event_records(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will lock an IP address by adding it to the "login_lockdown" table
|
||||
*/
|
||||
|
||||
function block_ip($entries, $username = '') {
|
||||
global $wpdb;
|
||||
$events_table = AIOWPSEC_TBL_LOGIN_LOCKDOWN;
|
||||
if (is_array($entries)) {
|
||||
//lock multiple records
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" .implode(",",$entries) .")"; //Create comma separate list for DB operation
|
||||
$events_table = AIOWPSEC_TBL_EVENTS;
|
||||
$query = "SELECT ip_or_host FROM $events_table WHERE ID IN ".$id_list;
|
||||
$results = $wpdb->get_col($query);
|
||||
if(empty($results)){
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Could not process the request because the IP addresses for the selected entries could not be found!', 'WPS'));
|
||||
return false;
|
||||
}else{
|
||||
foreach($results as $entry){
|
||||
if(filter_var($entry, FILTER_VALIDATE_IP)){
|
||||
AIOWPSecurity_Utility::lock_IP($entry, '404', $username);
|
||||
}
|
||||
}
|
||||
}
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses are now temporarily blocked!', 'WPS'));
|
||||
} elseif ($entries != NULL) {
|
||||
//Block single record
|
||||
if(filter_var($entries, FILTER_VALIDATE_IP)){
|
||||
AIOWPSecurity_Utility::lock_IP($entries, '404', $username);
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP address is now temporarily blocked!', 'WPS'));
|
||||
}else{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The selected entry is not a valid IP address!', 'WPS'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will lock an IP address by adding it to the "login_lockdown" table
|
||||
*/
|
||||
|
||||
function blacklist_ip_address($entries) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
$bl_ip_addresses = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'); //get the currently saved blacklisted IPs
|
||||
$ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($bl_ip_addresses);
|
||||
|
||||
if (is_array($entries)) {
|
||||
//Get the selected IP addresses
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" .implode(",",$entries) .")"; //Create comma separate list for DB operation
|
||||
$events_table = AIOWPSEC_TBL_EVENTS;
|
||||
$query = "SELECT ip_or_host FROM $events_table WHERE ID IN ".$id_list;
|
||||
$results = $wpdb->get_col($query);
|
||||
if(empty($results)){
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Could not process the request because the IP addresses for the selected entries could not be found!', 'WPS'));
|
||||
return false;
|
||||
}else{
|
||||
foreach($results as $entry){
|
||||
$ip_list_array[] = $entry;
|
||||
}
|
||||
}
|
||||
} elseif ($entries != NULL) {
|
||||
//Blacklist single record
|
||||
$ip_list_array[] = $entries;
|
||||
}
|
||||
$payload = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'blacklist');
|
||||
if($payload[0] == 1){
|
||||
//success case
|
||||
$result = 1;
|
||||
$list = $payload[1];
|
||||
$banned_ip_data = implode(PHP_EOL, $list);
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_blacklisting','1'); //Force blacklist feature to be enabled
|
||||
$aio_wp_security->configs->set_value('aiowps_banned_ip_addresses',$banned_ip_data);
|
||||
$aio_wp_security->configs->save_config(); //Save the configuration
|
||||
|
||||
$write_result = AIOWPSecurity_Utility_Htaccess::write_to_htaccess(); //now let's write to the .htaccess file
|
||||
if ( $write_result ) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses have been added to the blacklist and will be permanently blocked!', 'WPS'));
|
||||
} else {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The plugin was unable to write to the .htaccess file. Please edit file manually.','all-in-one-wp-security-and-firewall'));
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Blacklist_Menu - The plugin was unable to write to the .htaccess file.");
|
||||
}
|
||||
}
|
||||
else{
|
||||
$result = -1;
|
||||
$error_msg = $payload[1][0];
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st($error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will delete selected 404 records from the "events" table.
|
||||
* The function accepts either an array of IDs or a single ID
|
||||
*/
|
||||
|
||||
function delete_404_event_records($entries) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
$events_table = AIOWPSEC_TBL_EVENTS;
|
||||
if (is_array($entries)) {
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//Delete multiple records
|
||||
$entries = array_map( 'esc_sql', $entries); //escape every array element
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" . implode(",", $entries) . ")"; //Create comma separate list for DB operation
|
||||
$delete_command = "DELETE FROM " . $events_table . " WHERE id IN " . $id_list;
|
||||
$result = $wpdb->query($delete_command);
|
||||
if ($result != NULL) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st();
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($entries != NULL) {
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'delete_404_log'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for delete selected 404 event logs operation!",4);
|
||||
die(__('Nonce check failed for delete selected 404 event logs operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
//Delete single record
|
||||
$delete_command = "DELETE FROM " . $events_table . " WHERE id = '" . absint($entries) . "'";
|
||||
//$delete_command = $wpdb->prepare("DELETE FROM $events_table WHERE id = %s", absint($entries));
|
||||
$result = $wpdb->query($delete_command);
|
||||
if ($result != NULL) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function prepare_items($ignore_pagination=false) {
|
||||
/**
|
||||
* First, lets decide how many records per page to show
|
||||
*/
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
global $wpdb;
|
||||
$events_table_name = AIOWPSEC_TBL_EVENTS;
|
||||
|
||||
/* -- Ordering parameters -- */
|
||||
//Parameters that are going to be used to order the result
|
||||
isset($_GET["orderby"]) ? $orderby = strip_tags($_GET["orderby"]): $orderby = '';
|
||||
isset($_GET["order"]) ? $order = strip_tags($_GET["order"]): $order = '';
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'id';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
if (isset($_POST['s'])) {
|
||||
$search_term = trim($_POST['s']);
|
||||
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM " . $events_table_name . " WHERE `ip_or_host` LIKE '%%%s%%' OR `url` LIKE '%%%s%%' OR `referer_info` LIKE '%%%s%%'", $search_term, $search_term, $search_term), ARRAY_A);
|
||||
} else {
|
||||
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM $events_table_name WHERE event_type=%s ORDER BY $orderby $order",'404'), ARRAY_A);
|
||||
}
|
||||
$new_data = array();
|
||||
foreach ($data as $row) {
|
||||
//lets insert an empty "status" column - we will use later
|
||||
$row['status'] = '';
|
||||
$new_data[] = $row;
|
||||
}
|
||||
if (!$ignore_pagination) {
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($new_data);
|
||||
$new_data = array_slice($new_data, (($current_page - 1) * $per_page), $per_page);
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
$this->items = $new_data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Account_Activity extends AIOWPSecurity_List_Table {
|
||||
|
||||
function __construct(){
|
||||
global $status, $page;
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct( array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
function column_default($item, $column_name){
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
function column_user_id($item){
|
||||
$tab = strip_tags($_REQUEST['tab']);
|
||||
$delete_url = sprintf('admin.php?page=%s&tab=%s&action=%s&activity_login_rec=%s', AIOWPSEC_USER_LOGIN_MENU_SLUG, $tab, 'delete_acct_activity_rec', $item['id']);
|
||||
//Add nonce to delete URL
|
||||
$delete_url_nonce = wp_nonce_url($delete_url, "delete_acct_activity_log", "aiowps_nonce");
|
||||
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'delete' => '<a href="'.$delete_url_nonce.'" onclick="return confirm(\'Are you sure you want to delete this item?\')">Delete</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['user_id'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function column_cb($item){
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/ $item['id'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
function get_columns(){
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'user_id' => __('User ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_login' => __('Username', 'all-in-one-wp-security-and-firewall'),
|
||||
'login_date' => __('Login Date', 'all-in-one-wp-security-and-firewall'),
|
||||
'logout_date' => __('Logout Date', 'all-in-one-wp-security-and-firewall'),
|
||||
'login_ip' => 'IP'
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
'user_id' => array('user_id',false),
|
||||
'user_login' => array('user_login',false),
|
||||
'login_date' => array('login_date',false),
|
||||
'login_ip' => array('login_ip',false),
|
||||
'logout_date' => array('logout_date',false),
|
||||
);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
function get_bulk_actions() {
|
||||
$actions = array(
|
||||
'delete' => 'Delete'
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
function process_bulk_action() {
|
||||
if('delete'===$this->current_action())
|
||||
{//Process delete bulk actions
|
||||
if(!isset($_REQUEST['item']))
|
||||
{
|
||||
$error_msg = '<div id="message" class="error"><p><strong>';
|
||||
$error_msg .= __('Please select some records using the checkboxes','all-in-one-wp-security-and-firewall');
|
||||
$error_msg .= '</strong></p></div>';
|
||||
_e($error_msg);
|
||||
} else{
|
||||
$this->delete_login_activity_records(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This function will delete selected records from the "user_login_activity" table.
|
||||
* The function accepts either an array of IDs or a single ID
|
||||
*/
|
||||
function delete_login_activity_records($entries)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
$login_activity_table = AIOWPSEC_TBL_USER_LOGIN_ACTIVITY;
|
||||
if (is_array($entries))
|
||||
{
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//Delete multiple records
|
||||
$tab = strip_tags($_REQUEST['tab']);
|
||||
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" .implode(",",$entries) .")"; //Create comma separate list for DB operation
|
||||
$delete_command = "DELETE FROM ".$login_activity_table." WHERE id IN ".$id_list;
|
||||
$result = $wpdb->query($delete_command);
|
||||
if($result !== false)
|
||||
{
|
||||
$redir_url = sprintf('admin.php?page=%s&tab=%s&bulk_count=%s', AIOWPSEC_USER_LOGIN_MENU_SLUG, $tab, count($entries));
|
||||
AIOWPSecurity_Utility::redirect_to_url($redir_url);
|
||||
} else {
|
||||
// error on bulk delete
|
||||
$aio_wp_security->debug_logger->log_debug("DB error: ".$wpdb->last_error,4);
|
||||
$redir_url = sprintf('admin.php?page=%s&tab=%s&bulk_error=%s', AIOWPSEC_USER_LOGIN_MENU_SLUG, $tab, 1);
|
||||
AIOWPSecurity_Utility::redirect_to_url($redir_url);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($entries != NULL)
|
||||
{
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'delete_acct_activity_log'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for delete selected account activity logs operation!",4);
|
||||
die(__('Nonce check failed for delete selected account activity logs operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
//Delete single record
|
||||
$delete_command = "DELETE FROM ".$login_activity_table." WHERE id = '".absint($entries)."'";
|
||||
$result = $wpdb->query($delete_command);
|
||||
if($result !== false)
|
||||
{
|
||||
$success_msg = '<div id="message" class="updated fade"><p><strong>';
|
||||
$success_msg .= __('The selected entry was deleted successfully!','all-in-one-wp-security-and-firewall');
|
||||
$success_msg .= '</strong></p></div>';
|
||||
echo $success_msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function prepare_items($ignore_pagination = false) {
|
||||
/**
|
||||
* First, lets decide how many records per page to show
|
||||
*/
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
$search = isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '';
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
global $wpdb;
|
||||
$login_activity_table = AIOWPSEC_TBL_USER_LOGIN_ACTIVITY;
|
||||
|
||||
/* -- Ordering parameters -- */
|
||||
//Parameters that are going to be used to order the result
|
||||
|
||||
isset($_GET["orderby"]) ? $orderby = strip_tags($_GET["orderby"]) : $orderby = '';
|
||||
isset($_GET["order"]) ? $order = strip_tags($_GET["order"]) : $order = '';
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'login_date';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
if(empty($search)) {
|
||||
$data = $wpdb->get_results("SELECT * FROM $login_activity_table ORDER BY $orderby $order", ARRAY_A);
|
||||
} else {
|
||||
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM $login_activity_table WHERE `user_login` LIKE '%%%s%%' OR `login_ip` LIKE '%%%s%%' ORDER BY $orderby $order LIMIT %d", $search, $search, 100), ARRAY_A);
|
||||
}
|
||||
|
||||
if (!$ignore_pagination) {
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($data);
|
||||
$data = array_slice($data, (($current_page - 1) * $per_page), $per_page);
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
$this->items = $data;
|
||||
}
|
||||
}
|
||||
@@ -1,275 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Comment_Spammer_IP extends AIOWPSecurity_List_Table {
|
||||
|
||||
function __construct(){
|
||||
global $status, $page;
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct( array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
function column_default($item, $column_name){
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
function column_comment_author_IP($item){
|
||||
$tab = strip_tags($_REQUEST['tab']);
|
||||
//Build row actions
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && get_current_blog_id() != 1){
|
||||
//Suppress the block link if site is a multi site AND not the main site
|
||||
$actions = array(); //blank array
|
||||
}else{
|
||||
$block_url = sprintf('admin.php?page=%s&tab=%s&action=%s&spammer_ip=%s', AIOWPSEC_SPAM_MENU_SLUG, $tab, 'block_spammer_ip', $item['comment_author_IP']);
|
||||
//Add nonce to block URL
|
||||
$block_url_nonce = wp_nonce_url($block_url, "block_spammer_ip", "aiowps_nonce");
|
||||
|
||||
$actions = array(
|
||||
'block' => '<a href="'.$block_url_nonce.'" onclick="return confirm(\'Are you sure you want to permanently block this IP address?\')">Block</a>',
|
||||
);
|
||||
}
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['comment_author_IP'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function column_cb($item){
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/ $item['comment_author_IP'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
function get_columns(){
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'comment_author_IP' => __('Spammer IP', 'all-in-one-wp-security-and-firewall'),
|
||||
'amount' => __('Number of SPAM Comments From This IP', 'all-in-one-wp-security-and-firewall'),
|
||||
'status' => __('Status', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
'comment_author_IP' => array('comment_author_IP',false),
|
||||
'amount' => array('amount',false),
|
||||
'status' => array('status',false),
|
||||
);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
function get_bulk_actions() {
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && get_current_blog_id() != 1){
|
||||
//Suppress the block link if site is a multi site AND not the main site
|
||||
$actions = array(); //blank array
|
||||
}else{
|
||||
$actions = array(
|
||||
'block' => __('Block', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
function process_bulk_action() {
|
||||
global $aio_wp_security;
|
||||
if('block'===$this->current_action())
|
||||
{
|
||||
//Process block bulk actions
|
||||
if(!isset($_REQUEST['item']))
|
||||
{
|
||||
$error_msg = '<div id="message" class="error"><p><strong>';
|
||||
$error_msg .= __('Please select some records using the checkboxes','all-in-one-wp-security-and-firewall');
|
||||
$error_msg .= '</strong></p></div>';
|
||||
_e($error_msg);
|
||||
} else {
|
||||
$this->block_spammer_ip_records(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This function will add the selected IP addresses to the blacklist.
|
||||
* The function accepts either an array of IDs or a single ID
|
||||
*/
|
||||
function block_spammer_ip_records($entries)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
if (is_array($entries))
|
||||
{
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//Bulk selection using checkboxes were used
|
||||
foreach ($entries as $ip_add)
|
||||
{
|
||||
AIOWPSecurity_Blocking::add_ip_to_block_list($ip_add, 'spam');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($entries != NULL)
|
||||
{
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'block_spammer_ip'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for delete selected blocked IP operation!",4);
|
||||
die(__('Nonce check failed for delete selected blocked IP operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
//individual entry where "block" link was clicked
|
||||
AIOWPSecurity_Blocking::add_ip_to_block_list($entries, 'spam');
|
||||
}
|
||||
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses are now permanently blocked!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/*
|
||||
* (Old function which uses .htaccess blacklist - replaced by new method which uses php blocking code)
|
||||
* This function will add the selected IP addresses to the .htaccess blacklist.
|
||||
* The function accepts either an array of IDs or a single ID
|
||||
*/
|
||||
function block_spammer_ip_records_old($entries)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
$raw_banned_ip_list = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses');
|
||||
$currently_banned_ips = explode(PHP_EOL, $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'));
|
||||
if (is_array($entries))
|
||||
{
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//Bulk selection using checkboxes were used
|
||||
foreach ($entries as $ip_add)
|
||||
{
|
||||
if (!empty($currently_banned_ips) && !(sizeof($currently_banned_ips) == 1 && trim($currently_banned_ips[0]) == ''))
|
||||
{
|
||||
//Check if the IP address is already in the blacklist. If not add it to the list.
|
||||
if (!in_array($ip_add, $currently_banned_ips))
|
||||
{
|
||||
$raw_banned_ip_list .= PHP_EOL.$ip_add;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//if blacklist is currently empty just add all IP addresses to the list regardless
|
||||
$raw_banned_ip_list .= PHP_EOL.$ip_add;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($entries != NULL)
|
||||
{
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'block_spammer_ip'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for delete selected blocked IP operation!",4);
|
||||
die(__('Nonce check failed for delete selected blocked IP operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
//individual entry where "block" link was clicked
|
||||
//Check if the IP address is already in the blacklist. If not add it to the list.
|
||||
if (!in_array($entries, $currently_banned_ips))
|
||||
{
|
||||
$raw_banned_ip_list .= PHP_EOL.$entries;
|
||||
}
|
||||
}
|
||||
|
||||
//Let's save the selected IP addresses to the blacklist config
|
||||
$aio_wp_security->configs->set_value('aiowps_banned_ip_addresses',$raw_banned_ip_list); //Save the blocked IP address config variable with the newly added addresses
|
||||
$aio_wp_security->configs->save_config();
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses were saved in the blacklist configuration settings.','all-in-one-wp-security-and-firewall'));
|
||||
|
||||
//Let's check if the Enable Blacklisting flag has been set - If so, we will write the new data to the .htaccess file.
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_blacklisting')=='1')
|
||||
{
|
||||
$write_result = AIOWPSecurity_Utility_Htaccess::write_to_htaccess();
|
||||
if ( $write_result )
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The .htaccess file was successfully modified to include the selected IP addresses.','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
else
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The plugin was unable to write to the .htaccess file. Please edit file manually.','all-in-one-wp-security-and-firewall'));
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Blacklist_Menu - The plugin was unable to write to the .htaccess file.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$blacklist_settings_link = '<a href="admin.php?page='.AIOWPSEC_BLACKLIST_MENU_SLUG.'">Ban Users</a>';
|
||||
$info_msg = '<p>'.__('NOTE: The .htaccess file was not modified because you have disabled the "Enable IP or User Agent Blacklisting" check box.', 'all-in-one-wp-security-and-firewall').
|
||||
'<br />'.sprintf( __('To block these IP addresses you will need to enable the above flag in the %s menu', 'all-in-one-wp-security-and-firewall'), $blacklist_settings_link).'</p>';
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st($info_msg);
|
||||
}
|
||||
}
|
||||
|
||||
function prepare_items()
|
||||
{
|
||||
//First, lets decide how many records per page to show
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
global $wpdb;
|
||||
global $aio_wp_security;
|
||||
$minimum_comments_per_ip = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments');
|
||||
if (empty($minimum_comments_per_ip)) {
|
||||
$minimum_comments_per_ip = 5;
|
||||
}
|
||||
/* -- Ordering parameters -- */
|
||||
//Parameters that are going to be used to order the result
|
||||
isset($_GET["orderby"]) ? $orderby = strip_tags($_GET["orderby"]) : $orderby = '';
|
||||
isset($_GET["order"]) ? $order = strip_tags($_GET["order"]) : $order = '';
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'amount';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
$sql = $wpdb->prepare("SELECT comment_author_IP, COUNT(*) AS amount
|
||||
FROM $wpdb->comments
|
||||
WHERE comment_approved = 'spam'
|
||||
GROUP BY comment_author_IP
|
||||
HAVING amount >= %d
|
||||
ORDER BY $orderby $order
|
||||
", $minimum_comments_per_ip);
|
||||
$data = $wpdb->get_results($sql, ARRAY_A);
|
||||
|
||||
//Get all permamnetly blocked IP addresses
|
||||
$block_list = AIOWPSecurity_Blocking::get_list_blocked_ips();
|
||||
if(!empty($block_list)){
|
||||
foreach($data as $key=>$value){
|
||||
if(in_array($value['comment_author_IP'],$block_list)){
|
||||
$data[$key]['status'] = 'blocked';
|
||||
}
|
||||
}
|
||||
}
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($data);
|
||||
$data = array_slice($data, (($current_page - 1) * $per_page), $per_page);
|
||||
$this->items = $data;
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Locked_IP extends AIOWPSecurity_List_Table {
|
||||
|
||||
function __construct(){
|
||||
global $status, $page;
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct( array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
function column_default($item, $column_name){
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
function column_failed_login_ip($item){
|
||||
$tab = isset($_REQUEST['tab'])?strip_tags($_REQUEST['tab']):'';
|
||||
$delete_lockdown_record = sprintf('admin.php?page=%s&tab=%s&action=%s&lockdown_id=%s', AIOWPSEC_MAIN_MENU_SLUG, $tab, 'delete_blocked_ip', $item['id']);
|
||||
//Add nonce to delete URL
|
||||
$delete_lockdown_record_nonce = wp_nonce_url($delete_lockdown_record, "delete_lockdown_record", "aiowps_nonce");
|
||||
|
||||
$unlock_ip_url = sprintf('admin.php?page=%s&tab=%s&action=%s&lockdown_id=%s', AIOWPSEC_MAIN_MENU_SLUG, $tab, 'unlock_ip', $item['id']);
|
||||
//Add nonce to unlock IP URL
|
||||
$unlock_ip_nonce = wp_nonce_url($unlock_ip_url, "unlock_ip", "aiowps_nonce");
|
||||
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'unlock' => '<a href="'.$unlock_ip_nonce.'" onclick="return confirm(\'Are you sure you want to unlock this address range?\')">Unlock</a>',
|
||||
'delete' => '<a href="'.$delete_lockdown_record_nonce.'" onclick="return confirm(\'Are you sure you want to delete this item?\')">Delete</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['failed_login_ip'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function column_cb($item){
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/ $item['id'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
function get_columns(){
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'failed_login_ip' => __('Locked IP/Range', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_id' => __('User ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_login' => __('Username', 'all-in-one-wp-security-and-firewall'),
|
||||
'lock_reason' => __('Reason', 'all-in-one-wp-security-and-firewall'),
|
||||
'lockdown_date' => __('Date Locked', 'all-in-one-wp-security-and-firewall'),
|
||||
'release_date' => __('Release Date', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
'failed_login_ip' => array('failed_login_ip',false),
|
||||
'user_id' => array('user_id',false),
|
||||
'user_login' => array('user_login',false),
|
||||
'lock_reason' => array('lock_reason',false),
|
||||
'lockdown_date' => array('lockdown_date',false),
|
||||
'release_date' => array('release_date',false)
|
||||
);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
function get_bulk_actions() {
|
||||
$actions = array(
|
||||
'unlock' => __('Unlock', 'all-in-one-wp-security-and-firewall'),
|
||||
'delete' => __('Delete', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
function process_bulk_action() {
|
||||
if('delete'===$this->current_action())
|
||||
{//Process delete bulk actions
|
||||
if(!isset($_REQUEST['item']))
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes','all-in-one-wp-security-and-firewall'));
|
||||
}else
|
||||
{
|
||||
$this->delete_lockdown_records(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
|
||||
if('unlock'===$this->current_action())
|
||||
{//Process unlock bulk actions
|
||||
if(!isset($_REQUEST['item']))
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes','all-in-one-wp-security-and-firewall'));
|
||||
}else
|
||||
{
|
||||
$this->unlock_ip_range(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function will unlock an IP range by modifying the "release_date" column of a record in the "login_lockdown" table
|
||||
*/
|
||||
function unlock_ip_range($entries)
|
||||
{
|
||||
global $wpdb,$aio_wp_security;
|
||||
$lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKDOWN;
|
||||
if (is_array($entries))
|
||||
{
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//Unlock multiple records
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" .implode(",",$entries) .")"; //Create comma separate list for DB operation
|
||||
$unlock_command = "UPDATE ".$lockdown_table." SET release_date = now() WHERE id IN ".$id_list;
|
||||
$result = $wpdb->query($unlock_command);
|
||||
if($result != NULL)
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP entries were unlocked successfully!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
} elseif ($entries != NULL)
|
||||
{
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'unlock_ip'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for unlock IP operation!",4);
|
||||
die(__('Nonce check failed for unlock IP operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
//Unlock single record
|
||||
$unlock_command = $wpdb->prepare( "UPDATE ".$lockdown_table." SET release_date = now() WHERE id = %d", absint($entries) );
|
||||
$result = $wpdb->query($unlock_command);
|
||||
if($result != NULL)
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP entry was unlocked successfully!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will delete selected records from the "login_lockdown" table.
|
||||
* The function accepts either an array of IDs or a single ID
|
||||
*/
|
||||
function delete_lockdown_records($entries)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
$lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKDOWN;
|
||||
if (is_array($entries))
|
||||
{
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//Delete multiple records
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" .implode(",",$entries) .")"; //Create comma separate list for DB operation
|
||||
$delete_command = "DELETE FROM ".$lockdown_table." WHERE id IN ".$id_list;
|
||||
$result = $wpdb->query($delete_command);
|
||||
if($result != NULL)
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st();
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($entries != NULL)
|
||||
{
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'delete_lockdown_record'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for delete lockdown record operation!",4);
|
||||
die(__('Nonce check failed for delete lockdown record operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
//Delete single record
|
||||
$delete_command = "DELETE FROM ".$lockdown_table." WHERE id = '".absint($entries)."'";
|
||||
$result = $wpdb->query($delete_command);
|
||||
if($result != NULL)
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function prepare_items() {
|
||||
/**
|
||||
* First, lets decide how many records per page to show
|
||||
*/
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
global $wpdb;
|
||||
$lockdown_table_name = AIOWPSEC_TBL_LOGIN_LOCKDOWN;
|
||||
|
||||
/* -- Ordering parameters -- */
|
||||
//Parameters that are going to be used to order the result
|
||||
isset($_GET["orderby"]) ? $orderby = strip_tags($_GET["orderby"]): $orderby = '';
|
||||
isset($_GET["order"]) ? $order = strip_tags($_GET["order"]): $order = '';
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'lockdown_date';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
$now = current_time( 'mysql' );
|
||||
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM $lockdown_table_name WHERE (lock_reason=%s OR lock_reason=%s) AND release_date > %s ORDER BY $orderby $order", 'login_fail', '404', $now), ARRAY_A);
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($data);
|
||||
$data = array_slice($data,(($current_page-1)*$per_page),$per_page);
|
||||
$this->items = $data;
|
||||
$this->set_pagination_args( array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Logged_In_Users extends AIOWPSecurity_List_Table {
|
||||
|
||||
function __construct(){
|
||||
global $status, $page;
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct( array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
function column_default($item, $column_name){
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
function column_user_id($item){
|
||||
$tab = strip_tags($_REQUEST['tab']);
|
||||
$force_logout_url = sprintf('admin.php?page=%s&tab=%s&action=%s&logged_in_id=%s&ip_address=%s', AIOWPSEC_USER_LOGIN_MENU_SLUG, $tab, 'force_user_logout', $item['user_id'], $item['ip_address']);
|
||||
//Add nonce to URL
|
||||
$force_logout_nonce = wp_nonce_url($force_logout_url, "force_user_logout", "aiowps_nonce");
|
||||
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'logout' => '<a href="'.$force_logout_nonce.'" onclick="return confirm(\'Are you sure you want to force this user to be logged out of this session?\')">Force Logout</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['user_id'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
function get_columns(){
|
||||
$columns = array(
|
||||
'user_id' => __('User ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'username' => __('Login Name', 'all-in-one-wp-security-and-firewall'),
|
||||
'ip_address' => __('IP Address', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
'user_id' => array('user_id',false),
|
||||
'username' => array('username',false),
|
||||
'ip_address' => array('ip_address',false),
|
||||
);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
function get_bulk_actions() {
|
||||
return array();
|
||||
}
|
||||
|
||||
function process_bulk_action() {
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will force a selected user to be logged out.
|
||||
* The function accepts either an array of IDs or a single ID (TODO - bulk actions not implemented yet!)
|
||||
*/
|
||||
function force_user_logout($user_id, $ip_addr)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
if (is_array($user_id))
|
||||
{
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//TODO - implement bulk action in future release!
|
||||
}
|
||||
}
|
||||
elseif ($user_id != NULL)
|
||||
{
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'force_user_logout'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for force user logout operation!",4);
|
||||
die(__('Nonce check failed for force user logout operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
// Force single user logout
|
||||
$user_id = absint($user_id);
|
||||
$manager = WP_Session_Tokens::get_instance( $user_id );
|
||||
$manager->destroy_all();
|
||||
|
||||
$aio_wp_security->user_login_obj->cleanup_users_online_transient($user_id, $ip_addr);
|
||||
$success_msg = '<div id="message" class="updated fade"><p><strong>';
|
||||
$success_msg .= __('The selected user was logged out successfully!','all-in-one-wp-security-and-firewall');
|
||||
$success_msg .= '</strong></p></div>';
|
||||
_e($success_msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function prepare_items() {
|
||||
//First, lets decide how many records per page to show
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
global $wpdb;
|
||||
global $aio_wp_security;
|
||||
|
||||
if (AIOWPSecurity_Utility::is_multisite_install()) {
|
||||
$current_blog_id = get_current_blog_id();
|
||||
$logged_in_users = AIOWPSecurity_User_Login::get_subsite_logged_in_users($current_blog_id);
|
||||
} else {
|
||||
$logged_in_users = get_transient('users_online');
|
||||
}
|
||||
if(empty($logged_in_users)){
|
||||
$logged_in_users = array(); //If no transient found set to empty array
|
||||
}else{
|
||||
foreach ($logged_in_users as $key=>$val)
|
||||
{
|
||||
$userdata = get_userdata($val['user_id']);
|
||||
$username = $userdata->user_login;
|
||||
$val['username'] = $username;
|
||||
$logged_in_users[$key] = $val;
|
||||
}
|
||||
}
|
||||
$data = $logged_in_users;
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($data);
|
||||
$data = array_slice($data,(($current_page-1)*$per_page),$per_page);
|
||||
$this->items = $data;
|
||||
$this->set_pagination_args( array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Login_Failed_Attempts extends AIOWPSecurity_List_Table {
|
||||
|
||||
function __construct(){
|
||||
global $status, $page;
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct( array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
function column_default($item, $column_name){
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
function column_login_attempt_ip($item){
|
||||
$tab = strip_tags($_REQUEST['tab']);
|
||||
$delete_url = sprintf('admin.php?page=%s&tab=%s&action=%s&failed_login_id=%s', AIOWPSEC_USER_LOGIN_MENU_SLUG, $tab, 'delete_failed_login_rec', $item['id']);
|
||||
//Add nonce to delete URL
|
||||
$delete_url_nonce = wp_nonce_url($delete_url, "delete_failed_login_rec", "aiowps_nonce");
|
||||
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'delete' => '<a href="'.$delete_url_nonce.'" onclick="return confirm(\'Are you sure you want to delete this item?\')">Delete</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['login_attempt_ip'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function column_cb($item){
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/ $item['id'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
function get_columns(){
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'login_attempt_ip' => __('Login IP Range', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_id' => __('User ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_login' => __('Username', 'all-in-one-wp-security-and-firewall'),
|
||||
'failed_login_date' => __('Date', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
'login_attempt_ip' => array('login_attempt_ip',false),
|
||||
'user_id' => array('user_id',false),
|
||||
'user_login' => array('user_login',false),
|
||||
'failed_login_date' => array('failed_login_date',false),
|
||||
);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
function get_bulk_actions() {
|
||||
$actions = array(
|
||||
'delete' => 'Delete'
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
function process_bulk_action() {
|
||||
global $aio_wp_security;
|
||||
if('delete'===$this->current_action())
|
||||
{//Process delete bulk actions
|
||||
if(!isset($_REQUEST['item']))
|
||||
{
|
||||
$error_msg = '<div id="message" class="error"><p><strong>';
|
||||
$error_msg .= __('Please select some records using the checkboxes','all-in-one-wp-security-and-firewall');
|
||||
$error_msg .= '</strong></p></div>';
|
||||
_e($error_msg);
|
||||
} else{
|
||||
$this->delete_login_failed_records(($_REQUEST['item']));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This function will delete selected records from the "failed_logins" table.
|
||||
* The function accepts either an array of IDs or a single ID
|
||||
*/
|
||||
function delete_login_failed_records($entries)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
$failed_login_table = AIOWPSEC_TBL_FAILED_LOGINS;
|
||||
if (is_array($entries))
|
||||
{
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//Delete multiple records
|
||||
$tab = strip_tags($_REQUEST['tab']);
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" .implode(",",$entries) .")"; //Create comma separate list for DB operation
|
||||
$delete_command = "DELETE FROM ".$failed_login_table." WHERE ID IN ".$id_list;
|
||||
$result = $wpdb->query($delete_command);
|
||||
if($result !== false)
|
||||
{
|
||||
$redir_url = sprintf('admin.php?page=%s&tab=%s&bulk_count=%s', AIOWPSEC_USER_LOGIN_MENU_SLUG, $tab, count($entries));
|
||||
AIOWPSecurity_Utility::redirect_to_url($redir_url);
|
||||
} else {
|
||||
// error on bulk delete
|
||||
$aio_wp_security->debug_logger->log_debug("DB error: ".$wpdb->last_error,4);
|
||||
$redir_url = sprintf('admin.php?page=%s&tab=%s&bulk_error=%s', AIOWPSEC_USER_LOGIN_MENU_SLUG, $tab, 1);
|
||||
AIOWPSecurity_Utility::redirect_to_url($redir_url);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($entries != NULL)
|
||||
{
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'delete_failed_login_rec'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for delete failed login record operation!",4);
|
||||
die(__('Nonce check failed for delete failed login record operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
//Delete single record
|
||||
$delete_command = "DELETE FROM ".$failed_login_table." WHERE ID = '".absint($entries)."'";
|
||||
$result = $wpdb->query($delete_command);
|
||||
if($result !== false)
|
||||
{
|
||||
$success_msg = '<div id="message" class="updated fade"><p><strong>';
|
||||
$success_msg .= __('The selected entry was deleted successfully!','all-in-one-wp-security-and-firewall');
|
||||
$success_msg .= '</strong></p></div>';
|
||||
_e($success_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function prepare_items($ignore_pagination = false) {
|
||||
/**
|
||||
* First, lets decide how many records per page to show
|
||||
*/
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
$search = isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '';
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
global $wpdb;
|
||||
$failed_logins_table_name = AIOWPSEC_TBL_FAILED_LOGINS;
|
||||
|
||||
/* -- Ordering parameters -- */
|
||||
//Parameters that are going to be used to order the result
|
||||
isset($_GET["orderby"]) ? $orderby = strip_tags($_GET["orderby"]) : $orderby = '';
|
||||
isset($_GET["order"]) ? $order = strip_tags($_GET["order"]) : $order = '';
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'failed_login_date';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
if(empty($search)) {
|
||||
$data = $wpdb->get_results("SELECT * FROM " . $failed_logins_table_name . " ORDER BY $orderby $order", ARRAY_A);
|
||||
} else {
|
||||
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM $failed_logins_table_name WHERE `user_login` LIKE '%%%s%%' OR `login_attempt_ip` LIKE '%%%s%%' ORDER BY $orderby $order", $search, $search), ARRAY_A);
|
||||
}
|
||||
|
||||
if (!$ignore_pagination) {
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($data);
|
||||
$data = array_slice($data, (($current_page - 1) * $per_page), $per_page);
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
$this->items = $data;
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Blocked_IP extends AIOWPSecurity_List_Table
|
||||
{
|
||||
|
||||
function __construct()
|
||||
{
|
||||
global $status, $page;
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
function column_default($item, $column_name)
|
||||
{
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
function column_id($item)
|
||||
{
|
||||
$tab = isset($_REQUEST['tab']) ? strip_tags($_REQUEST['tab']) : '';
|
||||
//Add nonce to delete URL
|
||||
$unblock_ip_url = sprintf('admin.php?page=%s&tab=%s&action=%s&blocked_id=%s', AIOWPSEC_MAIN_MENU_SLUG, $tab, 'unblock_ip', $item['id']);
|
||||
//Add nonce to unlock IP URL
|
||||
$unblock_ip_nonce = wp_nonce_url($unblock_ip_url, "unblock_ip", "aiowps_nonce");
|
||||
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'unblock' => '<a href="' . $unblock_ip_nonce . '" onclick="return confirm(\'Are you sure you want to unblock this IP address?\')">Unblock</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/
|
||||
$item['id'],
|
||||
/*$2%s*/
|
||||
$this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function column_cb($item)
|
||||
{
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/
|
||||
$this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/
|
||||
$item['id'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
function get_columns()
|
||||
{
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'id' => 'ID',
|
||||
'blocked_ip' => __('Blocked IP', 'all-in-one-wp-security-and-firewall'),
|
||||
'block_reason' => __('Reason', 'all-in-one-wp-security-and-firewall'),
|
||||
'blocked_date' => __('Date', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
function get_sortable_columns()
|
||||
{
|
||||
$sortable_columns = array(
|
||||
'id' => array('id', false),
|
||||
'blocked_ip' => array('blocked_ip', false),
|
||||
'block_reason' => array('block_reason', false),
|
||||
'blocked_date' => array('blocked_date', false)
|
||||
);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
function get_bulk_actions()
|
||||
{
|
||||
$actions = array(
|
||||
'unblock' => __('Unblock', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
function process_bulk_action()
|
||||
{
|
||||
if ('unblock' === $this->current_action()) {//Process unlock bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
$this->unblock_ip_address(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function will delete selected records from the "AIOWPSEC_TBL_PERM_BLOCK" table.
|
||||
* The function accepts either an array of IDs or a single ID
|
||||
*/
|
||||
function unblock_ip_address($entries)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
if (is_array($entries)) {
|
||||
if (isset($_REQUEST['_wp_http_referer'])) {
|
||||
// multiple records
|
||||
$tab = strip_tags($_REQUEST['tab']);
|
||||
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" . implode(",", $entries) . ")"; //Create comma separate list for DB operation
|
||||
$delete_command = "DELETE FROM " . AIOWPSEC_TBL_PERM_BLOCK . " WHERE id IN " . $id_list;
|
||||
$result = $wpdb->query($delete_command);
|
||||
if($result !== false)
|
||||
{
|
||||
$redir_url = sprintf('admin.php?page=%s&tab=%s&bulk_count=%s', AIOWPSEC_MAIN_MENU_SLUG, $tab, count($entries));
|
||||
AIOWPSecurity_Utility::redirect_to_url($redir_url);
|
||||
} else {
|
||||
// error on bulk delete
|
||||
$aio_wp_security->debug_logger->log_debug("DB error: ".$wpdb->last_error,4);
|
||||
$redir_url = sprintf('admin.php?page=%s&tab=%s&bulk_error=%s', AIOWPSEC_MAIN_MENU_SLUG, $tab, 1);
|
||||
AIOWPSecurity_Utility::redirect_to_url($redir_url);
|
||||
|
||||
}
|
||||
}
|
||||
} elseif ($entries != NULL) {
|
||||
$nonce = isset($_GET['aiowps_nonce']) ? $_GET['aiowps_nonce'] : '';
|
||||
if (!isset($nonce) || !wp_verify_nonce($nonce, 'unblock_ip')) {
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for unblock IP operation!", 4);
|
||||
die(__('Nonce check failed for unblock IP operation!', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
//Delete single record
|
||||
$delete_command = "DELETE FROM " . AIOWPSEC_TBL_PERM_BLOCK . " WHERE id = '" . absint($entries) . "'";
|
||||
$result = $wpdb->query($delete_command);
|
||||
if ($result !== false) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function prepare_items()
|
||||
{
|
||||
/**
|
||||
* First, lets decide how many records per page to show
|
||||
*/
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
$search = isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '';
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
global $wpdb;
|
||||
$block_table_name = AIOWPSEC_TBL_PERM_BLOCK;
|
||||
|
||||
/* -- Ordering parameters -- */
|
||||
//Parameters that are going to be used to order the result
|
||||
isset($_GET["orderby"]) ? $orderby = strip_tags($_GET["orderby"]) : $orderby = '';
|
||||
isset($_GET["order"]) ? $order = strip_tags($_GET["order"]) : $order = '';
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'id';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
if(empty($search)) {
|
||||
$data = $wpdb->get_results("SELECT * FROM " . $block_table_name . " ORDER BY $orderby $order", ARRAY_A);
|
||||
} else {
|
||||
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM " . $block_table_name . " WHERE `blocked_ip` LIKE '%%%s%%' OR `block_reason` LIKE '%%%s%%' OR `country_origin` LIKE '%%%s%%' OR `blocked_date` LIKE '%%%s%%' ORDER BY $orderby $order", $search, $search, $search, $search), ARRAY_A);
|
||||
}
|
||||
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($data);
|
||||
$data = array_slice($data, (($current_page - 1) * $per_page), $per_page);
|
||||
$this->items = $data;
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Registered_Users extends AIOWPSecurity_List_Table {
|
||||
|
||||
function __construct(){
|
||||
global $status, $page;
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct( array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
function column_default($item, $column_name){
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
function column_ID($item){
|
||||
//$tab = strip_tags($_REQUEST['tab']);
|
||||
$delete_url = sprintf('admin.php?page=%s&action=%s&user_id=%s', AIOWPSEC_USER_REGISTRATION_MENU_SLUG, 'delete_acct', $item['ID']);
|
||||
//Add nonce to delete URL
|
||||
$delete_url_nonce = wp_nonce_url($delete_url, "delete_user_acct", "aiowps_nonce");
|
||||
|
||||
$block_ip = sprintf('admin.php?page=%s&action=%s&ip_address=%s', AIOWPSEC_USER_REGISTRATION_MENU_SLUG, 'block_ip', $item['ip_address']);
|
||||
//Add nonce to block IP
|
||||
$block_ip_nonce = wp_nonce_url($block_ip, "block_ip", "aiowps_nonce");
|
||||
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'view' => sprintf('<a href="user-edit.php?user_id=%s" target="_blank">View</a>',$item['ID']),
|
||||
'approve_acct' => sprintf('<a href="admin.php?page=%s&action=%s&user_id=%s" onclick="return confirm(\'Are you sure you want to approve this account?\')">Approve</a>',AIOWPSEC_USER_REGISTRATION_MENU_SLUG,'approve_acct',$item['ID']),
|
||||
'delete_acct' => '<a href="'.$delete_url_nonce.'" onclick="return confirm(\'Are you sure you want to delete this account?\')">Delete</a>',
|
||||
'block_ip' => '<a href="'.$block_ip_nonce.'" onclick="return confirm(\'Are you sure you want to block this IP address?\')">Block IP</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['ID'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
function column_ip_address($item){
|
||||
if (AIOWPSecurity_Blocking::is_ip_blocked($item['ip_address'])){
|
||||
return $item['ip_address'].'<br /><span class="aiowps-label aiowps-label-success">'.__('blocked','WPS').'</span>';
|
||||
} else{
|
||||
return $item['ip_address'];
|
||||
}
|
||||
}
|
||||
|
||||
function column_cb($item){
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/ $item['ID'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function get_columns(){
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'ID' => __('User ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_login' => __('Login Name', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_email' => __('Email', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_registered' => __('Register Date', 'all-in-one-wp-security-and-firewall'),
|
||||
'account_status' => __('Account Status', 'all-in-one-wp-security-and-firewall'),
|
||||
'ip_address' => __('IP Address', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
// 'ID' => array('ID',false),
|
||||
// 'user_login' => array('user_login',false),
|
||||
// 'user_email' => array('user_email',false),
|
||||
// 'user_registered' => array('user_registered',false),
|
||||
// 'account_status' => array('account_status',false),
|
||||
);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
function get_bulk_actions() {
|
||||
$actions = array(
|
||||
'approve' => 'Approve',
|
||||
'delete' => 'Delete',
|
||||
'block' => 'Block IP'
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
function process_bulk_action() {
|
||||
if('approve'===$this->current_action())
|
||||
{//Process approve bulk actions
|
||||
if(!isset($_REQUEST['item']))
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes','all-in-one-wp-security-and-firewall'));
|
||||
}else
|
||||
{
|
||||
$this->approve_selected_accounts(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
|
||||
if('delete'===$this->current_action())
|
||||
{//Process delete bulk actions
|
||||
if(!isset($_REQUEST['item']))
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes','all-in-one-wp-security-and-firewall'));
|
||||
}else
|
||||
{
|
||||
$this->delete_selected_accounts(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
|
||||
if('block'===$this->current_action())
|
||||
{//Process block bulk actions
|
||||
if(!isset($_REQUEST['item']))
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes','all-in-one-wp-security-and-firewall'));
|
||||
}else
|
||||
{
|
||||
$this->block_selected_ips(($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function approve_selected_accounts($entries)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
$meta_key = 'aiowps_account_status';
|
||||
$meta_value = 'approved'; //set account status
|
||||
$failed_accts = ''; //string to store comma separated accounts which failed to update
|
||||
$at_least_one_updated = false;
|
||||
if (is_array($entries))
|
||||
{
|
||||
//Let's go through each entry and approve
|
||||
foreach($entries as $user_id)
|
||||
{
|
||||
$result = update_user_meta($user_id, $meta_key, $meta_value);
|
||||
if($result === false)
|
||||
{
|
||||
$failed_accts .= ' '.$user_id.',';
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::approve_selected_accounts() - could not approve account ID: $user_id",4);
|
||||
}else{
|
||||
$at_least_one_updated = true;
|
||||
$user = get_user_by('id', $user_id);
|
||||
if($user === false){
|
||||
//don't send mail
|
||||
}else{
|
||||
$email_msg = '';
|
||||
$to_email_address = $user->user_email;
|
||||
$subject = '['.get_option('siteurl').'] '. __('Your account is now active','all-in-one-wp-security-and-firewall');
|
||||
$email_msg .= __('Your account with user ID:','all-in-one-wp-security-and-firewall').$user->ID.__(' is now active','all-in-one-wp-security-and-firewall')."\n";
|
||||
$site_title = get_bloginfo( 'name' );
|
||||
$from_name = empty($site_title)?'WordPress':$site_title;
|
||||
$subject = apply_filters( 'aiowps_register_approval_email_subject', $subject );
|
||||
$email_msg = apply_filters( 'aiowps_register_approval_email_msg', $email_msg, $user ); //also pass the WP_User object
|
||||
$from_name = apply_filters( 'aiowps_register_approval_email_from_name', $from_name );
|
||||
|
||||
$email_header = 'From: '.$from_name.' <'.get_bloginfo('admin_email').'>' . "\r\n\\";
|
||||
$sendMail = wp_mail($to_email_address, $subject, $email_msg, $email_header);
|
||||
if(FALSE === $sendMail){
|
||||
$aio_wp_security->debug_logger->log_debug("Manual account approval notification email failed to send to ".$to_email_address,4);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($at_least_one_updated){
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected accounts were approved successfully!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
if ($failed_accts != ''){//display any failed account updates
|
||||
rtrim($failed_accts);
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The following accounts failed to update successfully: ','all-in-one-wp-security-and-firewall').$failed_accts);
|
||||
}
|
||||
} elseif ($entries != NULL)
|
||||
{
|
||||
//Approve single account
|
||||
$result = update_user_meta($entries, $meta_key, $meta_value);
|
||||
if($result)
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected account was approved successfully!','all-in-one-wp-security-and-firewall'));
|
||||
$user = get_user_by('id', $entries);
|
||||
$to_email_address = $user->user_email;
|
||||
$email_msg = '';
|
||||
$subject = '['.get_option('siteurl').'] '. __('Your account is now active','all-in-one-wp-security-and-firewall');
|
||||
$email_msg .= __('Your account with username: ','all-in-one-wp-security-and-firewall').$user->user_login.__(' is now active','all-in-one-wp-security-and-firewall')."\n";
|
||||
$site_title = get_bloginfo( 'name' );
|
||||
$from_name = empty($site_title)?'WordPress':$site_title;
|
||||
$subject = apply_filters( 'aiowps_register_approval_email_subject', $subject );
|
||||
$email_msg = apply_filters( 'aiowps_register_approval_email_msg', $email_msg, $user ); //also pass the WP_User object
|
||||
$from_name = apply_filters( 'aiowps_register_approval_email_from_name', $from_name );
|
||||
|
||||
$email_header = 'From: '.$from_name.' <'.get_bloginfo('admin_email').'>' . "\r\n\\";
|
||||
$sendMail = wp_mail($to_email_address, $subject, $email_msg, $email_header);
|
||||
if(FALSE === $sendMail){
|
||||
$aio_wp_security->debug_logger->log_debug("Manual account approval notification email failed to send to ".$to_email_address,4);
|
||||
}
|
||||
|
||||
|
||||
}else if($result === false){
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::approve_selected_accounts() - could not approve account ID: $user_id",4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function delete_selected_accounts($entries)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
if (is_array($entries))
|
||||
{
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//Let's go through each entry and delete account
|
||||
foreach($entries as $user_id)
|
||||
{
|
||||
$result = wp_delete_user($user_id);
|
||||
if($result !== true)
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::delete_selected_accounts() - could not delete account ID: $user_id",4);
|
||||
}
|
||||
}
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected accounts were deleted successfully!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
} elseif ($entries != NULL)
|
||||
{
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'delete_user_acct'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for delete registered user account operation!",4);
|
||||
die(__('Nonce check failed for delete registered user account operation!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
//Delete single account
|
||||
|
||||
$result = wp_delete_user($entries);
|
||||
if($result === true)
|
||||
{
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected account was deleted successfully!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::delete_selected_accounts() - could not delete account ID: $entries",4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function block_selected_ips($entries)
|
||||
{
|
||||
global $wpdb, $aio_wp_security;
|
||||
if (is_array($entries))
|
||||
{
|
||||
if (isset($_REQUEST['_wp_http_referer']))
|
||||
{
|
||||
//Let's go through each entry and block IP
|
||||
foreach($entries as $id)
|
||||
{
|
||||
$ip_address = get_user_meta($id, 'aiowps_registrant_ip', true);
|
||||
$result = AIOWPSecurity_Blocking::add_ip_to_block_list($ip_address, 'registration_spam');
|
||||
if($result === false)
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::block_selected_ips() - could not block IP : $ip_address",4);
|
||||
}
|
||||
}
|
||||
$msg = __('The selected IP addresses were successfully added to the permanent block list!','all-in-one-wp-security-and-firewall');
|
||||
$msg .= ' <a href="admin.php?page='.AIOWPSEC_MAIN_MENU_SLUG.'&tab=tab4" target="_blank">'.__('View Blocked IPs','all-in-one-wp-security-and-firewall').'</a>';
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st($msg);
|
||||
}
|
||||
} elseif ($entries != NULL)
|
||||
{
|
||||
$nonce=isset($_GET['aiowps_nonce'])?$_GET['aiowps_nonce']:'';
|
||||
if (!isset($nonce) ||!wp_verify_nonce($nonce, 'block_ip'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for block IP operation of registered user!",4);
|
||||
die(__('Nonce check failed for block IP operation of registered user!','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
//Block single IP
|
||||
$result = AIOWPSecurity_Blocking::add_ip_to_block_list($entries, 'registration_spam');
|
||||
if($result === true)
|
||||
{
|
||||
$msg = __('The selected IP was successfully added to the permanent block list!','all-in-one-wp-security-and-firewall');
|
||||
$msg .= ' <a href="admin.php?page='.AIOWPSEC_MAIN_MENU_SLUG.'&tab=tab4" target="_blank">'.__('View Blocked IPs','all-in-one-wp-security-and-firewall').'</a>';
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st($msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::block_selected_ips() - could not block IP: $entries",4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function prepare_items() {
|
||||
//First, lets decide how many records per page to show
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
$search = isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '';
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
//Get registered users which have the special 'aiowps_account_status' meta key set to 'pending'
|
||||
$data = $this->get_registered_user_data('pending', $search);
|
||||
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($data);
|
||||
$data = array_slice($data,(($current_page-1)*$per_page),$per_page);
|
||||
$this->items = $data;
|
||||
$this->set_pagination_args( array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
|
||||
//Returns all users who have the special 'aiowps_account_status' meta key
|
||||
function get_registered_user_data($status='', $search='')
|
||||
{
|
||||
$user_fields = array( 'ID', 'user_login', 'user_email', 'user_registered');
|
||||
$user_query = new WP_User_Query(array('meta_key' => 'aiowps_account_status', 'meta_value' => $status, 'fields' => $user_fields));
|
||||
$user_results = $user_query->results;
|
||||
|
||||
$final_data = array();
|
||||
foreach ($user_results as $user)
|
||||
{
|
||||
$temp_array = get_object_vars($user); //Turn the object into array
|
||||
$temp_array['account_status'] = get_user_meta($temp_array['ID'], 'aiowps_account_status', true);
|
||||
$ip = get_user_meta($temp_array['ID'], 'aiowps_registrant_ip', true);
|
||||
$temp_array['ip_address'] = empty($ip)?'':$ip;
|
||||
if(empty($search)) {
|
||||
$final_data[] = $temp_array;
|
||||
} else {
|
||||
$input = preg_quote($search, '~'); // don't forget to quote input string!
|
||||
|
||||
$result = preg_grep('~' . $input . '~', $temp_array);
|
||||
if(!empty($result)) $final_data[] = $temp_array;
|
||||
}
|
||||
}
|
||||
return $final_data;
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Maintenance_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
var $menu_page_slug = AIOWPSEC_MAINTENANCE_MENU_SLUG;
|
||||
|
||||
/* Specify all the tabs of this menu in the following array */
|
||||
var $menu_tabs;
|
||||
|
||||
var $menu_tabs_handler = array(
|
||||
'tab1' => 'render_tab1',
|
||||
);
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->render_menu_page();
|
||||
}
|
||||
|
||||
function set_menu_tabs()
|
||||
{
|
||||
$this->menu_tabs = array(
|
||||
'tab1' => __('Visitor Lockout', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}
|
||||
|
||||
function get_current_tab()
|
||||
{
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
$tab = isset( $_GET['tab'] ) ? sanitize_text_field($_GET['tab']) : $tab_keys[0];
|
||||
return $tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders our tabs of this menu as nav items
|
||||
*/
|
||||
function render_menu_tabs()
|
||||
{
|
||||
$current_tab = $this->get_current_tab();
|
||||
|
||||
echo '<h2 class="nav-tab-wrapper">';
|
||||
foreach ( $this->menu_tabs as $tab_key => $tab_caption )
|
||||
{
|
||||
$active = $current_tab == $tab_key ? 'nav-tab-active' : '';
|
||||
echo '<a class="nav-tab ' . $active . '" href="?page=' . $this->menu_page_slug . '&tab=' . $tab_key . '">' . $tab_caption . '</a>';
|
||||
}
|
||||
echo '</h2>';
|
||||
}
|
||||
|
||||
/*
|
||||
* The menu rendering goes here
|
||||
*/
|
||||
function render_menu_page()
|
||||
{
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>'.__('Maintenance','all-in-one-wp-security-and-firewall').'</h2>';//Interface title
|
||||
$this->set_menu_tabs();
|
||||
$tab = $this->get_current_tab();
|
||||
$this->render_menu_tabs();
|
||||
?>
|
||||
<div id="poststuff"><div id="post-body">
|
||||
<?php
|
||||
//$tab_keys = array_keys($this->menu_tabs);
|
||||
call_user_func(array(&$this, $this->menu_tabs_handler[$tab]));
|
||||
?>
|
||||
</div></div>
|
||||
</div><!-- end of wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab1()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
$maint_msg = '';
|
||||
if(isset($_POST['aiowpsec_save_site_lockout']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-site-lockout'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on site lockout feature settings save!",4);
|
||||
die("Nonce check failed on site lockout feature settings save!");
|
||||
}
|
||||
|
||||
//Save settings
|
||||
$aio_wp_security->configs->set_value('aiowps_site_lockout',isset($_POST["aiowps_site_lockout"])?'1':'');
|
||||
$maint_msg = htmlentities(stripslashes($_POST['aiowps_site_lockout_msg']), ENT_COMPAT, "UTF-8");
|
||||
$aio_wp_security->configs->set_value('aiowps_site_lockout_msg',$maint_msg);//Text area/msg box
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
$this->show_msg_updated(__('Site lockout feature settings saved!', 'all-in-one-wp-security-and-firewall'));
|
||||
|
||||
}
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('General Visitor Lockout', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-site-lockout'); ?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('This feature allows you to put your site into "maintenance mode" by locking down the front-end to all visitors except logged in users with super admin privileges.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p>'.__('Locking your site down to general visitors can be useful if you are investigating some issues on your site or perhaps you might be doing some maintenance and wish to keep out all traffic for security reasons.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Front-end Lockout', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_site_lockout" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_site_lockout')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want all visitors except those who are logged in as administrator to be locked out of the front-end of your site.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enter a Message:', 'all-in-one-wp-security-and-firewall')?></th>
|
||||
<td>
|
||||
<?php
|
||||
$aiowps_site_lockout_msg_raw = $aio_wp_security->configs->get_value('aiowps_site_lockout_msg');
|
||||
if(empty($aiowps_site_lockout_msg_raw)){
|
||||
$aiowps_site_lockout_msg_raw = 'This site is currently not available. Please try again later.';
|
||||
}
|
||||
$aiowps_site_lockout_msg = html_entity_decode($aiowps_site_lockout_msg_raw, ENT_COMPAT, "UTF-8");
|
||||
$aiowps_site_lockout_msg_settings = array('textarea_name' => 'aiowps_site_lockout_msg');
|
||||
wp_editor($aiowps_site_lockout_msg, "aiowps_site_lockout_msg_editor_content", $aiowps_site_lockout_msg_settings);
|
||||
?>
|
||||
<br />
|
||||
<span class="description"><?php _e('Enter a message you wish to display to visitors when your site is in maintenance mode.','all-in-one-wp-security-and-firewall');?></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="submit">
|
||||
<input type="submit" class="button-primary" name="aiowpsec_save_site_lockout" value="<?php _e('Save Site Lockout Settings', 'all-in-one-wp-security-and-firewall'); ?>" />
|
||||
</div>
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
} //end class
|
||||
@@ -1,292 +0,0 @@
|
||||
<?php
|
||||
if(!defined('ABSPATH')){
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Misc_Options_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
var $menu_page_slug = AIOWPSEC_MISC_MENU_SLUG;
|
||||
|
||||
/* Specify all the tabs of this menu in the following array */
|
||||
var $menu_tabs;
|
||||
|
||||
var $menu_tabs_handler = array(
|
||||
'tab1' => 'render_tab1',
|
||||
'tab2' => 'render_tab2',
|
||||
'tab3' => 'render_tab3',
|
||||
'tab4' => 'render_tab4',
|
||||
);
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->render_menu_page();
|
||||
}
|
||||
|
||||
function set_menu_tabs()
|
||||
{
|
||||
$this->menu_tabs = array(
|
||||
'tab1' => __('Copy Protection', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab2' => __('Frames', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab3' => __('Users Enumeration', 'all-in-one-wp-security-and-firewall'),
|
||||
'tab4' => __('WP REST API', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}
|
||||
|
||||
function get_current_tab()
|
||||
{
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
$tab = isset( $_GET['tab'] ) ? sanitize_text_field($_GET['tab']) : $tab_keys[0];
|
||||
return $tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders our tabs of this menu as nav items
|
||||
*/
|
||||
function render_menu_tabs()
|
||||
{
|
||||
$current_tab = $this->get_current_tab();
|
||||
|
||||
echo '<h2 class="nav-tab-wrapper">';
|
||||
foreach ( $this->menu_tabs as $tab_key => $tab_caption )
|
||||
{
|
||||
$active = $current_tab == $tab_key ? 'nav-tab-active' : '';
|
||||
echo '<a class="nav-tab ' . $active . '" href="?page=' . $this->menu_page_slug . '&tab=' . $tab_key . '">' . $tab_caption . '</a>';
|
||||
}
|
||||
echo '</h2>';
|
||||
}
|
||||
|
||||
/*
|
||||
* The menu rendering goes here
|
||||
*/
|
||||
function render_menu_page()
|
||||
{
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>'.__('Miscellaneous','all-in-one-wp-security-and-firewall').'</h2>';//Interface title
|
||||
$this->set_menu_tabs();
|
||||
$tab = $this->get_current_tab();
|
||||
$this->render_menu_tabs();
|
||||
?>
|
||||
<div id="poststuff"><div id="post-body">
|
||||
<?php
|
||||
//$tab_keys = array_keys($this->menu_tabs);
|
||||
call_user_func(array(&$this, $this->menu_tabs_handler[$tab]));
|
||||
?>
|
||||
</div></div>
|
||||
</div><!-- end of wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab1()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
$maint_msg = '';
|
||||
if(isset($_POST['aiowpsec_save_copy_protection']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-copy-protection'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on copy protection feature settings save!",4);
|
||||
die("Nonce check failed on copy protection feature settings save!");
|
||||
}
|
||||
|
||||
//Save settings
|
||||
$aio_wp_security->configs->set_value('aiowps_copy_protection',isset($_POST["aiowps_copy_protection"])?'1':'');
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
$this->show_msg_updated(__('Copy Protection feature settings saved!', 'all-in-one-wp-security-and-firewall'));
|
||||
|
||||
}
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Disable The Ability To Copy Text', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-copy-protection'); ?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('This feature allows you to disable the ability to select and copy text from your front end.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p>'.__('When admin user is logged in, the feature is automatically disabled for his session.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable Copy Protection', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_copy_protection" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_copy_protection')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to disable the "Right Click", "Text Selection" and "Copy" option on the front end of your site.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="submit">
|
||||
<input type="submit" class="button-primary" name="aiowpsec_save_copy_protection" value="<?php _e('Save Copy Protection Settings', 'all-in-one-wp-security-and-firewall'); ?>" />
|
||||
</div>
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab2()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
$maint_msg = '';
|
||||
if(isset($_POST['aiowpsec_save_frame_display_prevent']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-prevent-display-frame'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on prevent display inside frame feature settings save!",4);
|
||||
die("Nonce check failed on prevent display inside frame feature settings save!");
|
||||
}
|
||||
|
||||
//Save settings
|
||||
$aio_wp_security->configs->set_value('aiowps_prevent_site_display_inside_frame',isset($_POST["aiowps_prevent_site_display_inside_frame"])?'1':'');
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
$this->show_msg_updated(__('Frame Display Prevention feature settings saved!', 'all-in-one-wp-security-and-firewall'));
|
||||
|
||||
}
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Prevent Your Site From Being Displayed In a Frame', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-prevent-display-frame'); ?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('This feature allows you to prevent other sites from displaying any of your content via a frame or iframe.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p>'.__('When enabled, this feature will set the "X-Frame-Options" paramater to "sameorigin" in the HTTP header.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Enable iFrame Protection', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_prevent_site_display_inside_frame" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_prevent_site_display_inside_frame')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to stop other sites from displaying your content in a frame or iframe.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="submit">
|
||||
<input type="submit" class="button-primary" name="aiowpsec_save_frame_display_prevent" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall'); ?>" />
|
||||
</div>
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab3()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
$maint_msg = '';
|
||||
if(isset($_POST['aiowpsec_save_users_enumeration']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-users-enumeration'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on prevent users enumeration feature settings save!",4);
|
||||
die("Nonce check failed on prevent users enumeration feature settings save!");
|
||||
}
|
||||
|
||||
//Save settings
|
||||
$aio_wp_security->configs->set_value('aiowps_prevent_users_enumeration',isset($_POST["aiowps_prevent_users_enumeration"])?'1':'');
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
$this->show_msg_updated(__('Users Enumeration Prevention feature settings saved!', 'all-in-one-wp-security-and-firewall'));
|
||||
|
||||
}
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Prevent Users Enumeration', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-users-enumeration'); ?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('This feature allows you to prevent external users/bots from fetching the user info with urls like "/?author=1".', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p>'.__('When enabled, this feature will print a "forbidden" error rather than the user information.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Disable Users Enumeration', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_prevent_users_enumeration" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_prevent_users_enumeration')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to stop users enumeration.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="submit">
|
||||
<input type="submit" class="button-primary" name="aiowpsec_save_users_enumeration" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall'); ?>" />
|
||||
</div>
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
function render_tab4()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
$maint_msg = '';
|
||||
if(isset($_POST['aiowpsec_save_rest_settings']))
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-rest-settings'))
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on REST API security feature settings save!",4);
|
||||
die("Nonce check failed on REST API security feature settings save!");
|
||||
}
|
||||
|
||||
//Save settings
|
||||
$aio_wp_security->configs->set_value('aiowps_disallow_unauthorized_rest_requests',isset($_POST["aiowps_disallow_unauthorized_rest_requests"])?'1':'');
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
$this->show_msg_updated(__('WP REST API Security feature settings saved!', 'all-in-one-wp-security-and-firewall'));
|
||||
|
||||
}
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-rest-settings'); ?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('This feature allows you to block WordPress REST API access for unauthorized requests.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo '<p>'.__('When enabled this feature will only allow REST requests to be processed if the user is logged in.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
<div class="aio_orange_box">
|
||||
<p>
|
||||
<?php
|
||||
echo __('Beware that if you are using other plugins which have registered REST endpoints (eg, Contact Form 7), then this feature will also block REST requests used by these plugins if the user is not logged in.'
|
||||
. ' It is recommended that you leave this feature disabled if you want uninterrupted functionality for such plugins.', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Disallow Unauthorized REST Requests', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input name="aiowps_disallow_unauthorized_rest_requests" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_disallow_unauthorized_rest_requests')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to stop REST API access for non-logged in requests.', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="submit">
|
||||
<input type="submit" class="button-primary" name="aiowpsec_save_rest_settings" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall'); ?>" />
|
||||
</div>
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
} //end class
|
||||
Algunos archivos no se mostraron porque demasiados archivos han cambiado en esta diferencia Ver más
Referencia en una nueva incidencia
Block a user