modified
Este commit está contenido en:
@@ -36,7 +36,7 @@ services:
|
||||
container_name: mysql-wordpress
|
||||
hostname: mysql-wordpress
|
||||
restart: always
|
||||
command: ["mysqld", "--character-set-server=utf8", "--collation-server=utf8_general_ci", "--default-time-zone=+00:00","--explicit_defaults_for_timestamp", "--default-authentication-plugin=mysql_native_password"]
|
||||
command: ["mysqld", "--character-set-server=utf8", "--collation-server=utf8_general_ci", "--default-time-zone=+00:00","--explicit_defaults_for_timestamp", "--default-authentication-plugin=mysql_native_password", "--innodb_file_per_table=ON", "--innodb_stats_on_metadata=OFF", "--innodb_buffer_pool_instances=8", "--query_cache_type=0"]
|
||||
expose:
|
||||
- 3306
|
||||
environment:
|
||||
|
||||
@@ -47,16 +47,5 @@
|
||||
</div><!-- #page -->
|
||||
<?php wp_footer(); ?>
|
||||
|
||||
<!-- Start of Rocket.Chat Livechat Script -->
|
||||
<script type="text/javascript">
|
||||
(function(w, d, s, u) {
|
||||
w.RocketChat = function(c) { w.RocketChat._.push(c) }; w.RocketChat._ = []; w.RocketChat.url = u;
|
||||
var h = d.getElementsByTagName(s)[0], j = d.createElement(s);
|
||||
j.async = true; j.src = 'https://talk.hatthieves.es/livechat/rocketchat-livechat.min.js?_=201903270000';
|
||||
h.parentNode.insertBefore(j, h);
|
||||
})(window, document, 'script', 'https://talk.hatthieves.es/livechat');
|
||||
</script>
|
||||
<!-- End of Rocket.Chat Livechat Script -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,3 +1,68 @@
|
||||
# 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>
|
||||
@@ -141,182 +206,6 @@ RewriteRule .* http://127.0.0.1 [L]
|
||||
#AIOWPS_BLOCK_SPAMBOTS_END
|
||||
# END All In One WP Security
|
||||
|
||||
# BEGIN W3TC Browser Cache
|
||||
<IfModule mod_mime.c>
|
||||
AddType text/css .css
|
||||
AddType text/x-component .htc
|
||||
AddType application/x-javascript .js
|
||||
AddType application/javascript .js2
|
||||
AddType text/javascript .js3
|
||||
AddType text/x-js .js4
|
||||
AddType video/asf .asf .asx .wax .wmv .wmx
|
||||
AddType video/avi .avi
|
||||
AddType image/bmp .bmp
|
||||
AddType application/java .class
|
||||
AddType video/divx .divx
|
||||
AddType application/msword .doc .docx
|
||||
AddType application/vnd.ms-fontobject .eot
|
||||
AddType application/x-msdownload .exe
|
||||
AddType image/gif .gif
|
||||
AddType application/x-gzip .gz .gzip
|
||||
AddType image/x-icon .ico
|
||||
AddType image/jpeg .jpg .jpeg .jpe
|
||||
AddType image/webp .webp
|
||||
AddType application/json .json
|
||||
AddType application/vnd.ms-access .mdb
|
||||
AddType audio/midi .mid .midi
|
||||
AddType video/quicktime .mov .qt
|
||||
AddType audio/mpeg .mp3 .m4a
|
||||
AddType video/mp4 .mp4 .m4v
|
||||
AddType video/mpeg .mpeg .mpg .mpe
|
||||
AddType video/webm .webm
|
||||
AddType application/vnd.ms-project .mpp
|
||||
AddType application/x-font-otf .otf
|
||||
AddType application/vnd.ms-opentype ._otf
|
||||
AddType application/vnd.oasis.opendocument.database .odb
|
||||
AddType application/vnd.oasis.opendocument.chart .odc
|
||||
AddType application/vnd.oasis.opendocument.formula .odf
|
||||
AddType application/vnd.oasis.opendocument.graphics .odg
|
||||
AddType application/vnd.oasis.opendocument.presentation .odp
|
||||
AddType application/vnd.oasis.opendocument.spreadsheet .ods
|
||||
AddType application/vnd.oasis.opendocument.text .odt
|
||||
AddType audio/ogg .ogg
|
||||
AddType application/pdf .pdf
|
||||
AddType image/png .png
|
||||
AddType application/vnd.ms-powerpoint .pot .pps .ppt .pptx
|
||||
AddType audio/x-realaudio .ra .ram
|
||||
AddType image/svg+xml .svg .svgz
|
||||
AddType application/x-shockwave-flash .swf
|
||||
AddType application/x-tar .tar
|
||||
AddType image/tiff .tif .tiff
|
||||
AddType application/x-font-ttf .ttf .ttc
|
||||
AddType application/vnd.ms-opentype ._ttf
|
||||
AddType audio/wav .wav
|
||||
AddType audio/wma .wma
|
||||
AddType application/vnd.ms-write .wri
|
||||
AddType application/font-woff .woff
|
||||
AddType application/font-woff2 .woff2
|
||||
AddType application/vnd.ms-excel .xla .xls .xlsx .xlt .xlw
|
||||
AddType application/zip .zip
|
||||
</IfModule>
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive On
|
||||
ExpiresByType text/css A31536000
|
||||
ExpiresByType text/x-component A31536000
|
||||
ExpiresByType application/x-javascript A31536000
|
||||
ExpiresByType application/javascript A31536000
|
||||
ExpiresByType text/javascript A31536000
|
||||
ExpiresByType text/x-js A31536000
|
||||
ExpiresByType video/asf A31536000
|
||||
ExpiresByType video/avi A31536000
|
||||
ExpiresByType image/bmp A31536000
|
||||
ExpiresByType application/java A31536000
|
||||
ExpiresByType video/divx A31536000
|
||||
ExpiresByType application/msword A31536000
|
||||
ExpiresByType application/vnd.ms-fontobject A31536000
|
||||
ExpiresByType application/x-msdownload A31536000
|
||||
ExpiresByType image/gif A31536000
|
||||
ExpiresByType application/x-gzip A31536000
|
||||
ExpiresByType image/x-icon A31536000
|
||||
ExpiresByType image/jpeg A31536000
|
||||
ExpiresByType image/webp A31536000
|
||||
ExpiresByType application/json A31536000
|
||||
ExpiresByType application/vnd.ms-access A31536000
|
||||
ExpiresByType audio/midi A31536000
|
||||
ExpiresByType video/quicktime A31536000
|
||||
ExpiresByType audio/mpeg A31536000
|
||||
ExpiresByType video/mp4 A31536000
|
||||
ExpiresByType video/mpeg A31536000
|
||||
ExpiresByType video/webm A31536000
|
||||
ExpiresByType application/vnd.ms-project A31536000
|
||||
ExpiresByType application/x-font-otf A31536000
|
||||
ExpiresByType application/vnd.ms-opentype A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.database A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.chart A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.formula A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.graphics A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.presentation A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.spreadsheet A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.text A31536000
|
||||
ExpiresByType audio/ogg A31536000
|
||||
ExpiresByType application/pdf A31536000
|
||||
ExpiresByType image/png A31536000
|
||||
ExpiresByType application/vnd.ms-powerpoint A31536000
|
||||
ExpiresByType audio/x-realaudio A31536000
|
||||
ExpiresByType image/svg+xml A31536000
|
||||
ExpiresByType application/x-shockwave-flash A31536000
|
||||
ExpiresByType application/x-tar A31536000
|
||||
ExpiresByType image/tiff A31536000
|
||||
ExpiresByType application/x-font-ttf A31536000
|
||||
ExpiresByType application/vnd.ms-opentype A31536000
|
||||
ExpiresByType audio/wav A31536000
|
||||
ExpiresByType audio/wma A31536000
|
||||
ExpiresByType application/vnd.ms-write A31536000
|
||||
ExpiresByType application/font-woff A31536000
|
||||
ExpiresByType application/font-woff2 A31536000
|
||||
ExpiresByType application/vnd.ms-excel A31536000
|
||||
ExpiresByType application/zip A31536000
|
||||
</IfModule>
|
||||
<IfModule mod_deflate.c>
|
||||
<IfModule mod_filter.c>
|
||||
AddOutputFilterByType DEFLATE text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/html text/richtext text/plain text/xsd text/xsl text/xml image/bmp application/java application/msword application/vnd.ms-fontobject application/x-msdownload image/x-icon application/json application/vnd.ms-access video/webm application/vnd.ms-project application/x-font-otf application/vnd.ms-opentype application/vnd.oasis.opendocument.database application/vnd.oasis.opendocument.chart application/vnd.oasis.opendocument.formula application/vnd.oasis.opendocument.graphics application/vnd.oasis.opendocument.presentation application/vnd.oasis.opendocument.spreadsheet application/vnd.oasis.opendocument.text audio/ogg application/pdf application/vnd.ms-powerpoint image/svg+xml application/x-shockwave-flash image/tiff application/x-font-ttf application/vnd.ms-opentype audio/wav application/vnd.ms-write application/font-woff application/font-woff2 application/vnd.ms-excel
|
||||
<IfModule mod_mime.c>
|
||||
# DEFLATE by extension
|
||||
AddOutputFilter DEFLATE js css htm html xml
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
<FilesMatch "\.(css|htc|less|js|js2|js3|js4|CSS|HTC|LESS|JS|JS2|JS3|JS4)$">
|
||||
FileETag MTime Size
|
||||
<IfModule mod_headers.c>
|
||||
Header unset Set-Cookie
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
<FilesMatch "\.(html|htm|rtf|rtx|txt|xsd|xsl|xml|HTML|HTM|RTF|RTX|TXT|XSD|XSL|XML)$">
|
||||
FileETag MTime Size
|
||||
</FilesMatch>
|
||||
<FilesMatch "\.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|webp|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|webm|mpp|otf|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|_ttf|wav|wma|wri|woff|woff2|xla|xls|xlsx|xlt|xlw|zip|ASF|ASX|WAX|WMV|WMX|AVI|BMP|CLASS|DIVX|DOC|DOCX|EOT|EXE|GIF|GZ|GZIP|ICO|JPG|JPEG|JPE|WEBP|JSON|MDB|MID|MIDI|MOV|QT|MP3|M4A|MP4|M4V|MPEG|MPG|MPE|WEBM|MPP|OTF|_OTF|ODB|ODC|ODF|ODG|ODP|ODS|ODT|OGG|PDF|PNG|POT|PPS|PPT|PPTX|RA|RAM|SVG|SVGZ|SWF|TAR|TIF|TIFF|TTF|TTC|_TTF|WAV|WMA|WRI|WOFF|WOFF2|XLA|XLS|XLSX|XLT|XLW|ZIP)$">
|
||||
FileETag MTime Size
|
||||
<IfModule mod_headers.c>
|
||||
Header unset Set-Cookie
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
<FilesMatch "\.(bmp|class|doc|docx|eot|exe|ico|json|mdb|webm|mpp|otf|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|pot|pps|ppt|pptx|svg|svgz|swf|tif|tiff|ttf|ttc|_ttf|wav|wri|woff|woff2|xla|xls|xlsx|xlt|xlw|BMP|CLASS|DOC|DOCX|EOT|EXE|ICO|JSON|MDB|WEBM|MPP|OTF|_OTF|ODB|ODC|ODF|ODG|ODP|ODS|ODT|OGG|PDF|POT|PPS|PPT|PPTX|SVG|SVGZ|SWF|TIF|TIFF|TTF|TTC|_TTF|WAV|WRI|WOFF|WOFF2|XLA|XLS|XLSX|XLT|XLW)$">
|
||||
<IfModule mod_headers.c>
|
||||
Header unset Last-Modified
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
<IfModule mod_headers.c>
|
||||
Header set Referrer-Policy "no-referrer-when-downgrade"
|
||||
</IfModule>
|
||||
# END W3TC Browser Cache
|
||||
# BEGIN W3TC CDN
|
||||
<IfModule mod_headers.c>
|
||||
Header set Access-Control-Allow-Origin "*"
|
||||
</IfModule>
|
||||
# END W3TC CDN
|
||||
# BEGIN W3TC Page Cache core
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
RewriteCond %{HTTPS} =on
|
||||
RewriteRule .* - [E=W3TC_SSL:_ssl]
|
||||
RewriteCond %{SERVER_PORT} =443
|
||||
RewriteRule .* - [E=W3TC_SSL:_ssl]
|
||||
RewriteCond %{HTTP:X-Forwarded-Proto} =https [NC]
|
||||
RewriteRule .* - [E=W3TC_SSL:_ssl]
|
||||
RewriteCond %{HTTP:Accept-Encoding} gzip
|
||||
RewriteRule .* - [E=W3TC_ENC:_gzip]
|
||||
RewriteCond %{HTTP_COOKIE} w3tc_preview [NC]
|
||||
RewriteRule .* - [E=W3TC_PREVIEW:_preview]
|
||||
RewriteCond %{REQUEST_METHOD} !=POST
|
||||
RewriteCond %{QUERY_STRING} =""
|
||||
RewriteCond %{HTTP_COOKIE} !(comment_author|wp\-postpass|w3tc_logged_out|wordpress_logged_in|wptouch_switch_toggle) [NC]
|
||||
RewriteCond %{REQUEST_URI} \/$
|
||||
RewriteCond "%{DOCUMENT_ROOT}/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_SSL}%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" -f
|
||||
RewriteRule .* "/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_SSL}%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" [L]
|
||||
</IfModule>
|
||||
# END W3TC Page Cache core
|
||||
# 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.
|
||||
|
||||
Las diferiencias del archivo han sido suprimidas porque una o mas lineas son muy largas
@@ -1,199 +1,41 @@
|
||||
<?php
|
||||
//ObjectCache Version: 1.4
|
||||
defined( 'WPINC' ) || exit ;
|
||||
/**
|
||||
* W3 Total Cache Object Cache
|
||||
* LiteSpeed Object Cache
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
if ( !defined( 'ABSPATH' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
if ( !defined( 'W3TC_DIR' ) ) {
|
||||
define( 'W3TC_DIR', ( defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins' ) . '/w3-total-cache' );
|
||||
}
|
||||
! defined( 'LSCWP_OBJECT_CACHE' ) && define( 'LSCWP_OBJECT_CACHE', true ) ;
|
||||
|
||||
if ( !@is_dir( W3TC_DIR ) || !file_exists( W3TC_DIR . '/w3-total-cache-api.php' ) ) {
|
||||
if ( !defined( 'WP_ADMIN' ) ) { // lets don't show error on front end
|
||||
require_once ABSPATH . WPINC . '/cache.php';
|
||||
} else {
|
||||
echo sprintf( '<strong>W3 Total Cache Error:</strong> some files appear to be missing or out of place. Please re-install plugin or remove <strong>%s</strong>. <br />', __FILE__ );
|
||||
}
|
||||
} else {
|
||||
require_once W3TC_DIR . '/w3-total-cache-api.php';
|
||||
|
||||
/**
|
||||
* Init cache
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function wp_cache_init() {
|
||||
$GLOBALS['wp_object_cache'] =
|
||||
\W3TC\Dispatcher::component( 'ObjectCache_WpObjectCache' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Close cache
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function wp_cache_close() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $group
|
||||
* @return mixed
|
||||
*/
|
||||
function wp_cache_get( $id, $group = 'default', $force = false, &$found = null ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->get( $id, $group, $force, $found );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache
|
||||
*
|
||||
* @param string $id
|
||||
* @param mixed $data
|
||||
* @param string $group
|
||||
* @param integer $expire
|
||||
* @return boolean
|
||||
*/
|
||||
function wp_cache_set( $id, $data, $group = 'default', $expire = 0 ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->set( $id, $data, $group, (int)$expire );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete from cache
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $group
|
||||
* @return boolean
|
||||
*/
|
||||
function wp_cache_delete( $id, $group = 'default' ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->delete( $id, $group );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data to cache
|
||||
*
|
||||
* @param string $id
|
||||
* @param mixed $data
|
||||
* @param string $group
|
||||
* @param integer $expire
|
||||
* @return boolean
|
||||
*/
|
||||
function wp_cache_add( $id, $data, $group = 'default', $expire = 0 ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->add( $id, $data, $group, (int)$expire );
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace data in cache
|
||||
*
|
||||
* @param string $id
|
||||
* @param mixed $data
|
||||
* @param string $group
|
||||
* @param integer $expire
|
||||
* @return boolean
|
||||
*/
|
||||
function wp_cache_replace( $id, $data, $group = 'default', $expire = 0 ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->replace( $id, $data, $group, (int)$expire );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset cache
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function wp_cache_reset() {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush cache
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function wp_cache_flush() {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add global groups
|
||||
*
|
||||
* @param array $groups
|
||||
* @return void
|
||||
*/
|
||||
function wp_cache_add_global_groups( $groups ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
$wp_object_cache->add_global_groups( $groups );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add non-persistent groups
|
||||
*
|
||||
* @param array $groups
|
||||
* @return void
|
||||
*/
|
||||
function wp_cache_add_non_persistent_groups( $groups ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
$wp_object_cache->add_nonpersistent_groups( $groups );
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment numeric cache item's value
|
||||
*
|
||||
* @param int|string $key The cache key to increment
|
||||
* @param int $offset The amount by which to increment the item's value. Default is 1.
|
||||
* @param string $group The group the key is in.
|
||||
* @return bool|int False on failure, the item's new value on success.
|
||||
*/
|
||||
function wp_cache_incr( $key, $offset = 1, $group = 'default' ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->incr( $key, $offset, $group );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement numeric cache item's value
|
||||
*
|
||||
* @param int|string $key The cache key to increment
|
||||
* @param int $offset The amount by which to decrement the item's value. Default is 1.
|
||||
* @param string $group The group the key is in.
|
||||
* @return bool|int False on failure, the item's new value on success.
|
||||
*/
|
||||
function wp_cache_decr( $key, $offset = 1, $group = 'default' ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->decr( $key, $offset, $group );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch the internal blog id.
|
||||
*
|
||||
* This changes the blog id used to create keys in blog specific groups.
|
||||
*
|
||||
* @param int $blog_id Blog ID
|
||||
*/
|
||||
function wp_cache_switch_to_blog( $blog_id ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->switch_to_blog( $blog_id );
|
||||
// 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 ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,15 +79,6 @@ table.comments td.comment p a:after {
|
||||
.checkforspam {
|
||||
display: inline-block !important;
|
||||
}
|
||||
.checkforspam-progress {
|
||||
display: none;
|
||||
}
|
||||
.checkforspam.checking .checkforspam-progress {
|
||||
padding-left: 1ex;
|
||||
}
|
||||
.checkforspam.button-disabled .checkforspam-progress {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.checkforspam-spinner {
|
||||
display: inline-block;
|
||||
|
||||
@@ -84,70 +84,72 @@ jQuery( function ( $ ) {
|
||||
});
|
||||
|
||||
// Show a preview image of the hovered URL. Applies to author URLs and URLs inside the comments.
|
||||
$( '#the-comment-list' ).on( 'mouseover', mshotEnabledLinkSelector, function () {
|
||||
clearTimeout( mshotRemovalTimer );
|
||||
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;
|
||||
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();
|
||||
}
|
||||
}
|
||||
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 );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
var thisHref = $( this ).attr( 'href' );
|
||||
|
||||
$( '.checkforspam' ).click( function( e ) {
|
||||
if ( $( this ).hasClass( 'checkforspam-pending-config' ) ) {
|
||||
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;
|
||||
}
|
||||
@@ -162,11 +164,9 @@ jQuery( function ( $ ) {
|
||||
$('.checkforspam').addClass('button-disabled').addClass( 'checking' );
|
||||
$('.checkforspam-spinner').addClass( 'spinner' ).addClass( 'is-active' );
|
||||
|
||||
// Update the label on the "Check for Spam" button to use the active "Checking for Spam" language.
|
||||
$( '.checkforspam .akismet-label' ).text( $( '.checkforspam' ).data( 'active-label' ) );
|
||||
|
||||
akismet_check_for_spam(0, 100);
|
||||
});
|
||||
$( '.checkforspam.enable-on-load' ).removeClass( 'button-disabled' );
|
||||
|
||||
var spam_count = 0;
|
||||
var recheck_count = 0;
|
||||
@@ -181,7 +181,7 @@ jQuery( function ( $ ) {
|
||||
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-progress' ).text( check_for_spam_buttons.data( 'progress-label-format' ).replace( '%1$s', percentage_complete ) );
|
||||
$( '.checkforspam' ).text( check_for_spam_buttons.data( 'progress-label' ).replace( '%1$s', percentage_complete ) );
|
||||
|
||||
$.post(
|
||||
ajaxurl,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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.5
|
||||
Version: 4.1.6
|
||||
Author: Automattic
|
||||
Author URI: https://automattic.com/wordpress-plugins/
|
||||
License: GPLv2 or later
|
||||
@@ -37,7 +37,7 @@ if ( !function_exists( 'add_action' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
define( 'AKISMET_VERSION', '4.1.5' );
|
||||
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 );
|
||||
|
||||
@@ -137,7 +137,7 @@ class Akismet_Admin {
|
||||
|
||||
wp_register_script( 'akismet.js', plugin_dir_url( __FILE__ ) . '_inc/akismet.js', array('jquery'), AKISMET_VERSION );
|
||||
wp_enqueue_script( 'akismet.js' );
|
||||
|
||||
|
||||
$inline_js = array(
|
||||
'comment_author_url_nonce' => wp_create_nonce( 'comment_author_url_nonce' ),
|
||||
'strings' => array(
|
||||
@@ -153,6 +153,10 @@ class Akismet_Admin {
|
||||
$inline_js['start_recheck'] = true;
|
||||
}
|
||||
|
||||
if ( apply_filters( 'akismet_enable_mshots', true ) ) {
|
||||
$inline_js['enable_mshots'] = true;
|
||||
}
|
||||
|
||||
wp_localize_script( 'akismet.js', 'WPAkismet', $inline_js );
|
||||
}
|
||||
}
|
||||
@@ -383,7 +387,7 @@ class Akismet_Admin {
|
||||
return;
|
||||
}
|
||||
|
||||
$link = add_query_arg( array( 'action' => 'akismet_recheck_queue' ), admin_url( 'admin.php' ) );
|
||||
$link = '';
|
||||
|
||||
$comments_count = wp_count_comments();
|
||||
|
||||
@@ -393,32 +397,30 @@ class Akismet_Admin {
|
||||
$classes = array(
|
||||
'button-secondary',
|
||||
'checkforspam',
|
||||
'button-disabled' // Disable button until the page is loaded
|
||||
);
|
||||
|
||||
if ( ! Akismet::get_api_key() ) {
|
||||
$link = admin_url( 'options-general.php?page=akismet-key-config' );
|
||||
if ( $comments_count->moderated > 0 ) {
|
||||
$classes[] = 'enable-on-load';
|
||||
|
||||
$classes[] = 'checkforspam-pending-config';
|
||||
if ( ! Akismet::get_api_key() ) {
|
||||
$link = add_query_arg( array( 'page' => 'akismet-key-config' ), class_exists( 'Jetpack' ) ? admin_url( 'admin.php' ) : admin_url( 'options-general.php' ) );
|
||||
$classes[] = 'ajax-disabled';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $comments_count->moderated == 0 ) {
|
||||
$classes[] = 'button-disabled';
|
||||
}
|
||||
echo '<a
|
||||
class="' . esc_attr( implode( ' ', $classes ) ) . '"
|
||||
href="' . esc_url( $link ) . '"
|
||||
data-active-label="' . esc_attr( __( 'Checking for Spam', 'akismet' ) ) . '"
|
||||
data-progress-label-format="' . esc_attr( __( '(%1$s%)', 'akismet' ) ) . '"
|
||||
class="' . esc_attr( implode( ' ', $classes ) ) . '"' .
|
||||
( ! empty( $link ) ? ' href="' . esc_url( $link ) . '"' : '' ) .
|
||||
/* translators: The placeholder is for showing how much of the process has completed, as a percent. e.g., "Checking for Spam (40%)" */
|
||||
' data-progress-label="' . esc_attr( __( 'Checking for Spam (%1$s%)', 'akismet' ) ) . '"
|
||||
data-success-url="' . esc_attr( remove_query_arg( array( 'akismet_recheck', 'akismet_recheck_error' ), add_query_arg( array( 'akismet_recheck_complete' => 1, 'recheck_count' => urlencode( '__recheck_count__' ), 'spam_count' => urlencode( '__spam_count__' ) ) ) ) ) . '"
|
||||
data-failure-url="' . esc_attr( remove_query_arg( array( 'akismet_recheck', 'akismet_recheck_complete' ), add_query_arg( array( 'akismet_recheck_error' => 1 ) ) ) ) . '"
|
||||
data-pending-comment-count="' . esc_attr( $comments_count->moderated ) . '"
|
||||
data-nonce="' . esc_attr( wp_create_nonce( 'akismet_check_for_spam' ) ) . '"
|
||||
>';
|
||||
echo '<span class="akismet-label">' . esc_html__('Check for Spam', 'akismet') . '</span>';
|
||||
echo '<span class="checkforspam-progress"></span>';
|
||||
echo '</a>';
|
||||
' . ( ! in_array( 'ajax-disabled', $classes ) ? 'onclick="return false;"' : '' ) . '
|
||||
>' . esc_html__('Check for Spam', 'akismet') . '</a>';
|
||||
echo '<span class="checkforspam-spinner"></span>';
|
||||
|
||||
}
|
||||
|
||||
public static function recheck_queue() {
|
||||
|
||||
@@ -3,7 +3,7 @@ Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eo
|
||||
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.5
|
||||
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.
|
||||
@@ -30,6 +30,12 @@ Upload the Akismet plugin to your blog, activate it, and then enter your Akismet
|
||||
|
||||
== 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*
|
||||
|
||||
@@ -77,4 +83,4 @@ Upload the Akismet plugin to your blog, activate it, and then enter your Akismet
|
||||
* 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.
|
||||
For older changelog entries, please see the [additional changelog.txt file](https://plugins.svn.wordpress.org/akismet/trunk/changelog.txt) delivered with the plugin.
|
||||
|
||||
@@ -86,19 +86,16 @@ class AIOWPSecurity_List_Logged_In_Users extends AIOWPSecurity_List_Table {
|
||||
$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
|
||||
// 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->update_user_online_transient($user_id, $ip_addr);
|
||||
// if($result != NULL)
|
||||
// {
|
||||
$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);
|
||||
// }
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,19 +114,10 @@ class AIOWPSecurity_List_Logged_In_Users extends AIOWPSecurity_List_Table {
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
$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{
|
||||
|
||||
@@ -6,12 +6,12 @@ if(!defined('ABSPATH')){
|
||||
class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
var $menu_page_slug = AIOWPSEC_SETTINGS_MENU_SLUG;
|
||||
|
||||
|
||||
/* Specify all the tabs of this menu in the following array */
|
||||
var $menu_tabs;
|
||||
|
||||
var $menu_tabs_handler = array(
|
||||
'tab1' => 'render_tab1',
|
||||
'tab1' => 'render_tab1',
|
||||
'tab2' => 'render_tab2',
|
||||
'tab3' => 'render_tab3',
|
||||
'tab4' => 'render_tab4',
|
||||
@@ -19,12 +19,12 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
'tab6' => 'render_tab6',
|
||||
);
|
||||
|
||||
function __construct()
|
||||
function __construct()
|
||||
{
|
||||
$this->render_menu_page();
|
||||
}
|
||||
|
||||
function set_menu_tabs()
|
||||
function set_menu_tabs()
|
||||
{
|
||||
$this->menu_tabs = array(
|
||||
'tab1' => __('General Settings', 'all-in-one-wp-security-and-firewall'),
|
||||
@@ -36,7 +36,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
);
|
||||
}
|
||||
|
||||
function get_current_tab()
|
||||
function get_current_tab()
|
||||
{
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
$tab = isset( $_GET['tab'] ) ? sanitize_text_field($_GET['tab']) : $tab_keys[0];
|
||||
@@ -46,32 +46,32 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
/*
|
||||
* Renders our tabs of this menu as nav items
|
||||
*/
|
||||
function render_menu_tabs()
|
||||
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 )
|
||||
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 '<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()
|
||||
function render_menu_page()
|
||||
{
|
||||
echo '<div class="wrap">';
|
||||
echo '<h2>'.__('Settings','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
|
||||
<?php
|
||||
//$tab_keys = array_keys($this->menu_tabs);
|
||||
call_user_func(array(&$this, $this->menu_tabs_handler[$tab]));
|
||||
?>
|
||||
@@ -79,7 +79,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
</div><!-- end of wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
function render_tab1()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
@@ -94,7 +94,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
AIOWPSecurity_Configure_Settings::turn_off_all_security_features();
|
||||
//Now let's clear the applicable rules from the .htaccess file
|
||||
$res = AIOWPSecurity_Utility_Htaccess::write_to_htaccess();
|
||||
|
||||
|
||||
//Now let's revert the disable editing setting in the wp-config.php file if necessary
|
||||
$res2 = AIOWPSecurity_Utility::enable_file_edits();
|
||||
|
||||
@@ -154,7 +154,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
<p><?php _e('For information, updates and documentation, please visit the', 'all-in-one-wp-security-and-firewall'); ?> <a href="https://www.tipsandtricks-hq.com/wordpress-security-and-firewall-plugin" target="_blank">AIO WP Security & Firewall Plugin</a> <?php _e('Page', 'all-in-one-wp-security-and-firewall'); ?>.</p>
|
||||
<p><a href="https://www.tipsandtricks-hq.com/development-center" target="_blank">Follow us</a> on Twitter, Google+ or via Email to stay upto date about the new security features of this plugin.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('WP Security Plugin', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
@@ -170,45 +170,45 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
</p>
|
||||
</div>
|
||||
</div> <!-- end postbox-->
|
||||
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Disable Security Features', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('aiowpsec-disable-all-features'); ?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('If you think that some plugin functionality on your site is broken due to a security feature you enabled in this plugin, then use the following option to turn off all the security features of this plugin.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="submit">
|
||||
<input type="submit" class="button" name="aiowpsec_disable_all_features" value="<?php _e('Disable All Security Features', 'all-in-one-wp-security-and-firewall'); ?>" />
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div> <!-- end postbox-->
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Disable All Firewall Rules', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('aiowpsec-disable-all-firewall-rules'); ?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
echo '<p>'.__('This feature will disable all firewall rules which are currently active in this plugin and it will also delete these rules from your .htacess file. Use it if you think one of the firewall rules is causing an issue on your site.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="submit">
|
||||
<input type="submit" class="button" name="aiowpsec_disable_all_firewall_rules" value="<?php _e('Disable All Firewall Rules'); ?>" />
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div> <!-- end postbox-->
|
||||
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php _e('Debug Settings', 'all-in-one-wp-security-and-firewall'); ?></label></h3>
|
||||
<div class="inside">
|
||||
<form method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('aiowpsec-save-debug-settings'); ?>
|
||||
<div class="aio_blue_box">
|
||||
<?php
|
||||
@@ -233,7 +233,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
</div> <!-- end postbox-->
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
function render_tab2()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
@@ -250,9 +250,9 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on htaccess file save!",4);
|
||||
die("Nonce check failed on htaccess file save!");
|
||||
}
|
||||
|
||||
|
||||
$result = AIOWPSecurity_Utility_File::backup_and_rename_htaccess($htaccess_path); //Backup the htaccess file
|
||||
|
||||
|
||||
if ($result)
|
||||
{
|
||||
$random_prefix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10);
|
||||
@@ -268,14 +268,14 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
$aio_wp_security->debug_logger->log_debug("htaccess file rename failed during backup!",4);
|
||||
$this->show_msg_error(__('htaccess file rename failed during backup. Please check your root directory for the backup file using FTP.','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aio_wp_security->debug_logger->log_debug("htaccess - Backup operation failed!",4);
|
||||
$this->show_msg_error(__('htaccess backup failed.','all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(isset($_POST['aiowps_restore_htaccess_button']))//Do form submission tasks
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
@@ -284,7 +284,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on htaccess file restore!",4);
|
||||
die("Nonce check failed on htaccess file restore!");
|
||||
}
|
||||
|
||||
|
||||
if (empty($_POST['aiowps_htaccess_file']))
|
||||
{
|
||||
$this->show_msg_error(__('Please choose a .htaccess to restore from.', 'all-in-one-wp-security-and-firewall'));
|
||||
@@ -298,7 +298,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
$is_htaccess = AIOWPSecurity_Utility_Htaccess::check_if_htaccess_contents($new_htaccess_file_path);
|
||||
if ($is_htaccess == 1)
|
||||
{
|
||||
if (!copy($new_htaccess_file_path, $htaccess_path))
|
||||
if (!copy($new_htaccess_file_path, $htaccess_path))
|
||||
{
|
||||
//Failed to make a backup copy
|
||||
$aio_wp_security->debug_logger->log_debug("htaccess - Restore from .htaccess operation failed!",4);
|
||||
@@ -316,7 +316,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<h2><?php _e('.htaccess File Operations', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
<div class="aio_blue_box">
|
||||
@@ -328,7 +328,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
$blog_id = get_current_blog_id();
|
||||
$blog_id = get_current_blog_id();
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && !is_main_site( $blog_id ))
|
||||
{
|
||||
//Hide config settings if MS and not main site
|
||||
@@ -363,7 +363,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_restore_htaccess_button" value="<?php _e('Restore .htaccess File', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
@@ -375,7 +375,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
function render_tab3()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
|
||||
|
||||
if(isset($_POST['aiowps_restore_wp_config_button']))//Do form submission tasks
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
@@ -384,7 +384,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed on wp-config file restore!",4);
|
||||
die("Nonce check failed on wp-config file restore!");
|
||||
}
|
||||
|
||||
|
||||
if (empty($_POST['aiowps_wp_config_file']))
|
||||
{
|
||||
$this->show_msg_error(__('Please choose a wp-config.php file to restore from.', 'all-in-one-wp-security-and-firewall'));
|
||||
@@ -393,13 +393,13 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
{
|
||||
//Let's copy the uploaded wp-config.php file into the active root file
|
||||
$new_wp_config_file_path = trim($_POST['aiowps_wp_config_file']);
|
||||
|
||||
|
||||
//Verify that file chosen is a wp-config.file
|
||||
$is_wp_config = $this->check_if_wp_config_contents($new_wp_config_file_path);
|
||||
if ($is_wp_config == 1)
|
||||
{
|
||||
$active_root_wp_config = AIOWPSecurity_Utility_File::get_wp_config_file_path();
|
||||
if (!copy($new_wp_config_file_path, $active_root_wp_config))
|
||||
if (!copy($new_wp_config_file_path, $active_root_wp_config))
|
||||
{
|
||||
//Failed to make a backup copy
|
||||
$aio_wp_security->debug_logger->log_debug("wp-config.php - Restore from backed up wp-config operation failed!",4);
|
||||
@@ -417,7 +417,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<h2><?php _e('wp-config.php File Operations', 'all-in-one-wp-security-and-firewall')?></h2>
|
||||
<div class="aio_blue_box">
|
||||
@@ -428,8 +428,8 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
</p>';
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
$blog_id = get_current_blog_id();
|
||||
<?php
|
||||
$blog_id = get_current_blog_id();
|
||||
if (AIOWPSecurity_Utility::is_multisite_install() && !is_main_site( $blog_id ))
|
||||
{
|
||||
//Hide config settings if MS and not main site
|
||||
@@ -458,14 +458,14 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
<th scope="row"><?php _e('wp-config file to restore from', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
<td>
|
||||
<input type="button" id="aiowps_wp_config_file_button" name="aiowps_wp_config_file_button" class="button rbutton" value="<?php _e('Select Your wp-config File', 'all-in-one-wp-security-and-firewall'); ?>" />
|
||||
<input name="aiowps_wp_config_file" type="text" id="aiowps_wp_config_file" value="" size="80" />
|
||||
<input name="aiowps_wp_config_file" type="text" id="aiowps_wp_config_file" value="" size="80" />
|
||||
<p class="description">
|
||||
<?php
|
||||
_e('After selecting your file click the button below to restore your site using the backed up wp-config file (wp-config.php.backup.txt).', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_restore_wp_config_button" value="<?php _e('Restore wp-config File', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
@@ -483,12 +483,12 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
<?php
|
||||
} //End if statement
|
||||
}
|
||||
|
||||
|
||||
function render_tab4()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
|
||||
|
||||
if(isset($_POST['aiowps_save_remove_wp_meta_info']))//Do form submission tasks
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
@@ -499,10 +499,10 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
}
|
||||
$aio_wp_security->configs->set_value('aiowps_remove_wp_generator_meta_info',isset($_POST["aiowps_remove_wp_generator_meta_info"])?'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();
|
||||
}
|
||||
?>
|
||||
@@ -529,7 +529,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
?>
|
||||
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-remove-wp-meta-info-nonce'); ?>
|
||||
<?php wp_nonce_field('aiowpsec-remove-wp-meta-info-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php _e('Remove WP Generator Meta Info', 'all-in-one-wp-security-and-firewall')?>:</th>
|
||||
@@ -537,7 +537,7 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
<input name="aiowps_remove_wp_generator_meta_info" type="checkbox"<?php if($aio_wp_security->configs->get_value('aiowps_remove_wp_generator_meta_info')=='1') echo ' checked="checked"'; ?> value="1"/>
|
||||
<span class="description"><?php _e('Check this if you want to remove the version and meta info produced by WP from all pages', 'all-in-one-wp-security-and-firewall'); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_save_remove_wp_meta_info" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
@@ -545,15 +545,15 @@ class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
|
||||
function render_tab5()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$events_table_name = AIOWPSEC_TBL_EVENTS;
|
||||
AIOWPSecurity_Utility::cleanup_table($events_table_name, 500);
|
||||
AIOWPSecurity_Utility::cleanup_table($events_table_name, 500);
|
||||
if(isset($_POST['aiowps_import_settings']))//Do form submission tasks
|
||||
{
|
||||
$nonce=$_REQUEST['_wpnonce'];
|
||||
@@ -592,7 +592,7 @@ function render_tab5()
|
||||
//Apply the settings and delete the file (if applicable)
|
||||
$settings_array = json_decode($aiowps_settings_file_contents, true);
|
||||
$aiowps_settings_applied = update_option('aio_wp_security_configs', $settings_array);
|
||||
|
||||
|
||||
if (!$aiowps_settings_applied)
|
||||
{
|
||||
//Failed to import settings
|
||||
@@ -717,7 +717,7 @@ function render_tab5()
|
||||
function render_tab6()
|
||||
{
|
||||
global $aio_wp_security;
|
||||
|
||||
|
||||
$result = 1;
|
||||
if (isset($_POST['aiowps_save_advanced_settings']))
|
||||
{
|
||||
@@ -727,7 +727,7 @@ function render_tab5()
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for save advanced settings!",4);
|
||||
die(__('Nonce check failed for save advanced settings!','aiowpsecurity'));
|
||||
}
|
||||
|
||||
|
||||
$aio_wp_security->configs->set_value('aiowps_ip_retrieve_method', sanitize_text_field($_POST["aiowps_ip_retrieve_method"]));
|
||||
$aio_wp_security->configs->save_config(); //Save the configuration
|
||||
|
||||
@@ -738,7 +738,7 @@ function render_tab5()
|
||||
else{
|
||||
delete_transient('users_online');
|
||||
}
|
||||
|
||||
|
||||
$this->show_msg_settings_updated();
|
||||
}
|
||||
?>
|
||||
@@ -753,9 +753,9 @@ function render_tab5()
|
||||
'<br />'.__('You can use the settings below to configure which $_SERVER global you would like to use for retrieving the IP address.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
|
||||
<form action="" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-ip-settings-nonce'); ?>
|
||||
<?php wp_nonce_field('aiowpsec-ip-settings-nonce'); ?>
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<td>
|
||||
@@ -771,21 +771,21 @@ function render_tab5()
|
||||
<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
|
||||
<?php
|
||||
_e('If your chosen server variable fails the plugin will automatically fall back to retrieving the IP address from $_SERVER["REMOTE_ADDR"]', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" name="aiowps_save_advanced_settings" value="<?php _e('Save Settings', 'all-in-one-wp-security-and-firewall')?>" class="button-primary" />
|
||||
</form>
|
||||
</div></div>
|
||||
<?php
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function check_if_wp_config_contents($wp_file)
|
||||
{
|
||||
$is_wp_config = false;
|
||||
|
||||
@@ -20,8 +20,6 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
AIOWPSecurity_Blocking::check_visitor_ip_and_perform_blocking();
|
||||
|
||||
if ($aio_wp_security->configs->get_value('aiowps_enable_autoblock_spam_ip') == '1') {
|
||||
//add_action( 'spammed_comment', array(&$this, 'process_spammed_comment' )); //this hook gets fired when admin marks comment as spam
|
||||
//add_action( 'akismet_submit_spam_comment', array(&$this, 'process_akismet_submit_spam_comment' ), 10, 2); //this hook gets fired when akismet marks a comment as spam
|
||||
add_action( 'comment_post', array(&$this, 'spam_detect_process_comment_post' ), 10, 2); //this hook gets fired just after comment is saved to DB
|
||||
add_action( 'transition_comment_status', array(&$this, 'process_transition_comment_status' ), 10, 3); //this hook gets fired when a comment's status changes
|
||||
}
|
||||
@@ -38,15 +36,15 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
if(AIOWPSecurity_Installer::reactivation_tasks()){
|
||||
$aio_wp_security->debug_logger->log_debug("The AIOWPS .htaccess rules were successfully re-inserted!");
|
||||
$_SESSION['reapply_htaccess_rules_action_result'] = '1';//Success indicator.
|
||||
//Can't echo to the screen here. It will create an header already sent error.
|
||||
// Can't echo to the screen here. It will create an header already sent error.
|
||||
}else{
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPS encountered an error when trying to write to your .htaccess file. Please check the logs.", 5);
|
||||
$_SESSION['reapply_htaccess_rules_action_result'] = '2';//fail indicator.
|
||||
//Can't echo to the screen here. It will create an header already sent error.
|
||||
// Can't echo to the screen here. It will create an header already sent error.
|
||||
}
|
||||
|
||||
}elseif(strip_tags($_REQUEST['aiowps_reapply_htaccess']) == 2){
|
||||
//Don't re-write the rules and just delete the temp config item
|
||||
// Don't re-write the rules and just delete the temp config item
|
||||
delete_option('aiowps_temp_configs');
|
||||
}
|
||||
}
|
||||
@@ -61,27 +59,27 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
add_filter('script_loader_src', array(&$this,'remove_wp_css_js_meta_info'));
|
||||
}
|
||||
|
||||
//For the cookie based brute force prevention feature
|
||||
// For the cookie based brute force prevention feature
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention') == 1){
|
||||
$bfcf_secret_word = $aio_wp_security->configs->get_value('aiowps_brute_force_secret_word');
|
||||
if(isset($_GET[$bfcf_secret_word])){
|
||||
//If URL contains secret word in query param then set cookie and then redirect to the login page
|
||||
// If URL contains secret word in query param then set cookie and then redirect to the login page
|
||||
AIOWPSecurity_Utility::set_cookie_value($bfcf_secret_word, "1");
|
||||
AIOWPSecurity_Utility::redirect_to_url(AIOWPSEC_WP_URL."/wp-admin");
|
||||
}
|
||||
}
|
||||
|
||||
//Stop users enumeration feature
|
||||
// Stop users enumeration feature
|
||||
if( $aio_wp_security->configs->get_value('aiowps_prevent_users_enumeration') == 1) {
|
||||
include_once(AIO_WP_SECURITY_PATH.'/other-includes/wp-security-stop-users-enumeration.php');
|
||||
}
|
||||
|
||||
//REST API security
|
||||
// REST API security
|
||||
if( $aio_wp_security->configs->get_value('aiowps_disallow_unauthorized_rest_requests') == 1) {
|
||||
add_action('rest_api_init', array(&$this, 'check_rest_api_requests'), 10 ,1);
|
||||
}
|
||||
|
||||
//For user unlock request feature
|
||||
// For user unlock request feature
|
||||
if(isset($_POST['aiowps_unlock_request']) || isset($_POST['aiowps_wp_submit_unlock_request'])){
|
||||
nocache_headers();
|
||||
remove_action('wp_head','head_addons',7);
|
||||
@@ -95,7 +93,7 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
AIOWPSecurity_User_Login::process_unlock_request($unlock_key);
|
||||
}
|
||||
|
||||
//For honeypot feature
|
||||
// For honeypot feature
|
||||
if(isset($_POST['aio_special_field'])){
|
||||
$special_field_value = sanitize_text_field($_POST['aio_special_field']);
|
||||
if(!empty($special_field_value)){
|
||||
@@ -105,7 +103,7 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
}
|
||||
}
|
||||
|
||||
//For 404 IP lockout feature
|
||||
// For 404 IP lockout feature
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_404_IP_lockout') == '1'){
|
||||
if (!is_user_logged_in() || !current_user_can('administrator')) {
|
||||
$this->do_404_lockout_tasks();
|
||||
@@ -113,14 +111,14 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
}
|
||||
|
||||
|
||||
//For login captcha feature
|
||||
// For login captcha feature
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_login_captcha') == '1'){
|
||||
if (!is_user_logged_in()) {
|
||||
add_action('login_form', array(&$this, 'insert_captcha_question_form'));
|
||||
}
|
||||
}
|
||||
|
||||
//For woo form captcha features
|
||||
// For woo form captcha features
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_woo_login_captcha') == '1') {
|
||||
if (!is_user_logged_in()) {
|
||||
add_action('woocommerce_login_form', array(&$this, 'insert_captcha_question_form'));
|
||||
@@ -149,35 +147,35 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
}
|
||||
}
|
||||
|
||||
//For bbpress new topic form captcha
|
||||
// For bbpress new topic form captcha
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_bbp_new_topic_captcha') == '1'){
|
||||
if (!is_user_logged_in()) {
|
||||
add_action('bbp_theme_before_topic_form_submit_wrapper', array(&$this, 'insert_captcha_question_form'));
|
||||
}
|
||||
}
|
||||
|
||||
//For custom login form captcha feature, ie, when wp_login_form() function is used to generate login form
|
||||
// For custom login form captcha feature, ie, when wp_login_form() function is used to generate login form
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_custom_login_captcha') == '1'){
|
||||
if (!is_user_logged_in()) {
|
||||
add_filter( 'login_form_middle', array(&$this, 'insert_captcha_custom_login'), 10, 2); //For cases where the WP wp_login_form() function is used
|
||||
}
|
||||
}
|
||||
|
||||
//For honeypot feature
|
||||
// For honeypot feature
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_login_honeypot') == '1'){
|
||||
if (!is_user_logged_in()) {
|
||||
add_action('login_form', array(&$this, 'insert_honeypot_hidden_field'));
|
||||
}
|
||||
}
|
||||
|
||||
//For registration honeypot feature
|
||||
// For registration honeypot feature
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_registration_honeypot') == '1'){
|
||||
if (!is_user_logged_in()) {
|
||||
add_action('register_form', array(&$this, 'insert_honeypot_hidden_field'));
|
||||
}
|
||||
}
|
||||
|
||||
//For lost password captcha feature
|
||||
// For lost password captcha feature
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_lost_password_captcha') == '1'){
|
||||
if (!is_user_logged_in()) {
|
||||
add_action('lostpassword_form', array(&$this, 'insert_captcha_question_form'));
|
||||
@@ -185,12 +183,12 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
}
|
||||
}
|
||||
|
||||
//For registration manual approval feature
|
||||
// For registration manual approval feature
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_manual_registration_approval') == '1'){
|
||||
add_filter('wp_login_errors', array(&$this, 'modify_registration_page_messages'),10, 2);
|
||||
}
|
||||
|
||||
//For registration page captcha feature
|
||||
// For registration page captcha feature
|
||||
if (AIOWPSecurity_Utility::is_multisite_install()){
|
||||
$blog_id = get_current_blog_id();
|
||||
switch_to_blog($blog_id);
|
||||
@@ -210,7 +208,7 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
}
|
||||
}
|
||||
|
||||
//For comment captcha feature or custom login form captcha
|
||||
// For comment captcha feature or custom login form captcha
|
||||
if (AIOWPSecurity_Utility::is_multisite_install()){
|
||||
$blog_id = get_current_blog_id();
|
||||
switch_to_blog($blog_id);
|
||||
@@ -238,28 +236,28 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
}
|
||||
}
|
||||
|
||||
//For buddypress registration captcha feature
|
||||
// For buddypress registration captcha feature
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_bp_register_captcha') == '1'){
|
||||
add_action('bp_account_details_fields', array(&$this, 'insert_captcha_question_form'));
|
||||
add_action('bp_signup_validate', array(&$this, 'buddy_press_signup_validate_captcha'));
|
||||
}
|
||||
|
||||
|
||||
//For feature which displays logged in users
|
||||
$this->update_logged_in_user_transient();
|
||||
// For feature which displays logged in users
|
||||
$aio_wp_security->user_login_obj->update_users_online_transient();
|
||||
|
||||
//For block fake googlebots feature
|
||||
// For block fake googlebots feature
|
||||
if($aio_wp_security->configs->get_value('aiowps_block_fake_googlebots') == '1'){
|
||||
include_once(AIO_WP_SECURITY_PATH.'/classes/wp-security-bot-protection.php');
|
||||
AIOWPSecurity_Fake_Bot_Protection::block_fake_googlebots();
|
||||
}
|
||||
|
||||
//For 404 event logging
|
||||
// For 404 event logging
|
||||
if($aio_wp_security->configs->get_value('aiowps_enable_404_logging') == '1'){
|
||||
add_action('wp_head', array(&$this, 'check_404_event'));
|
||||
}
|
||||
|
||||
//Add more tasks that need to be executed at init time
|
||||
// Add more tasks that need to be executed at init time
|
||||
|
||||
} // end _construct()
|
||||
|
||||
@@ -372,68 +370,6 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
}
|
||||
}
|
||||
|
||||
function update_logged_in_user_transient(){
|
||||
if(is_user_logged_in()){
|
||||
$current_user_ip = AIOWPSecurity_Utility_IP::get_user_ip_address();
|
||||
// get the logged in users list from transients entry
|
||||
$logged_in_users = (AIOWPSecurity_Utility::is_multisite_install() ? get_site_transient('users_online') : get_transient('users_online'));
|
||||
$current_user = wp_get_current_user();
|
||||
$current_user = $current_user->ID;
|
||||
$current_time = current_time('timestamp');
|
||||
|
||||
// Store last activity time and ip address in transient entry
|
||||
if(AIOWPSecurity_Utility::is_multisite_install()) {
|
||||
$current_blog_id = get_current_blog_id();
|
||||
// For multi-sites also store blog_id
|
||||
$current_user_info = array("user_id" => $current_user, "last_activity" => $current_time, "ip_address" => $current_user_ip, "blog_id" => $current_blog_id);
|
||||
} else {
|
||||
$current_user_info = array("user_id" => $current_user, "last_activity" => $current_time, "ip_address" => $current_user_ip); //We will store last activity time and ip address in transient entry
|
||||
}
|
||||
|
||||
|
||||
if($logged_in_users === false || $logged_in_users == NULL){
|
||||
$logged_in_users = array();
|
||||
$logged_in_users[] = $current_user_info;
|
||||
AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = 0;
|
||||
$do_nothing = false;
|
||||
$update_existing = false;
|
||||
$item_index = 0;
|
||||
foreach ($logged_in_users as $value)
|
||||
{
|
||||
if($value['user_id'] == $current_user && strcmp($value['ip_address'], $current_user_ip) == 0)
|
||||
{
|
||||
if ($value['last_activity'] < ($current_time - (15 * 60)))
|
||||
{
|
||||
$update_existing = true;
|
||||
$item_index = $key;
|
||||
break;
|
||||
}else{
|
||||
$do_nothing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$key++;
|
||||
}
|
||||
|
||||
if($update_existing)
|
||||
{
|
||||
//Update transient if the last activity was less than 15 min ago for this user
|
||||
$logged_in_users[$item_index] = $current_user_info;
|
||||
AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
|
||||
}else if($do_nothing){
|
||||
//Do nothing
|
||||
}else{
|
||||
$logged_in_users[] = $current_user_info;
|
||||
AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders captcha on form produced by the wp_login_form() function, ie, custom wp login form
|
||||
* @global type $aio_wp_security
|
||||
@@ -527,7 +463,7 @@ class AIOWPSecurity_General_Init_Tasks
|
||||
}
|
||||
|
||||
//Don't do captcha for pingback/trackback
|
||||
if ($comment['comment_type'] != '' && $comment['comment_type'] != 'comment') {
|
||||
if ($comment['comment_type'] != '' && $comment['comment_type'] != 'comment' && $comment['comment_type'] != 'review') {
|
||||
return $comment;
|
||||
}
|
||||
|
||||
|
||||
@@ -504,7 +504,7 @@ class AIOWPSecurity_User_Login
|
||||
$ip_addr = AIOWPSecurity_Utility_IP::get_user_ip_address();
|
||||
$user_id = $current_user->ID;
|
||||
//Clean up transients table
|
||||
$this->update_user_online_transient($user_id, $ip_addr);
|
||||
$this->cleanup_users_online_transient($user_id, $ip_addr);
|
||||
$login_activity_table = AIOWPSEC_TBL_USER_LOGIN_ACTIVITY;
|
||||
$logout_date_time = current_time( 'mysql' );
|
||||
$data = array('logout_date' => $logout_date_time);
|
||||
@@ -517,29 +517,93 @@ class AIOWPSecurity_User_Login
|
||||
$aio_wp_security->debug_logger->log_debug("Error inserting record into ".$login_activity_table,4);//Log the highly unlikely event of DB error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will clean up the "users_online" transient entry for the current user.
|
||||
*
|
||||
* Update the 'users_online' transient
|
||||
* @return void
|
||||
*/
|
||||
function update_user_online_transient($user_id, $ip_addr)
|
||||
function update_users_online_transient()
|
||||
{
|
||||
if(is_user_logged_in()){
|
||||
$is_multi_site = AIOWPSecurity_Utility::is_multisite_install();
|
||||
$current_user_ip = AIOWPSecurity_Utility_IP::get_user_ip_address();
|
||||
// get the logged in users list from transients entry
|
||||
$logged_in_users = ($is_multi_site ? get_site_transient('users_online') : get_transient('users_online'));
|
||||
$current_user = wp_get_current_user();
|
||||
$current_user = $current_user->ID;
|
||||
$current_time = current_time('timestamp');
|
||||
$current_user_info = array();
|
||||
|
||||
// Store last activity time and ip address in transient entry
|
||||
if($is_multi_site) {
|
||||
$current_blog_id = get_current_blog_id();
|
||||
// For multi-sites also store blog_id
|
||||
$current_user_info = array("user_id" => $current_user, "last_activity" => $current_time, "ip_address" => $current_user_ip, "blog_id" => $current_blog_id);
|
||||
} else {
|
||||
$current_user_info = array("user_id" => $current_user, "last_activity" => $current_time, "ip_address" => $current_user_ip, "blog_id" => false);
|
||||
}
|
||||
|
||||
if(empty($logged_in_users))
|
||||
{
|
||||
// case when "users_online" transient has been deleted after expiry or is empty
|
||||
$logged_in_users = array();
|
||||
$logged_in_users[] = $current_user_info;
|
||||
$is_multi_site ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = 0;
|
||||
$update_existing = false;
|
||||
$item_index = 0;
|
||||
foreach ($logged_in_users as $value)
|
||||
{
|
||||
$value_minus_activity = $value;
|
||||
unset($value_minus_activity['last_activity']);
|
||||
$current_user_minus_activity = $current_user_info;
|
||||
unset($current_user_minus_activity['last_activity']);
|
||||
// Check if current user we're looking at has an entry in the 'users_online' transient
|
||||
if(empty(array_diff($current_user_minus_activity, $value_minus_activity)))
|
||||
{
|
||||
if ($value['last_activity'] < ($current_time - (15 * 60)))
|
||||
{
|
||||
$update_existing = true;
|
||||
$item_index = $key;
|
||||
break;
|
||||
}else{
|
||||
return; // do nothing and just return
|
||||
}
|
||||
}
|
||||
$key++;
|
||||
}
|
||||
|
||||
if($update_existing) {
|
||||
// Update transient if the last activity was over 15 min ago for this user
|
||||
$logged_in_users[$item_index] = $current_user_info;
|
||||
AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
|
||||
} else {
|
||||
$logged_in_users[] = $current_user_info;
|
||||
AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will clean up the "users_online" transient entry for the current user when a logout occurs
|
||||
* @return void
|
||||
*/
|
||||
function cleanup_users_online_transient($user_id, $ip_addr)
|
||||
{
|
||||
global $aio_wp_security;
|
||||
$is_multi_site = AIOWPSecurity_Utility::is_multisite_install();
|
||||
if ($is_multi_site) {
|
||||
$current_blog_id = get_current_blog_id();
|
||||
$is_main = is_main_site($current_blog_id);
|
||||
if($is_main) {
|
||||
$logged_in_users = get_site_transient('users_online');
|
||||
} else {
|
||||
switch_to_blog($current_blog_id);
|
||||
$logged_in_users = get_transient('users_online');
|
||||
}
|
||||
$logged_in_users = AIOWPSecurity_User_Login::get_subsite_logged_in_users($current_blog_id);
|
||||
} else {
|
||||
$logged_in_users = get_transient('users_online');
|
||||
}
|
||||
|
||||
//$logged_in_users = get_transient('users_online');
|
||||
if ($logged_in_users === false || $logged_in_users == NULL)
|
||||
if (empty($logged_in_users))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -553,11 +617,10 @@ class AIOWPSecurity_User_Login
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
//Save the transient
|
||||
|
||||
// AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
|
||||
// Save the transient
|
||||
if ($is_multi_site) {
|
||||
($is_main) ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
|
||||
set_site_transient('users_online', $logged_in_users, 30 * 60);
|
||||
} else {
|
||||
set_transient('users_online', $logged_in_users, 30 * 60);
|
||||
}
|
||||
@@ -631,7 +694,7 @@ class AIOWPSecurity_User_Login
|
||||
* Returns all logged in users for specific subsite of multisite installation
|
||||
* Checks the aiowps transient 'users_online'
|
||||
* @param type $blog_id
|
||||
* @return array
|
||||
* @return array|bool
|
||||
*/
|
||||
static function get_subsite_logged_in_users($blog_id=0) {
|
||||
if(empty($blog_id)) return false;
|
||||
@@ -640,9 +703,11 @@ class AIOWPSecurity_User_Login
|
||||
if (AIOWPSecurity_Utility::is_multisite_install()) {
|
||||
// this contains all logged in users sitewide across subsites
|
||||
$users_online = get_site_transient('users_online');
|
||||
$logged_in_users = empty($users_online)?array():$users_online;
|
||||
// Subsite - extract only logged in users for current blog
|
||||
foreach($logged_in_users as $user) {
|
||||
if(empty($users_online)) {
|
||||
return array();
|
||||
}
|
||||
// Extract only logged in users for current subsite
|
||||
foreach($users_online as $user) {
|
||||
if (isset($user['blog_id']) && $user['blog_id'] == $blog_id) {
|
||||
$subsite_logged_in_users[] = $user;
|
||||
}
|
||||
@@ -650,4 +715,5 @@ class AIOWPSecurity_User_Login
|
||||
}
|
||||
return $subsite_logged_in_users;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ Donate link: https://www.tipsandtricks-hq.com
|
||||
Tags: security, secure, Anti Virus, antivirus, ban, ban hacker, virus, firewall, firewall security, login, lockdown, htaccess, hack, malware, vulnerability, protect, protection, phishing, database, backup, plugin, sql injection, ssl, restrict, login captcha, bot, hotlink, 404 detection, admin, rename, all in one, scan, scanner, iframe,
|
||||
Requires at least: 4.7
|
||||
Tested up to: 5.4
|
||||
Stable tag: 4.4.3
|
||||
Stable tag: 4.4.4
|
||||
License: GPLv3
|
||||
|
||||
A comprehensive, user-friendly, all in one WordPress security and firewall plugin for your site.
|
||||
@@ -184,6 +184,12 @@ None
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 4.4.4 =
|
||||
- Fixed bugs and improved functionality related to "logged in users" functionality.
|
||||
- Google recaptha checks for WooCommerce product reviews
|
||||
- Replaced use of deprecated hook "wpmu_new_blog" with "wp_insert_site"
|
||||
- Fixed a potential XSS issue in the settings menu of the plugin for IE11 or older browsers.
|
||||
|
||||
= 4.4.3 =
|
||||
- Improved file change detection feature to address DB backups failing silently in some cases due to very large serialized data stored in a single row.
|
||||
- Added new action hook (aiowps_rename_login_load) just before renamed login page is loaded.
|
||||
|
||||
@@ -7,7 +7,7 @@ if ( !defined('ABSPATH') ) {
|
||||
if (!class_exists('AIO_WP_Security')){
|
||||
|
||||
class AIO_WP_Security{
|
||||
var $version = '4.4.3';
|
||||
var $version = '4.4.4';
|
||||
var $db_version = '1.9';
|
||||
var $plugin_url;
|
||||
var $plugin_path;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: All In One WP Security
|
||||
Version: 4.4.3
|
||||
Version: 4.4.4
|
||||
Plugin URI: https://www.tipsandtricks-hq.com/wordpress-security-and-firewall-plugin
|
||||
Author: Tips and Tricks HQ, Peter Petreski, Ruhul, Ivy
|
||||
Author URI: https://www.tipsandtricks-hq.com/
|
||||
@@ -29,17 +29,20 @@ function aiowps_show_plugin_settings_link($links, $file)
|
||||
}
|
||||
add_filter('plugin_action_links', 'aiowps_show_plugin_settings_link', 10, 2 );
|
||||
|
||||
function aiowps_ms_handle_new_blog_creation($blog_id, $user_id, $domain, $path, $site_id, $meta ){
|
||||
function aiowps_ms_handle_new_site($new_site){
|
||||
global $wpdb;
|
||||
if (is_plugin_active_for_network(__FILE__))
|
||||
$plugin_basename = plugin_basename( __FILE__ );
|
||||
if (is_plugin_active_for_network($plugin_basename))
|
||||
{
|
||||
if(!class_exists('AIOWPSecurity_Installer')){
|
||||
include_once('classes/wp-security-installer.php');
|
||||
}
|
||||
$old_blog = $wpdb->blogid;
|
||||
switch_to_blog($blog_id);
|
||||
switch_to_blog($new_site->blog_id);
|
||||
AIOWPSecurity_Installer::create_db_tables();
|
||||
switch_to_blog($old_blog);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
add_action('wpmu_new_blog', 'aiowps_ms_handle_new_blog_creation', 10, 6);
|
||||
add_action('wp_insert_site', 'aiowps_ms_handle_new_site', 10, 1);
|
||||
|
||||
@@ -5,22 +5,24 @@
|
||||
*
|
||||
* bbPress is forum software with a twist from the creators of WordPress.
|
||||
*
|
||||
* $Id: bbpress.php 7062 2020-01-30 12:32:42Z johnjamesjacoby $
|
||||
* $Id: bbpress.php 7090 2020-05-28 16:58:55Z johnjamesjacoby $
|
||||
*
|
||||
* @package bbPress
|
||||
* @subpackage Main
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin Name: bbPress
|
||||
* Plugin URI: https://bbpress.org
|
||||
* Description: bbPress is forum software with a twist from the creators of WordPress.
|
||||
* Author: The bbPress Contributors
|
||||
* Author URI: https://bbpress.org
|
||||
* Version: 2.6.4
|
||||
* Text Domain: bbpress
|
||||
* Domain Path: /languages/
|
||||
* License: GPLv2 or later (license.txt)
|
||||
* Plugin Name: bbPress
|
||||
* Plugin URI: https://bbpress.org
|
||||
* Description: bbPress is forum software with a twist from the creators of WordPress.
|
||||
* Author: The bbPress Contributors
|
||||
* Author URI: https://bbpress.org
|
||||
* Version: 2.6.5
|
||||
* Text Domain: bbpress
|
||||
* Domain Path: /languages/
|
||||
* License: GPLv2 or later (license.txt)
|
||||
* Requires PHP: 5.6.20
|
||||
* Requires at least: 4.7
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
@@ -203,7 +205,7 @@ final class bbPress {
|
||||
|
||||
/** Versions **********************************************************/
|
||||
|
||||
$this->version = '2.6.4';
|
||||
$this->version = '2.6.5';
|
||||
$this->db_version = '263';
|
||||
|
||||
/** Paths *************************************************************/
|
||||
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -5,6 +5,7 @@ jQuery( document ).ready( function() {
|
||||
bbp_author_id.suggest(
|
||||
bbp_author_id.data( 'ajax-url' ),
|
||||
{
|
||||
minchars: 1, // Allow single-digit user IDs
|
||||
onSelect: function() {
|
||||
var value = this.value;
|
||||
bbp_author_id.val( value.substr( 0, value.indexOf( ' ' ) ) );
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
/*! This file is automatically generated. */
|
||||
|
||||
jQuery(document).ready(function(){var a=jQuery("#bbp_author_id");a.suggest(a.data("ajax-url"),{onSelect:function(){var u=this.value;a.val(u.substr(0,u.indexOf(" ")))}})});
|
||||
jQuery(document).ready(function(){var a=jQuery("#bbp_author_id");a.suggest(a.data("ajax-url"),{minchars:1,onSelect:function(){var u=this.value;a.val(u.substr(0,u.indexOf(" ")))}})});
|
||||
@@ -586,6 +586,11 @@ class BBP_Admin {
|
||||
// Loop through fields for this section
|
||||
foreach ( (array) $fields as $field_id => $field ) {
|
||||
|
||||
// Skip field if user is not capable
|
||||
if ( ! empty( $field['capability'] ) && ! current_user_can( $field['capability'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the field
|
||||
if ( ! empty( $field['callback'] ) && ! empty( $field['title'] ) ) {
|
||||
add_settings_field( $field_id, $field['title'], $field['callback'], $page, $section_id, $field['args'] );
|
||||
@@ -891,29 +896,46 @@ class BBP_Admin {
|
||||
*/
|
||||
public function suggest_topic() {
|
||||
|
||||
// Bail early if no request
|
||||
if ( empty( $_REQUEST['q'] ) ) {
|
||||
wp_die( '0' );
|
||||
// Do some very basic request checking
|
||||
$request = ! empty( $_REQUEST['q'] )
|
||||
? trim( $_REQUEST['q'] )
|
||||
: '';
|
||||
|
||||
// Bail early if empty request
|
||||
if ( empty( $request ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// Bail if user cannot moderate - only moderators can change hierarchy
|
||||
// Bail if user cannot moderate
|
||||
if ( ! current_user_can( 'moderate' ) ) {
|
||||
wp_die( '0' );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// Check the ajax nonce
|
||||
check_ajax_referer( 'bbp_suggest_topic_nonce' );
|
||||
|
||||
// Allow the maximum number of results to be filtered
|
||||
$number = (int) apply_filters( 'bbp_suggest_topic_count', 10 );
|
||||
|
||||
// Try to get some topics
|
||||
$topics = get_posts( array(
|
||||
's' => bbp_db()->esc_like( $_REQUEST['q'] ),
|
||||
'post_type' => bbp_get_topic_post_type()
|
||||
's' => bbp_db()->esc_like( $_REQUEST['q'] ),
|
||||
'post_type' => bbp_get_topic_post_type(),
|
||||
'posts_per_page' => $number,
|
||||
|
||||
// Performance
|
||||
'nopaging' => true,
|
||||
'suppress_filters' => true,
|
||||
'update_post_term_cache' => false,
|
||||
'update_post_meta_cache' => false,
|
||||
'ignore_sticky_posts' => true,
|
||||
'no_found_rows' => true
|
||||
) );
|
||||
|
||||
// If we found some topics, loop through and display them
|
||||
if ( ! empty( $topics ) ) {
|
||||
foreach ( (array) $topics as $post ) {
|
||||
printf( esc_html__( '%s - %s', 'bbpress' ), bbp_get_topic_id( $post->ID ), bbp_get_topic_title( $post->ID ) . "\n" );
|
||||
printf( esc_html__( '%1$s - %2$s', 'bbpress' ), bbp_get_topic_id( $post->ID ), bbp_get_topic_title( $post->ID ) . "\n" );
|
||||
}
|
||||
}
|
||||
die();
|
||||
@@ -926,31 +948,74 @@ class BBP_Admin {
|
||||
*/
|
||||
public function suggest_user() {
|
||||
|
||||
// Bail early if no request
|
||||
if ( empty( $_REQUEST['q'] ) ) {
|
||||
wp_die( '0' );
|
||||
// Do some very basic request checking
|
||||
$request = ! empty( $_REQUEST['q'] )
|
||||
? trim( $_REQUEST['q'] )
|
||||
: '';
|
||||
|
||||
// Bail early if empty request
|
||||
if ( empty( $request ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// Bail if user cannot moderate - only moderators can change authorship
|
||||
// Bail if user cannot moderate
|
||||
if ( ! current_user_can( 'moderate' ) ) {
|
||||
wp_die( '0' );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// Check the ajax nonce
|
||||
check_ajax_referer( 'bbp_suggest_user_nonce' );
|
||||
|
||||
// Try to get some users
|
||||
// Fields to retrieve & search by
|
||||
$fields = $search = array( 'ID', 'user_nicename' );
|
||||
|
||||
// Keymasters & Super-Mods can also search by email
|
||||
if ( current_user_can( 'keep_gate' ) || bbp_allow_super_mods() ) {
|
||||
|
||||
// Add user_email to searchable columns
|
||||
array_push( $search, 'user_email' );
|
||||
|
||||
// Unstrict to also allow some email characters
|
||||
$strict = false;
|
||||
|
||||
// Strict sanitizing if not Keymaster or Super-Mod
|
||||
} else {
|
||||
$strict = true;
|
||||
}
|
||||
|
||||
// Sanitize the request value (possibly not strictly)
|
||||
$suggest = sanitize_user( $request, $strict );
|
||||
|
||||
// Bail if searching for invalid user string
|
||||
if ( empty( $suggest ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// These single characters should not trigger a user query
|
||||
$disallowed_single_chars = array( '@', '.', '_', '-', '+', '!', '#', '$', '%', '&', '\\', '*', '+', '/', '=', '?', '^', '`', '{', '|', '}', '~' );
|
||||
|
||||
// Bail if request is only for the above single characters
|
||||
if ( in_array( $suggest, $disallowed_single_chars, true ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
// Allow the maximum number of results to be filtered
|
||||
$number = (int) apply_filters( 'bbp_suggest_user_count', 10 );
|
||||
|
||||
// Query database for users based on above criteria
|
||||
$users_query = new WP_User_Query( array(
|
||||
'search' => '*' . bbp_db()->esc_like( $_REQUEST['q'] ) . '*',
|
||||
'fields' => array( 'ID', 'user_nicename' ),
|
||||
'search_columns' => array( 'ID', 'user_nicename', 'user_email' ),
|
||||
'orderby' => 'ID'
|
||||
'search' => '*' . bbp_db()->esc_like( $suggest ) . '*',
|
||||
'fields' => $fields,
|
||||
'search_columns' => $search,
|
||||
'orderby' => 'ID',
|
||||
'number' => $number,
|
||||
'count_total' => false
|
||||
) );
|
||||
|
||||
// If we found some users, loop through and display them
|
||||
// If we found some users, loop through and output them to the AJAX
|
||||
if ( ! empty( $users_query->results ) ) {
|
||||
foreach ( (array) $users_query->results as $user ) {
|
||||
printf( esc_html__( '%s - %s', 'bbpress' ), bbp_get_user_id( $user->ID ), bbp_get_user_nicename( $user->ID, array( 'force' => $user->user_nicename ) ) . "\n" );
|
||||
printf( esc_html__( '%1$s - %2$s', 'bbpress' ), bbp_get_user_id( $user->ID ), bbp_get_user_nicename( $user->ID, array( 'force' => $user->user_nicename ) ) . "\n" );
|
||||
}
|
||||
}
|
||||
die();
|
||||
|
||||
@@ -635,8 +635,17 @@ class BBP_Forums_Admin {
|
||||
}
|
||||
}
|
||||
|
||||
// simple hack to show the forum description under the title
|
||||
bbp_forum_content( $forum->ID );
|
||||
// Only show content if user can read it and there is no password
|
||||
if ( current_user_can( 'read_forum', $forum->ID ) && ! post_password_required( $forum ) ) {
|
||||
|
||||
// Get the forum description
|
||||
$content = bbp_get_forum_content( $forum->ID );
|
||||
|
||||
// Only proceed if there is a description
|
||||
if ( ! empty( $content ) ) {
|
||||
echo '<div class="bbp-escaped-content">' . esc_html( wp_trim_excerpt( $content, $forum ) ) . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Sort & return
|
||||
return $this->sort_row_actions( $actions );
|
||||
|
||||
@@ -163,6 +163,28 @@ function bbp_admin_get_settings_fields() {
|
||||
|
||||
'bbp_settings_features' => array(
|
||||
|
||||
// Allow auto embedding setting
|
||||
'_bbp_use_autoembed' => array(
|
||||
'title' => esc_html__( 'Auto-embed links', 'bbpress' ),
|
||||
'callback' => 'bbp_admin_setting_callback_use_autoembed',
|
||||
'sanitize_callback' => 'intval',
|
||||
'args' => array()
|
||||
),
|
||||
|
||||
// Set reply threading level
|
||||
'_bbp_thread_replies_depth' => array(
|
||||
'title' => esc_html__( 'Reply Threading', 'bbpress' ),
|
||||
'callback' => 'bbp_admin_setting_callback_thread_replies_depth',
|
||||
'sanitize_callback' => 'intval',
|
||||
'args' => array()
|
||||
),
|
||||
|
||||
// Allow threaded replies
|
||||
'_bbp_allow_threaded_replies' => array(
|
||||
'sanitize_callback' => 'intval',
|
||||
'args' => array()
|
||||
),
|
||||
|
||||
// Allow topic and reply revisions
|
||||
'_bbp_allow_revisions' => array(
|
||||
'title' => esc_html__( 'Revisions', 'bbpress' ),
|
||||
@@ -203,22 +225,6 @@ function bbp_admin_get_settings_fields() {
|
||||
'args' => array()
|
||||
),
|
||||
|
||||
// Allow per-forum moderators
|
||||
'_bbp_allow_forum_mods' => array(
|
||||
'title' => esc_html__( 'Forum Moderators', 'bbpress' ),
|
||||
'callback' => 'bbp_admin_setting_callback_forum_mods',
|
||||
'sanitize_callback' => 'intval',
|
||||
'args' => array()
|
||||
),
|
||||
|
||||
// Allow moderators to edit users
|
||||
'_bbp_allow_super_mods' => array(
|
||||
'title' => esc_html__( 'Super Moderators', 'bbpress' ),
|
||||
'callback' => 'bbp_admin_setting_callback_super_mods',
|
||||
'sanitize_callback' => 'intval',
|
||||
'args' => array()
|
||||
),
|
||||
|
||||
// Allow topic tags
|
||||
'_bbp_allow_search' => array(
|
||||
'title' => esc_html__( 'Search', 'bbpress' ),
|
||||
@@ -235,25 +241,20 @@ function bbp_admin_get_settings_fields() {
|
||||
'sanitize_callback' => 'intval'
|
||||
),
|
||||
|
||||
// Allow auto embedding setting
|
||||
'_bbp_use_autoembed' => array(
|
||||
'title' => esc_html__( 'Auto-embed links', 'bbpress' ),
|
||||
'callback' => 'bbp_admin_setting_callback_use_autoembed',
|
||||
// Allow per-forum moderators
|
||||
'_bbp_allow_forum_mods' => array(
|
||||
'title' => esc_html__( 'Forum Moderators', 'bbpress' ),
|
||||
'callback' => 'bbp_admin_setting_callback_forum_mods',
|
||||
'sanitize_callback' => 'intval',
|
||||
'args' => array()
|
||||
),
|
||||
|
||||
// Set reply threading level
|
||||
'_bbp_thread_replies_depth' => array(
|
||||
'title' => esc_html__( 'Reply Threading', 'bbpress' ),
|
||||
'callback' => 'bbp_admin_setting_callback_thread_replies_depth',
|
||||
'sanitize_callback' => 'intval',
|
||||
'args' => array()
|
||||
),
|
||||
|
||||
// Allow threaded replies
|
||||
'_bbp_allow_threaded_replies' => array(
|
||||
// Allow moderators to edit users
|
||||
'_bbp_allow_super_mods' => array(
|
||||
'title' => esc_html__( 'Super Moderators', 'bbpress' ),
|
||||
'callback' => 'bbp_admin_setting_callback_super_mods',
|
||||
'sanitize_callback' => 'intval',
|
||||
'capability' => 'edit_users',
|
||||
'args' => array()
|
||||
)
|
||||
),
|
||||
@@ -837,6 +838,7 @@ function bbp_admin_setting_callback_forum_mods() {
|
||||
|
||||
<input name="_bbp_allow_forum_mods" id="_bbp_allow_forum_mods" type="checkbox" value="1" <?php checked( bbp_allow_forum_mods( true ) ); bbp_maybe_admin_setting_disabled( '_bbp_allow_forum_mods' ); ?> />
|
||||
<label for="_bbp_allow_forum_mods"><?php esc_html_e( 'Allow forums to have dedicated moderators', 'bbpress' ); ?></label>
|
||||
<p class="description"><?php esc_html_e( 'This does not include the ability to edit users.', 'bbpress' ); ?></p>
|
||||
|
||||
<?php
|
||||
}
|
||||
@@ -850,7 +852,8 @@ function bbp_admin_setting_callback_super_mods() {
|
||||
?>
|
||||
|
||||
<input name="_bbp_allow_super_mods" id="_bbp_allow_super_mods" type="checkbox" value="1" <?php checked( bbp_allow_super_mods( false ) ); bbp_maybe_admin_setting_disabled( '_bbp_allow_super_mods' ); ?> />
|
||||
<label for="_bbp_allow_super_mods"><?php esc_html_e( 'Allow moderators to edit other users', 'bbpress' ); ?></label>
|
||||
<label for="_bbp_allow_super_mods"><?php esc_html_e( 'Allow Moderators and Keymasters to edit users', 'bbpress' ); ?></label>
|
||||
<p class="description"><?php esc_html_e( 'This includes roles, passwords, and email addresses.', 'bbpress' ); ?></p>
|
||||
|
||||
<?php
|
||||
}
|
||||
@@ -968,7 +971,7 @@ function bbp_admin_setting_callback_subtheme_id() {
|
||||
|
||||
if ( ! empty( $theme_options ) ) : ?>
|
||||
|
||||
<select name="_bbp_theme_package_id" id="_bbp_theme_package_id" <?php bbp_maybe_admin_setting_disabled( '_bbp_theme_package_id' ); ?>><?php echo $theme_options ?></select>
|
||||
<select name="_bbp_theme_package_id" id="_bbp_theme_package_id" <?php bbp_maybe_admin_setting_disabled( '_bbp_theme_package_id' ); ?>><?php echo $theme_options; ?></select>
|
||||
<label for="_bbp_theme_package_id"><?php esc_html_e( 'will serve all bbPress templates', 'bbpress' ); ?></label>
|
||||
|
||||
<?php else : ?>
|
||||
@@ -1464,7 +1467,7 @@ function bbp_admin_setting_callback_group_forums_root_id() {
|
||||
|
||||
// Button & text
|
||||
$button = '<a href="' . esc_url( $new_url ) . '">' . esc_html__( 'create a new one', 'bbpress' ) . '</a>';
|
||||
$text = esc_html__( 'Use %s to contain your group forums, or %s', 'bbpress' );
|
||||
$text = esc_html__( 'Use %s to contain your group forums, or %s', 'bbpress' ); //phpcs:ignore
|
||||
} else {
|
||||
$text = esc_html__( 'Use %s to contain your group forums', 'bbpress' );
|
||||
}
|
||||
@@ -1517,7 +1520,7 @@ function bbp_admin_settings() {
|
||||
?>
|
||||
|
||||
<div class="wrap">
|
||||
<h1 class="wp-heading-inline"><?php esc_html_e( 'Forums Settings', 'bbpress' ) ?></h1>
|
||||
<h1 class="wp-heading-inline"><?php esc_html_e( 'Forums Settings', 'bbpress' ); ?></h1>
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<form action="options.php" method="post">
|
||||
@@ -1567,7 +1570,7 @@ function bbp_converter_setting_callback_platform() {
|
||||
$options .= '<option value="' . esc_attr( $name ) . '"' . selected( $name, $current, false ) . '>' . esc_html( $name ) . '</option>';
|
||||
} ?>
|
||||
|
||||
<select name="_bbp_converter_platform" id="_bbp_converter_platform"><?php echo $options ?></select>
|
||||
<select name="_bbp_converter_platform" id="_bbp_converter_platform"><?php echo $options; ?></select>
|
||||
<p class="description"><?php esc_html_e( 'The previous forum software', 'bbpress' ); ?></p>
|
||||
|
||||
<?php
|
||||
@@ -1792,7 +1795,7 @@ function bbp_converter_settings_page() {
|
||||
|
||||
// Starting or continuing?
|
||||
$progress_text = ! empty( $step )
|
||||
? sprintf( esc_html__( 'Previously stopped at step %d of %d', 'bbpress' ), $step, $max )
|
||||
? sprintf( esc_html__( 'Previously stopped at step %1$d of %2$d', 'bbpress' ), $step, $max )
|
||||
: esc_html__( 'Ready to go.', 'bbpress' ); ?>
|
||||
|
||||
<div class="wrap">
|
||||
@@ -1957,7 +1960,7 @@ function bbp_maybe_admin_setting_disabled( $option_key = '' ) {
|
||||
* @param string $default
|
||||
* @param bool $slug
|
||||
*/
|
||||
function bbp_form_option( $option, $default = '' , $slug = false ) {
|
||||
function bbp_form_option( $option, $default = '', $slug = false ) {
|
||||
echo bbp_get_form_option( $option, $default, $slug );
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -462,7 +462,7 @@ function bbp_make_emails_clickable( $text = '' ) {
|
||||
* @return string
|
||||
*/
|
||||
function bbp_make_mentions_clickable( $text = '' ) {
|
||||
return preg_replace_callback( '#@([0-9a-zA-Z-_]+)#i', 'bbp_make_mentions_clickable_callback', $text );
|
||||
return preg_replace_callback( '#([\s>])@([0-9a-zA-Z-_]+)#i', 'bbp_make_mentions_clickable_callback', $text );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -476,30 +476,49 @@ function bbp_make_mentions_clickable( $text = '' ) {
|
||||
*/
|
||||
function bbp_make_mentions_clickable_callback( $matches = array() ) {
|
||||
|
||||
// Bail if the match is empty malformed
|
||||
if ( empty( $matches[2] ) || ! is_string( $matches[2] ) ) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
// Get user; bail if not found
|
||||
$user = get_user_by( 'slug', $matches[1] );
|
||||
$user = get_user_by( 'slug', $matches[2] );
|
||||
if ( empty( $user ) || bbp_is_user_inactive( $user->ID ) ) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
// Default anchor classes
|
||||
$classes = array(
|
||||
'bbp-user-mention',
|
||||
'bbp-user-id-' . absint( $user->ID )
|
||||
);
|
||||
|
||||
// Filter classes
|
||||
$classes = (array) apply_filters( 'bbp_make_mentions_clickable_classes', array(
|
||||
'bbp-user-id-' . $user->ID,
|
||||
'bbp-user-mention'
|
||||
) );
|
||||
$classes = (array) apply_filters( 'bbp_make_mentions_clickable_classes', $classes, $user );
|
||||
|
||||
// Escape & implode if not empty, otherwise an empty string
|
||||
$class_str = ! empty( $classes )
|
||||
? implode( ' ', array_map( 'sanitize_html_class', $classes ) )
|
||||
: '';
|
||||
|
||||
// Setup as a variable to avoid a potentially empty class attribute
|
||||
$class = ! empty( $class_str )
|
||||
? ' class="' . esc_attr( $class_str ) . '"'
|
||||
: '';
|
||||
|
||||
// Create the link to the user's profile
|
||||
$html = '<a href="%1$s"' . $class . '">%2$s</a>';
|
||||
$url = bbp_get_user_profile_url( $user->ID );
|
||||
$clicky = '<a href="%1$s" class="' . esc_attr( $class_str ) . '">%2$s</a>';
|
||||
$anchor = sprintf( $clicky, esc_url( $url ), esc_html( $matches[0] ) );
|
||||
$anchor = sprintf( $html, esc_url( $url ), esc_html( $matches[0] ) );
|
||||
|
||||
// Prevent this link from being followed by bots
|
||||
$link = bbp_rel_nofollow( $anchor );
|
||||
|
||||
return $link;
|
||||
// Concatenate the matches into the return value
|
||||
$retval = $matches[1] . $link;
|
||||
|
||||
// Return the link
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/** Numbers *******************************************************************/
|
||||
|
||||
@@ -671,16 +671,21 @@ class BBP_Shortcodes {
|
||||
}
|
||||
|
||||
// Set passed attribute to $search_terms for clarity
|
||||
$search_terms = empty( $attr['search'] ) ? bbp_get_search_terms() : $attr['search'];
|
||||
$search_terms = empty( $attr['search'] )
|
||||
? bbp_get_search_terms()
|
||||
: $attr['search'];
|
||||
|
||||
// Get the rewrite ID (one time, to avoid repeated calls)
|
||||
$rewrite_id = bbp_get_search_rewrite_id();
|
||||
|
||||
// Unset globals
|
||||
$this->unset_globals();
|
||||
|
||||
// Set terms for query
|
||||
set_query_var( bbp_get_search_rewrite_id(), $search_terms );
|
||||
set_query_var( $rewrite_id, $search_terms );
|
||||
|
||||
// Start output buffer
|
||||
$this->start( bbp_get_search_rewrite_id() );
|
||||
$this->start( $rewrite_id );
|
||||
|
||||
// Output template
|
||||
bbp_get_template_part( 'content', 'search' );
|
||||
|
||||
@@ -134,11 +134,13 @@ function bbp_is_forum( $post_id = 0 ) {
|
||||
* @return bool
|
||||
*/
|
||||
function bbp_is_forum_archive() {
|
||||
global $wp_query;
|
||||
|
||||
// Default to false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// In forum archive
|
||||
if ( is_post_type_archive( bbp_get_forum_post_type() ) || bbp_is_query_name( 'bbp_forum_archive' ) || ! empty( $wp_query->bbp_show_topics_on_root ) ) {
|
||||
$retval = true;
|
||||
@@ -182,11 +184,14 @@ function bbp_is_single_forum() {
|
||||
* @return bool True if it's the forum edit page, false if not
|
||||
*/
|
||||
function bbp_is_forum_edit() {
|
||||
global $wp_query, $pagenow;
|
||||
global $pagenow;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_forum_edit ) && ( $wp_query->bbp_is_forum_edit === true ) ) {
|
||||
$retval = true;
|
||||
@@ -277,11 +282,14 @@ function bbp_is_topic_archive() {
|
||||
* @return bool True if it's the topic edit page, false if not
|
||||
*/
|
||||
function bbp_is_topic_edit() {
|
||||
global $wp_query, $pagenow;
|
||||
global $pagenow;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_topic_edit ) && ( $wp_query->bbp_is_topic_edit === true ) ) {
|
||||
$retval = true;
|
||||
@@ -376,7 +384,7 @@ function bbp_is_topic_tag() {
|
||||
* @return bool True if editing a topic tag, false if not
|
||||
*/
|
||||
function bbp_is_topic_tag_edit() {
|
||||
global $wp_query, $pagenow, $taxnow;
|
||||
global $pagenow, $taxnow;
|
||||
|
||||
// Bail if topic-tags are off
|
||||
if ( ! bbp_allow_topic_tags() ) {
|
||||
@@ -386,6 +394,9 @@ function bbp_is_topic_tag_edit() {
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_topic_tag_edit ) && ( true === $wp_query->bbp_is_topic_tag_edit ) ) {
|
||||
$retval = true;
|
||||
@@ -456,11 +467,14 @@ function bbp_is_reply( $post_id = 0 ) {
|
||||
* @return bool True if it's the reply edit page, false if not
|
||||
*/
|
||||
function bbp_is_reply_edit() {
|
||||
global $wp_query, $pagenow;
|
||||
global $pagenow;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_reply_edit ) && ( true === $wp_query->bbp_is_reply_edit ) ) {
|
||||
$retval = true;
|
||||
@@ -527,11 +541,13 @@ function bbp_is_single_reply() {
|
||||
* @return bool True if it's the favorites page, false if not
|
||||
*/
|
||||
function bbp_is_favorites() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_favs ) && ( true === $wp_query->bbp_is_single_user_favs ) ) {
|
||||
$retval = true;
|
||||
@@ -549,11 +565,13 @@ function bbp_is_favorites() {
|
||||
* @return bool True if it's the subscriptions page, false if not
|
||||
*/
|
||||
function bbp_is_subscriptions() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_subs ) && ( true === $wp_query->bbp_is_single_user_subs ) ) {
|
||||
$retval = true;
|
||||
@@ -572,11 +590,13 @@ function bbp_is_subscriptions() {
|
||||
* @return bool True if it's the topics created page, false if not
|
||||
*/
|
||||
function bbp_is_topics_created() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_topics ) && ( true === $wp_query->bbp_is_single_user_topics ) ) {
|
||||
$retval = true;
|
||||
@@ -595,11 +615,13 @@ function bbp_is_topics_created() {
|
||||
* @return bool True if it's the replies created page, false if not
|
||||
*/
|
||||
function bbp_is_replies_created() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_replies ) && ( true === $wp_query->bbp_is_single_user_replies ) ) {
|
||||
$retval = true;
|
||||
@@ -617,11 +639,13 @@ function bbp_is_replies_created() {
|
||||
* @return bool True if it's the user's home, false if not
|
||||
*/
|
||||
function bbp_is_user_home() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_home ) && ( true === $wp_query->bbp_is_single_user_home ) ) {
|
||||
$retval = true;
|
||||
@@ -659,11 +683,13 @@ function bbp_is_user_home_edit() {
|
||||
* @return bool True if it's a user's profile page, false if not
|
||||
*/
|
||||
function bbp_is_single_user() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user ) && ( true === $wp_query->bbp_is_single_user ) ) {
|
||||
$retval = true;
|
||||
@@ -681,11 +707,13 @@ function bbp_is_single_user() {
|
||||
* @return bool True if it's a user's profile edit page, false if not
|
||||
*/
|
||||
function bbp_is_single_user_edit() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_edit ) && ( true === $wp_query->bbp_is_single_user_edit ) ) {
|
||||
$retval = true;
|
||||
@@ -703,11 +731,13 @@ function bbp_is_single_user_edit() {
|
||||
* @return bool True if it's a user's profile page, false if not
|
||||
*/
|
||||
function bbp_is_single_user_profile() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_profile ) && ( true === $wp_query->bbp_is_single_user_profile ) ) {
|
||||
$retval = true;
|
||||
@@ -725,11 +755,13 @@ function bbp_is_single_user_profile() {
|
||||
* @return bool True if it's a user's topics page, false if not
|
||||
*/
|
||||
function bbp_is_single_user_topics() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_topics ) && ( true === $wp_query->bbp_is_single_user_topics ) ) {
|
||||
$retval = true;
|
||||
@@ -747,11 +779,13 @@ function bbp_is_single_user_topics() {
|
||||
* @return bool True if it's a user's replies page, false if not
|
||||
*/
|
||||
function bbp_is_single_user_replies() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_replies ) && ( true === $wp_query->bbp_is_single_user_replies ) ) {
|
||||
$retval = true;
|
||||
@@ -769,11 +803,13 @@ function bbp_is_single_user_replies() {
|
||||
* @return bool True if it's a user's replies page, false if not
|
||||
*/
|
||||
function bbp_is_single_user_engagements() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_single_user_engagements ) && ( true === $wp_query->bbp_is_single_user_engagements ) ) {
|
||||
$retval = true;
|
||||
@@ -792,11 +828,13 @@ function bbp_is_single_user_engagements() {
|
||||
* @return bool Is it a view page?
|
||||
*/
|
||||
function bbp_is_single_view() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_view ) && ( true === $wp_query->bbp_is_view ) ) {
|
||||
$retval = true;
|
||||
@@ -820,7 +858,6 @@ function bbp_is_single_view() {
|
||||
* @return bool Is it a search page?
|
||||
*/
|
||||
function bbp_is_search() {
|
||||
global $wp_query;
|
||||
|
||||
// Bail if search is disabled
|
||||
if ( ! bbp_allow_search() ) {
|
||||
@@ -830,18 +867,24 @@ function bbp_is_search() {
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Get the rewrite ID (one time, to avoid repeated calls)
|
||||
$rewrite_id = bbp_get_search_rewrite_id();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_search ) && ( true === $wp_query->bbp_is_search ) ) {
|
||||
$retval = true;
|
||||
}
|
||||
|
||||
// Check query name
|
||||
if ( empty( $retval ) && bbp_is_query_name( bbp_get_search_rewrite_id() ) ) {
|
||||
if ( empty( $retval ) && bbp_is_query_name( $rewrite_id ) ) {
|
||||
$retval = true;
|
||||
}
|
||||
|
||||
// Check $_GET
|
||||
if ( empty( $retval ) && isset( $_REQUEST[ bbp_get_search_rewrite_id() ] ) && empty( $_REQUEST[ bbp_get_search_rewrite_id() ] ) ) {
|
||||
if ( empty( $retval ) && isset( $_REQUEST[ $rewrite_id ] ) && empty( $_REQUEST[ $rewrite_id ] ) ) {
|
||||
$retval = true;
|
||||
}
|
||||
|
||||
@@ -858,7 +901,6 @@ function bbp_is_search() {
|
||||
* @return bool Is it a search page?
|
||||
*/
|
||||
function bbp_is_search_results() {
|
||||
global $wp_query;
|
||||
|
||||
// Bail if search is disabled
|
||||
if ( ! bbp_allow_search() ) {
|
||||
@@ -868,6 +910,9 @@ function bbp_is_search_results() {
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_search_terms ) ) {
|
||||
$retval = true;
|
||||
@@ -895,11 +940,13 @@ function bbp_is_search_results() {
|
||||
* @return bool True if it's the edit page, false if not
|
||||
*/
|
||||
function bbp_is_edit() {
|
||||
global $wp_query;
|
||||
|
||||
// Assume false
|
||||
$retval = false;
|
||||
|
||||
// Get the main query global
|
||||
$wp_query = bbp_get_wp_query();
|
||||
|
||||
// Check query
|
||||
if ( ! empty( $wp_query->bbp_is_edit ) && ( $wp_query->bbp_is_edit === true ) ) {
|
||||
$retval = true;
|
||||
@@ -1102,9 +1149,15 @@ function bbp_has_shortcode( $text = '' ) {
|
||||
*/
|
||||
function is_bbpress() {
|
||||
|
||||
// Defalt to false
|
||||
// Default to false
|
||||
$retval = false;
|
||||
|
||||
// Bail if main query has not been populated.
|
||||
if ( ! bbp_get_wp_query() ) {
|
||||
_doing_it_wrong( __FUNCTION__, esc_html__( 'Conditional query tags do not work before the query is run. Before then, they always return false.', 'bbpress' ), '2.7.0' );
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/** Archives **************************************************************/
|
||||
|
||||
if ( bbp_is_forum_archive() ) {
|
||||
|
||||
@@ -407,12 +407,15 @@ add_action( 'bbp_user_edit_after', 'bbp_user_edit_after' );
|
||||
// Clean bbPress post caches when WordPress's is cleaned
|
||||
add_action( 'clean_post_cache', 'bbp_clean_post_cache', 10, 2 );
|
||||
|
||||
// User Creation
|
||||
add_action( 'invite_user', 'bbp_user_add_role_on_invite', 10, 3 );
|
||||
add_action( 'wpmu_activate_user', 'bbp_user_add_role_on_activate', 10, 3 );
|
||||
add_action( 'bbp_user_register', 'bbp_user_add_role_on_register', 10, 1 );
|
||||
// User Registration
|
||||
add_action( 'added_existing_user', 'bbp_user_add_role_on_register', 10, 1 );
|
||||
add_action( 'register_new_user', 'bbp_user_add_role_on_register', 10, 1 );
|
||||
add_action( 'bbp_user_register', 'bbp_user_add_role_on_register', 10, 1 );
|
||||
|
||||
// Invite a New User
|
||||
add_action( 'invite_user', 'bbp_user_add_role_on_invite', 10, 3 );
|
||||
|
||||
// Multisite Activation (does not work in wp-activate.php)
|
||||
add_action( 'wpmu_activate_user', 'bbp_user_add_role_on_activate', 10, 3 );
|
||||
|
||||
/**
|
||||
* bbPress needs to redirect the user around in a few different circumstances:
|
||||
@@ -433,6 +436,9 @@ add_action( 'bbp_template_redirect', 'bbp_check_topic_edit', 10 );
|
||||
add_action( 'bbp_template_redirect', 'bbp_check_reply_edit', 10 );
|
||||
add_action( 'bbp_template_redirect', 'bbp_check_topic_tag_edit', 10 );
|
||||
|
||||
// Must be after bbp_template_include_theme_compat
|
||||
add_action( 'bbp_template_redirect', 'bbp_remove_adjacent_posts', 10 );
|
||||
|
||||
// Theme-side POST requests
|
||||
add_action( 'bbp_post_request', 'bbp_do_ajax', 1 );
|
||||
add_action( 'bbp_post_request', 'bbp_edit_topic_tag_handler', 1 );
|
||||
|
||||
@@ -378,8 +378,8 @@ function bbp_post_request() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bail if no action
|
||||
if ( empty( $_POST['action'] ) ) {
|
||||
// Bail if no action, or if not a string (arrays not supported)
|
||||
if ( empty( $_POST['action'] ) || ! is_string( $_POST['action'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -411,8 +411,8 @@ function bbp_get_request() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bail if no action
|
||||
if ( empty( $_GET['action'] ) ) {
|
||||
// Bail if no action, or if not a string (arrays not supported)
|
||||
if ( empty( $_GET['action'] ) || ! is_string( $_GET['action'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -535,13 +535,14 @@ function bbp_parse_query( $posts_query ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get query variables
|
||||
$bbp_view = $posts_query->get( bbp_get_view_rewrite_id() );
|
||||
$bbp_user = $posts_query->get( bbp_get_user_rewrite_id() );
|
||||
$is_edit = $posts_query->get( bbp_get_edit_rewrite_id() );
|
||||
// Get query variables (default to null if not set)
|
||||
$bbp_view = $posts_query->get( bbp_get_view_rewrite_id(), null );
|
||||
$bbp_user = $posts_query->get( bbp_get_user_rewrite_id(), null );
|
||||
$is_edit = $posts_query->get( bbp_get_edit_rewrite_id(), null );
|
||||
$is_search = $posts_query->get( bbp_get_search_rewrite_id(), null );
|
||||
|
||||
// It is a user page - We'll also check if it is user edit
|
||||
if ( ! empty( $bbp_user ) ) {
|
||||
if ( ! is_null( $bbp_user ) ) {
|
||||
|
||||
/** Find User *********************************************************/
|
||||
|
||||
@@ -572,7 +573,7 @@ function bbp_parse_query( $posts_query ) {
|
||||
$is_engagements = $posts_query->get( bbp_get_user_engagements_rewrite_id() );
|
||||
|
||||
// View or edit?
|
||||
if ( ! empty( $is_edit ) ) {
|
||||
if ( ! is_null( $is_edit ) ) {
|
||||
|
||||
// We are editing a profile
|
||||
$posts_query->bbp_is_single_user_edit = true;
|
||||
@@ -644,7 +645,7 @@ function bbp_parse_query( $posts_query ) {
|
||||
bbpress()->displayed_user = $the_user;
|
||||
|
||||
// View Page
|
||||
} elseif ( ! empty( $bbp_view ) ) {
|
||||
} elseif ( ! is_null( $bbp_view ) ) {
|
||||
|
||||
// Check if the view exists by checking if there are query args are set
|
||||
$view_args = bbp_get_view_query_args( $bbp_view );
|
||||
@@ -665,7 +666,7 @@ function bbp_parse_query( $posts_query ) {
|
||||
$posts_query->bbp_is_404 = false;
|
||||
|
||||
// Search Page
|
||||
} elseif ( isset( $posts_query->query_vars[ bbp_get_search_rewrite_id() ] ) ) {
|
||||
} elseif ( ! is_null( $is_search ) ) {
|
||||
|
||||
// Check if there are search query args set
|
||||
$search_terms = bbp_get_search_terms();
|
||||
@@ -683,7 +684,7 @@ function bbp_parse_query( $posts_query ) {
|
||||
$posts_query->bbp_is_404 = false;
|
||||
|
||||
// Forum/Topic/Reply Edit Page
|
||||
} elseif ( ! empty( $is_edit ) ) {
|
||||
} elseif ( ! is_null( $is_edit ) ) {
|
||||
|
||||
// Get the post type from the main query loop
|
||||
$post_type = $posts_query->get( 'post_type' );
|
||||
|
||||
@@ -1026,3 +1026,25 @@ function bbp_force_comment_status( $open = false, $post_id = 0 ) {
|
||||
// Filter & return
|
||||
return (bool) apply_filters( 'bbp_force_comment_status', $retval, $open, $post_id, $post_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove "prev" and "next" relational links from <head> on bbPress pages.
|
||||
*
|
||||
* WordPress automatically generates these relational links to the current
|
||||
* page, but bbPress does not use these links, nor would they work the same.
|
||||
*
|
||||
* In this function, we remove these links when on a bbPress page. This also
|
||||
* prevents additional, unnecessary queries from running.
|
||||
*
|
||||
* @since 2.6.0 bbPress (r7071)
|
||||
*/
|
||||
function bbp_remove_adjacent_posts() {
|
||||
|
||||
// Bail if not a bbPress page
|
||||
if ( ! is_bbpress() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the WordPress core action for adjacent posts
|
||||
remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10 );
|
||||
}
|
||||
|
||||
@@ -297,8 +297,11 @@ function bbp_search_terms( $search_terms = '' ) {
|
||||
} else {
|
||||
|
||||
// Global
|
||||
if ( get_query_var( bbp_get_search_rewrite_id() ) ) {
|
||||
$search_terms = get_query_var( bbp_get_search_rewrite_id() );
|
||||
$search_terms = get_query_var( bbp_get_search_rewrite_id(), null );
|
||||
|
||||
// Searching globally
|
||||
if ( ! is_null( $search_terms ) ) {
|
||||
$search_terms = wp_unslash( $search_terms );
|
||||
|
||||
// Other searches
|
||||
} else {
|
||||
|
||||
@@ -148,7 +148,7 @@ function bbp_map_primary_meta_caps( $caps = array(), $cap = '', $user_id = 0, $a
|
||||
*
|
||||
* @param int $user_id
|
||||
*
|
||||
* @return string
|
||||
* @return mixed False if no change. String of new role if changed.
|
||||
*/
|
||||
function bbp_set_user_role( $user_id = 0, $new_role = '' ) {
|
||||
|
||||
@@ -159,15 +159,15 @@ function bbp_set_user_role( $user_id = 0, $new_role = '' ) {
|
||||
// User exists
|
||||
if ( ! empty( $user ) ) {
|
||||
|
||||
// Get users forum role
|
||||
// Get user forum role
|
||||
$role = bbp_get_user_role( $user_id );
|
||||
|
||||
// User already has this role so no new role is set
|
||||
if ( $new_role === $role ) {
|
||||
$new_role = false;
|
||||
|
||||
// Users role is different than the new role
|
||||
} else {
|
||||
// User role is different than the new (valid) role
|
||||
} elseif ( bbp_is_valid_role( $new_role ) ) {
|
||||
|
||||
// Remove the old role
|
||||
if ( ! empty( $role ) ) {
|
||||
@@ -306,6 +306,38 @@ function bbp_profile_update_role( $user_id = 0 ) {
|
||||
bbp_set_user_role( $user_id, $new_role );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a role string is valid
|
||||
*
|
||||
* @since 2.6.5
|
||||
*
|
||||
* @param string $role
|
||||
*
|
||||
* @return bool True if role is valid. False if role is not valid.
|
||||
*/
|
||||
function bbp_is_valid_role( $role = '' ) {
|
||||
|
||||
// Default return value
|
||||
$retval = false;
|
||||
|
||||
// Skip if no role to check
|
||||
if ( ! empty( $role ) && is_string( $role ) ) {
|
||||
|
||||
// Get the dynamic role IDs
|
||||
$roles = array_keys( bbp_get_dynamic_roles() );
|
||||
|
||||
// Skip if no known role IDs
|
||||
if ( ! empty( $roles ) ) {
|
||||
|
||||
// Is role in dynamic roles array?
|
||||
$retval = in_array( $role, $roles, true );
|
||||
}
|
||||
}
|
||||
|
||||
// Filter & return
|
||||
return (bool) apply_filters( 'bbp_is_valid_role', $retval, $role );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the default role to the current user if needed
|
||||
*
|
||||
|
||||
@@ -19,7 +19,11 @@ defined( 'ABSPATH' ) || exit;
|
||||
* @since 2.6.0 bbPress (r6674)
|
||||
*/
|
||||
function bbp_add_user_form_role_field() {
|
||||
?>
|
||||
|
||||
// Bail if current user cannot promote users
|
||||
if ( ! current_user_can( 'promote_users' ) ) {
|
||||
return;
|
||||
} ?>
|
||||
|
||||
<table class="form-table">
|
||||
<tr class="form-field">
|
||||
@@ -66,21 +70,26 @@ function bbp_add_user_form_role_field() {
|
||||
*/
|
||||
function bbp_user_add_role_to_signup_meta( $meta = array() ) {
|
||||
|
||||
// Posted role
|
||||
$forum_role = isset( $_POST['bbp-forums-role'] )
|
||||
// Bail if already added
|
||||
if ( ! empty( $meta['bbp_new_role'] ) ) {
|
||||
return $meta;
|
||||
}
|
||||
|
||||
// Role to validate
|
||||
$to_validate = ! empty( $_POST['bbp-forums-role'] ) && is_string( $_POST['bbp-forums-role'] )
|
||||
? sanitize_key( $_POST['bbp-forums-role'] )
|
||||
: bbp_get_default_role();
|
||||
: '';
|
||||
|
||||
// Role keys
|
||||
$roles = array_keys( bbp_get_dynamic_roles() );
|
||||
// Validate the signup role
|
||||
$valid_role = bbp_validate_registration_role( $to_validate );
|
||||
|
||||
// Bail if posted role is not in dynamic roles
|
||||
if ( empty( $forum_role ) || ! in_array( $forum_role, $roles, true ) ) {
|
||||
// Bail if errors
|
||||
if ( bbp_has_errors() ) {
|
||||
return $meta;
|
||||
}
|
||||
|
||||
// Add role to meta
|
||||
$meta['bbp_new_role'] = $forum_role;
|
||||
$meta['bbp_new_role'] = $valid_role;
|
||||
|
||||
// Return meta
|
||||
return $meta;
|
||||
@@ -97,16 +106,16 @@ function bbp_user_add_role_to_signup_meta( $meta = array() ) {
|
||||
*/
|
||||
function bbp_user_add_role_on_invite( $user_id = '', $role = '', $newuser_key = '' ) {
|
||||
|
||||
// Posted role
|
||||
$forum_role = isset( $_POST['bbp-forums-role'] )
|
||||
// Role to validate
|
||||
$to_validate = ! empty( $_POST['bbp-forums-role'] ) && is_string( $_POST['bbp-forums-role'] )
|
||||
? sanitize_key( $_POST['bbp-forums-role'] )
|
||||
: bbp_get_default_role();
|
||||
: '';
|
||||
|
||||
// Role keys
|
||||
$roles = array_keys( bbp_get_dynamic_roles() );
|
||||
// Validate the signup role
|
||||
$valid_role = bbp_validate_registration_role( $to_validate );
|
||||
|
||||
// Bail if posted role is not in dynamic roles
|
||||
if ( empty( $forum_role ) || ! in_array( $forum_role, $roles, true ) ) {
|
||||
// Bail if errors
|
||||
if ( bbp_has_errors() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -117,7 +126,7 @@ function bbp_user_add_role_on_invite( $user_id = '', $role = '', $newuser_key =
|
||||
$user_option = get_option( $option_key, array() );
|
||||
|
||||
// Add the new role
|
||||
$user_option['bbp_new_role'] = $forum_role;
|
||||
$user_option['bbp_new_role'] = $valid_role;
|
||||
|
||||
// Update the invitation
|
||||
update_option( $option_key, $user_option );
|
||||
@@ -132,21 +141,21 @@ function bbp_user_add_role_on_invite( $user_id = '', $role = '', $newuser_key =
|
||||
*/
|
||||
function bbp_user_add_role_on_register( $user_id = '' ) {
|
||||
|
||||
// Posted role
|
||||
$forum_role = isset( $_POST['bbp-forums-role'] )
|
||||
// Role to validate
|
||||
$to_validate = ! empty( $_POST['bbp-forums-role'] ) && is_string( $_POST['bbp-forums-role'] )
|
||||
? sanitize_key( $_POST['bbp-forums-role'] )
|
||||
: bbp_get_default_role();
|
||||
: '';
|
||||
|
||||
// Role keys
|
||||
$roles = array_keys( bbp_get_dynamic_roles() );
|
||||
// Validate the signup role
|
||||
$valid_role = bbp_validate_registration_role( $to_validate );
|
||||
|
||||
// Bail if posted role is not in dynamic roles
|
||||
if ( empty( $forum_role ) || ! in_array( $forum_role, $roles, true ) ) {
|
||||
// Bail if errors
|
||||
if ( bbp_has_errors() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the user role
|
||||
bbp_set_user_role( $user_id, $forum_role );
|
||||
bbp_set_user_role( $user_id, $valid_role );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,19 +167,97 @@ function bbp_user_add_role_on_register( $user_id = '' ) {
|
||||
*/
|
||||
function bbp_user_add_role_on_activate( $user_id = 0, $password = '', $meta = array() ) {
|
||||
|
||||
// Posted role
|
||||
$forum_role = isset( $meta['bbp_new_role'] )
|
||||
// Role to validate
|
||||
$to_validate = ! empty( $meta['bbp_new_role'] ) && is_string( $meta['bbp_new_role'] )
|
||||
? sanitize_key( $meta['bbp_new_role'] )
|
||||
: bbp_get_default_role();
|
||||
: '';
|
||||
|
||||
// Sanitize role
|
||||
$roles = array_keys( bbp_get_dynamic_roles() );
|
||||
// Validate the signup role
|
||||
$valid_role = bbp_validate_activation_role( $to_validate );
|
||||
|
||||
// Bail if posted role is not in dynamic roles
|
||||
if ( empty( $forum_role ) || ! in_array( $forum_role, $roles, true ) ) {
|
||||
// Bail if errors
|
||||
if ( bbp_has_errors() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the user role
|
||||
bbp_set_user_role( $user_id, $forum_role );
|
||||
bbp_set_user_role( $user_id, $valid_role );
|
||||
}
|
||||
|
||||
/** Validators ****************************************************************/
|
||||
|
||||
/**
|
||||
* Validate the Forum role during signup
|
||||
*
|
||||
* This helper function performs a number of generic checks, and encapsulates
|
||||
* the logic used to validate if a Forum Role is valid, typically during new
|
||||
* user registration, but also when adding an existing user to a site in
|
||||
* Multisite installations.
|
||||
*
|
||||
* @since 2.6.5
|
||||
*
|
||||
* @param string $to_validate A role ID to validate
|
||||
* @return string A valid role ID, or empty string on error
|
||||
*/
|
||||
function bbp_validate_signup_role( $to_validate = '' ) {
|
||||
|
||||
// Default return value
|
||||
$retval = '';
|
||||
|
||||
// Add error if role is empty
|
||||
if ( empty( $to_validate ) ) {
|
||||
bbp_add_error( 'bbp_signup_role_empty', __( '<strong>ERROR</strong>: Empty role.', 'bbpress' ) );
|
||||
}
|
||||
|
||||
// Add error if posted role is not a valid role
|
||||
if ( ! bbp_is_valid_role( $to_validate ) ) {
|
||||
bbp_add_error( 'bbp_signup_role_invalid', __( '<strong>ERROR</strong>: Invalid role.', 'bbpress' ) );
|
||||
}
|
||||
|
||||
// If no errors, set return value to the role to validate
|
||||
if ( ! bbp_has_errors() ) {
|
||||
$retval = $to_validate;
|
||||
}
|
||||
|
||||
// Filter & return
|
||||
return (string) apply_filters( 'bbp_validate_signup_role', $retval, $to_validate );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the Forum role during the registration process
|
||||
*
|
||||
* @since 2.6.5
|
||||
*
|
||||
* @param string $to_validate A well-formed (string) role ID to validate
|
||||
* @return string A valid role ID, or empty string on error
|
||||
*/
|
||||
function bbp_validate_registration_role( $to_validate = '' ) {
|
||||
|
||||
// Default return value
|
||||
$retval = bbp_get_default_role();
|
||||
|
||||
// Conditionally handle posted values for capable users
|
||||
if ( is_admin() && current_user_can( 'create_users' ) ) {
|
||||
$retval = $to_validate;
|
||||
}
|
||||
|
||||
// Validate & return
|
||||
return bbp_validate_signup_role( $retval );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the Forum role during activation
|
||||
*
|
||||
* This function exists simply for parity with registrations, and to maintain an
|
||||
* intentional layer of abstraction from the more generic function it uses.
|
||||
*
|
||||
* @since 2.6.5
|
||||
*
|
||||
* @param string $to_validate A well-formed (string) role ID to validate
|
||||
* @return string A valid role ID, or empty string on error
|
||||
*/
|
||||
function bbp_validate_activation_role( $to_validate = '' ) {
|
||||
|
||||
// Validate & return
|
||||
return bbp_validate_signup_role( $to_validate );
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
=== bbPress ===
|
||||
Contributors: matt, johnjamesjacoby, jmdodd, netweb, sergeybiryukov
|
||||
Tags: forum, forums, discussion, support
|
||||
Requires at least: 4.7
|
||||
Tested up to: 5.4
|
||||
Stable tag: 2.6.4
|
||||
Stable tag: 2.6.5
|
||||
License: GPLv2 or later
|
||||
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
Requires PHP: 5.6.20
|
||||
Requires at least: 4.7
|
||||
|
||||
bbPress is forum software for WordPress.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Plugin Name: Code Syntax Block
|
||||
* Plugin URI: https://github.com/mkaz/code-syntax-block
|
||||
* Description: A plugin to extend Gutenberg code block with syntax highlighting
|
||||
* Version: 1.3.2
|
||||
* Version: 1.3.3
|
||||
* Author: Marcus Kazmierczak
|
||||
* Author URI: https://mkaz.blog/
|
||||
* License: GPL2
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
// version added, used in URL
|
||||
define( 'MKAZ_CODE_SYNTAX_BLOCK_VERSION', '1.3.2' );
|
||||
define( 'MKAZ_CODE_SYNTAX_BLOCK_VERSION', '1.3.3' );
|
||||
require dirname( __FILE__ ) . '/prism-languages.php';
|
||||
|
||||
/**
|
||||
@@ -188,3 +188,16 @@ function mkaz_prism_theme_css_ver() {
|
||||
}
|
||||
return MKAZ_CODE_SYNTAX_BLOCK_VERSION;
|
||||
}
|
||||
|
||||
// extend code tag to allow lang attribute
|
||||
add_filter( 'wp_kses_allowed_html', function( $tags ) {
|
||||
|
||||
if ( is_array( $tags['code'] ) ) {
|
||||
$tags['code']['lang'] = array();
|
||||
} else {
|
||||
$tags['code'] = array(
|
||||
'lang' => array(),
|
||||
);
|
||||
}
|
||||
return $tags;
|
||||
}, 10, 2);
|
||||
|
||||
@@ -5,7 +5,7 @@ Tags: code, code syntax, syntax highlight, code highlighting
|
||||
Requires at least: 5.0
|
||||
Tested up to: 5.4
|
||||
Requires PHP: 5.2.4
|
||||
Stable tag: 1.3.2
|
||||
Stable tag: 1.3.3
|
||||
License: GPLv2 or later
|
||||
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
@@ -109,6 +109,10 @@ Example:
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 1.3.3 =
|
||||
|
||||
Fix block validation error for user roles with restricted permissions.
|
||||
|
||||
= 1.3.2 =
|
||||
|
||||
Fix issue with PHP warning when no posts
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
* Plugin Name: Email Subscribers & Newsletters
|
||||
* Plugin URI: https://www.icegram.com/
|
||||
* Description: Add subscription forms on website, send HTML newsletters & automatically notify subscribers about new blog posts once it is published.
|
||||
* Version: 4.4.8
|
||||
* Version: 4.4.10
|
||||
* Author: Icegram
|
||||
* Author URI: https://www.icegram.com/
|
||||
* Requires at least: 3.9
|
||||
* Tested up to: 5.4.1
|
||||
* Tested up to: 5.4.2
|
||||
* Requires PHP: 5.6
|
||||
* Text Domain: email-subscribers
|
||||
* Domain Path: /lite/languages/
|
||||
@@ -156,7 +156,7 @@ if ( $is_premium ) {
|
||||
/* ***************************** Initial Compatibility Work (End) ******************* */
|
||||
|
||||
if ( ! defined( 'ES_PLUGIN_VERSION' ) ) {
|
||||
define( 'ES_PLUGIN_VERSION', '4.4.8' );
|
||||
define( 'ES_PLUGIN_VERSION', '4.4.10' );
|
||||
}
|
||||
|
||||
// Plugin Folder Path.
|
||||
|
||||
@@ -567,7 +567,7 @@ class Email_Subscribers_Admin {
|
||||
|
||||
public function count_contacts_by_list() {
|
||||
|
||||
$list_id = (int) ig_es_get_request_data( 'list_id', 0 );
|
||||
$list_id = ig_es_get_request_data( 'list_id', 0 );
|
||||
$status = ig_es_get_request_data( 'status', 'all' );
|
||||
|
||||
if ( $list_id == 0 ) {
|
||||
|
||||
@@ -1845,7 +1845,10 @@ div.broadcast_main_content{
|
||||
div.broadcast_side_content{
|
||||
width: 30% ;
|
||||
}
|
||||
|
||||
#ig_es_post_notification_list_ids+.select2-container{
|
||||
position: absolute;
|
||||
width: 75% !important;
|
||||
}
|
||||
.es-preview.broadcast-preview p {
|
||||
margin : 1em 0 !important;
|
||||
}
|
||||
@@ -1853,4 +1856,9 @@ div.broadcast_side_content{
|
||||
.es-preview.broadcast-preview img.aligncenter {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
#es-shortcode{
|
||||
-webkit-user-select: all;
|
||||
-ms-user-select: all;
|
||||
user-select: all;
|
||||
}
|
||||
Las diferiencias del archivo han sido suprimidas porque una o mas lineas son muy largas
@@ -270,6 +270,11 @@
|
||||
$('#ig_es_broadcast_list_ids').change(function () {
|
||||
var selected_list_id = $(this).val();
|
||||
|
||||
if( ! selected_list_id ) {
|
||||
jQuery('.ig_es_list_contacts_count').text(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update total count in lists
|
||||
var params = {
|
||||
action: 'count_contacts_by_list',
|
||||
@@ -287,8 +292,8 @@
|
||||
response = JSON.parse(response);
|
||||
if (response.hasOwnProperty('total')) {
|
||||
var total = response.total;
|
||||
var total_contacts_text = "<h2 class='text-sm font-normal text-gray-600'>Total Contacts: <span class='text-base font-medium text-gray-700'> " + total + "</span></h2>";
|
||||
var total_recipients_text = "<span class='font-medium text-base text-gray-700'>" + total + " <span class='text-base font-medium text-gray-700'></span><span class='font-normal text-sm text-gray-500'> recipients </span>";
|
||||
var total_contacts_text = "<h2 class='text-sm font-normal text-gray-600'>Total Contacts: <span class='text-base font-medium text-gray-700'> <span class='ig_es_list_contacts_count'>" + total + "</span></span></h2>";
|
||||
var total_recipients_text = "<div class='mt-1.5 py-2'><span class='font-medium text-base text-gray-700'><span class='ig_es_list_contacts_count'>" + total + "</span> <span class='text-base font-medium text-gray-700'></span><span class='font-normal text-sm text-gray-500'> recipients </span></div>";
|
||||
$('#ig_es_total_contacts').html(total_contacts_text);
|
||||
$('#ig_es_total_recipients').html(total_recipients_text);
|
||||
if (total == 0) {
|
||||
|
||||
@@ -304,10 +304,10 @@ if ( ! class_exists( 'Email_Subscribers' ) ) {
|
||||
$show_notice = apply_filters( 'ig_es_show_wp_cron_notice', $show_notice );
|
||||
|
||||
if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON && $notice_option != 'yes' && $show_notice ) {
|
||||
$es_cron_url = 'https://www.icegram.com/documentation/how-to-enable-the-wordpress-cron/?utm_source=es&utm_medium=in_app&utm_campaign=view_admin_notice';
|
||||
$cpanel_url = 'https://www.icegram.com/documentation/es-how-to-schedule-cron-emails-in-cpanel/?utm_source=es&utm_medium=in_app&utm_campaign=view_admin_notice';
|
||||
$es_pro_url = 'https://www.icegram.com/documentation/es-how-to-schedule-cron-emails-in-cpanel/?utm_source=es&utm_medium=in_app&utm_campaign=view_admin_notice';
|
||||
$disable_wp_cron_notice = sprintf( __( 'WordPress Cron is disable on your site. Email notifications from Email Subscribers plugin will not be sent automatically. <a href="%s" target="_blank" >Here\'s how you can enable it.</a>', 'email-subscribers' ), $es_cron_url );
|
||||
$es_cron_url = 'https://www.icegram.com/documentation/how-to-enable-the-wordpress-cron/?utm_medium=enable_wordpress_cron&utm_source=in_app&utm_campaign=view_admin_notice';
|
||||
$cpanel_url = 'https://www.icegram.com/documentation/es-how-to-schedule-cron-emails-in-cpanel/?utm_source=schedule_cron_in_cpanel&utm_medium=in_app&utm_campaign=view_admin_notice';
|
||||
$es_pro_url = 'https://www.icegram.com/documentation/es-how-to-schedule-cron-emails-in-cpanel/?utm_source=schedule_cron_in_cpanel&utm_medium=in_app&utm_campaign=view_admin_notice';
|
||||
$disable_wp_cron_notice = sprintf( __( 'WordPress Cron is disabled on your site. Email notifications from Email Subscribers plugin will not be sent automatically. <a href="%s" target="_blank" >Here\'s how you can enable it.</a>', 'email-subscribers' ), $es_cron_url );
|
||||
$disable_wp_cron_notice .= '<br/>' . sprintf( __( 'Or schedule Cron in <a href="%s" target="_blank">cPanel</a>', 'email-subscribers' ), $cpanel_url );
|
||||
$disable_wp_cron_notice .= '<br/>' . sprintf( __( 'Or use <strong><a href="%s" target="_blank">Email Subscribers Pro</a></strong> for automatic Cron support', 'email-subscribers' ), $es_pro_url );
|
||||
$html = '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">' . $disable_wp_cron_notice . '<a style="float:right" class="es-admin-btn es-admin-btn-secondary " href="' . admin_url() . '?es_dismiss_admin_notice=1&option_name=wp_cron_notice">' . __( 'OK, I Got it!',
|
||||
|
||||
@@ -43,9 +43,7 @@ class ES_Common {
|
||||
public static function es_process_template_body( $content, $tmpl_id = 0, $campaign_id = 0 ) {
|
||||
$content = convert_smilies( wptexturize( $content ) );
|
||||
|
||||
if ( isset( $GLOBALS['wp_embed'] ) ) {
|
||||
$content = $GLOBALS['wp_embed']->autoembed( $content );
|
||||
}
|
||||
$content = self::handle_oembed_content( $content );
|
||||
|
||||
$content = wpautop( $content );
|
||||
$content = do_shortcode( shortcode_unautop( $content ) );
|
||||
@@ -75,6 +73,107 @@ class ES_Common {
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to handle oembed content
|
||||
*
|
||||
* @param string @content Content.
|
||||
*
|
||||
* @return string $content
|
||||
*
|
||||
* @since 4.4.9
|
||||
*/
|
||||
public static function handle_oembed_content( $content = '' ) {
|
||||
|
||||
if ( ! empty( $content ) && isset( $GLOBALS['wp_embed'] ) ) {
|
||||
add_filter( 'embed_oembed_html', array( 'ES_Common', 'handle_link_in_email_content' ), 10, 4 );
|
||||
$content = $GLOBALS['wp_embed']->autoembed( $content );
|
||||
remove_filter( 'embed_oembed_html', array( 'ES_Common', 'handle_link_in_email_content' ), 10, 4 );
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to handle link in email content
|
||||
*
|
||||
* URL from {{POSTLINK-ONLY}} was being converted to oembed html if it is not wrapped inside <a> tag's href attribute and is on a seperate line in ES template content
|
||||
* resulting in a link html for {{POSTLINK-ONLY}} instead of plain text link.
|
||||
*
|
||||
* Most email clients like GMail, Outlook do not support videos in the email. To handle it, we are replacing the WordPress's oembed generated HTML for video links to their respective thubmnail images which are then linked the original video URL.
|
||||
*
|
||||
* @param string $html HTML for current URL.
|
||||
* @param string $url Current URL.
|
||||
* @param array $attr Shortcode attribute.
|
||||
* @param int $post_ID Current post id.
|
||||
*
|
||||
* @return string $html HTML for current URL.
|
||||
*
|
||||
* @since 4.4.9
|
||||
*/
|
||||
public static function handle_link_in_email_content( $html, $url, $attr, $post_ID ) {
|
||||
|
||||
$post_link = get_permalink( $post_ID );
|
||||
// Check if current URL is same as current post's permalink.
|
||||
if( ! empty( $post_link ) && $url === $post_link ) {
|
||||
// Convert URL HTML back to URL itself if it a current post URL.
|
||||
$html = $url;
|
||||
} else {
|
||||
if( ! class_exists( 'WP_oEmbed' ) ) {
|
||||
require_once( ABSPATH . 'wp-includes/class-wp-oembed.php' );
|
||||
}
|
||||
|
||||
$oembed = new WP_oEmbed();
|
||||
$provider = $oembed->discover( $url );
|
||||
|
||||
if( ! empty( $provider ) ) {
|
||||
$oembed_response = $oembed->fetch( $provider, $url, $attr );
|
||||
if( is_object( $oembed_response ) && ! empty( $oembed_response->type ) && 'video' === $oembed_response->type ) {
|
||||
$thumbnail_url = $oembed_response->thumbnail_url;
|
||||
if( ! empty( $thumbnail_url ) ) {
|
||||
$title = $oembed_response->title;
|
||||
$provider_name = $oembed_response->provider_name;
|
||||
$play_icon_url = '';
|
||||
|
||||
switch( $provider_name ) {
|
||||
case 'YouTube':
|
||||
$play_icon_url = ES_PLUGIN_URL . 'lite/public/images/youtube-play-button.png';
|
||||
break;
|
||||
|
||||
case 'Vimeo':
|
||||
$play_icon_url = ES_PLUGIN_URL . 'lite/public/images/vimeo-play-button.png';
|
||||
break;
|
||||
|
||||
default:
|
||||
$play_icon_url = ES_PLUGIN_URL . 'lite/public/images/default-play-button.png';
|
||||
break;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
$thumbnail_width = ! empty( $oembed_response->width ) ? $oembed_response->width . 'px' : 'auto';
|
||||
$thumbnail_height = ! empty( $oembed_response->height ) ? $oembed_response->height . 'px' : 'auto';
|
||||
?>
|
||||
<table style="margin-bottom: 1em;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="background-image: url('<?php echo esc_url( $thumbnail_url ); ?>');height:<?php echo esc_attr( $thumbnail_height ); ?>;width:<?php echo esc_attr( $thumbnail_width ); ?>;background-size: 100% 100%;background-repeat: no-repeat;text-align:center;">
|
||||
<a href="<?php echo esc_url( $url ); ?>" title="<?php echo esc_attr( $title ); ?>" target="_blank">
|
||||
<img src="<?php echo esc_url( $play_icon_url ); ?>" style="height: 75px; margin: auto;">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
$html = ob_get_clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Statuses key name map
|
||||
*
|
||||
@@ -150,13 +249,24 @@ class ES_Common {
|
||||
|
||||
$lists = ES()->lists_db->get_list_id_name_map();
|
||||
$lists = $default_option + $lists;
|
||||
|
||||
$dropdown = '';
|
||||
|
||||
if( is_string( $selected ) && strpos( $selected, ',' ) > 0 ) {
|
||||
$selected = explode( ',', $selected );
|
||||
}
|
||||
|
||||
foreach ( $lists as $key => $list ) {
|
||||
|
||||
$dropdown .= "<option value='{$key}'";
|
||||
|
||||
if ( $selected == $key ) {
|
||||
$dropdown .= "selected = selected";
|
||||
if( is_array( $selected ) ) {
|
||||
if( in_array( $key, $selected ) ) {
|
||||
$dropdown .= "selected = selected";
|
||||
}
|
||||
} else {
|
||||
if ( ! empty( $selected ) && $selected == $key ) {
|
||||
$dropdown .= "selected = selected";
|
||||
}
|
||||
}
|
||||
|
||||
$dropdown .= ">{$list}</option>";
|
||||
@@ -1441,7 +1551,6 @@ class ES_Common {
|
||||
'1' => __( 'Active', 'email-subscribers' ),
|
||||
);
|
||||
|
||||
|
||||
if ( $reverse ) {
|
||||
$statuses = array_flip( $statuses );
|
||||
}
|
||||
@@ -1489,6 +1598,16 @@ class ES_Common {
|
||||
* @since 4.4.8
|
||||
*/
|
||||
public static function can_show_coupon( $coupon = 'PREMIUM10' ) {
|
||||
|
||||
$can_show = true;
|
||||
|
||||
if ( $can_show ) {
|
||||
self::update_coupon_data( $coupon );
|
||||
}
|
||||
|
||||
return $can_show;
|
||||
|
||||
/*
|
||||
$coupons = get_option( 'ig_es_coupons', array() );
|
||||
|
||||
$can_show = true;
|
||||
@@ -1511,8 +1630,8 @@ class ES_Common {
|
||||
if ( $can_show ) {
|
||||
self::update_coupon_data( $coupon );
|
||||
}
|
||||
|
||||
return $can_show;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1533,5 +1652,4 @@ class ES_Common {
|
||||
update_option( 'ig_es_coupons', $coupons );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -202,6 +202,16 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
'4.4.2' => array(
|
||||
'ig_es_update_442_set_workflows_default_permission',
|
||||
'ig_es_update_442_db_version'
|
||||
),
|
||||
|
||||
'4.4.9' => array(
|
||||
'ig_es_update_449_create_tables',
|
||||
'ig_es_update_449_db_version'
|
||||
),
|
||||
|
||||
'4.4.10' => array(
|
||||
'ig_es_update_4410_load_templates',
|
||||
'ig_es_update_4410_db_version'
|
||||
)
|
||||
|
||||
);
|
||||
@@ -241,8 +251,6 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
self::install();
|
||||
}
|
||||
|
||||
// Do we need to load templates?
|
||||
self::load_templates();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -720,7 +728,6 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
$report .= "Thank You.";
|
||||
|
||||
|
||||
|
||||
$new_contact_email_subject = "One more contact joins our tribe!";
|
||||
$new_contact_email_content = "Hi,\r\n\r\nYour friendly Email Subscribers notification bot here!\r\n\r\n{{NAME}} ({{EMAIL}}) joined our tribe just now.\r\n\r\nWhich list/s? {{LIST}}\r\n\r\nIf you know this person, or if they are an influencer, you may want to reach out to them personally!\r\n\r\nLater...";
|
||||
|
||||
@@ -793,19 +800,13 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Tables
|
||||
* @param null $version
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @modify 4.4.9
|
||||
*/
|
||||
private static function create_tables() {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->hide_errors();
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( self::get_schema() );
|
||||
}
|
||||
|
||||
public static function get_ig_es_400_schema() {
|
||||
public static function create_tables( $version = null ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
@@ -815,6 +816,22 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
$collate = $wpdb->get_charset_collate();
|
||||
}
|
||||
|
||||
if ( is_null( $version ) ) {
|
||||
$schema_fn = 'get_schema';
|
||||
} else {
|
||||
$v = str_replace( '.', '', $version );
|
||||
$schema_fn = 'get_' . $v . '_schema';
|
||||
}
|
||||
|
||||
$wpdb->hide_errors();
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( self::$schema_fn( $collate ) );
|
||||
}
|
||||
|
||||
public static function get_ig_es_400_schema( $collate = '' ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$tables = "
|
||||
CREATE TABLE `{$wpdb->prefix}ig_campaigns` (
|
||||
`id` int(10) NOT NULL AUTO_INCREMENT,
|
||||
@@ -960,22 +977,15 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new tables
|
||||
* @param string $collate
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public static function get_ig_es_420_schema() {
|
||||
|
||||
public static function get_ig_es_420_schema( $collate = '' ) {
|
||||
global $wpdb;
|
||||
|
||||
$collate = '';
|
||||
|
||||
if ( $wpdb->has_cap( 'collation' ) ) {
|
||||
$collate = $wpdb->get_charset_collate();
|
||||
}
|
||||
|
||||
$tables = "CREATE TABLE `{$wpdb->prefix}ig_contact_meta` (
|
||||
`id` int(10) NOT NULL AUTO_INCREMENT,
|
||||
`contact_id` bigint(10) unsigned NOT NULL,
|
||||
@@ -993,20 +1003,16 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
/**
|
||||
* Add new table
|
||||
*
|
||||
* @param string $collate
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 4.2.1
|
||||
*/
|
||||
public static function get_ig_es_421_schema() {
|
||||
public static function get_ig_es_421_schema( $collate = '' ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$collate = '';
|
||||
|
||||
if ( $wpdb->has_cap( 'collation' ) ) {
|
||||
$collate = $wpdb->get_charset_collate();
|
||||
}
|
||||
|
||||
$tables = "CREATE TABLE `{$wpdb->prefix}ig_contactmeta` (
|
||||
`meta_id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`contact_id` bigint(20) unsigned NOT NULL,
|
||||
@@ -1065,20 +1071,16 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
/**
|
||||
* Create Links Table
|
||||
*
|
||||
* @param string $collate
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @sinc 4.2.4
|
||||
*/
|
||||
public static function get_ig_es_424_schema() {
|
||||
public static function get_ig_es_424_schema( $collate = '' ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$collate = '';
|
||||
|
||||
if ( $wpdb->has_cap( 'collation' ) ) {
|
||||
$collate = $wpdb->get_charset_collate();
|
||||
}
|
||||
|
||||
$tables = "CREATE TABLE `{$wpdb->prefix}ig_links` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`message_id` int(10) unsigned NOT NULL,
|
||||
@@ -1100,20 +1102,15 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
/**
|
||||
* Create Links Table
|
||||
*
|
||||
* @param string $collate
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @sinc 4.4.1
|
||||
*/
|
||||
public static function get_ig_es_441_schema() {
|
||||
|
||||
public static function get_ig_es_441_schema( $collate = '' ) {
|
||||
global $wpdb;
|
||||
|
||||
$collate = '';
|
||||
|
||||
if ( $wpdb->has_cap( 'collation' ) ) {
|
||||
$collate = $wpdb->get_charset_collate();
|
||||
}
|
||||
|
||||
$tables = "CREATE TABLE `{$wpdb->prefix}ig_workflows` (
|
||||
`id` int(10) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
@@ -1147,19 +1144,21 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect multiple version table schema
|
||||
* Collect multiple version schema
|
||||
*
|
||||
* @param string $collate
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
private static function get_schema() {
|
||||
private static function get_schema( $collate = '' ) {
|
||||
|
||||
$tables = self::get_ig_es_400_schema();
|
||||
$tables .= self::get_ig_es_420_schema();
|
||||
$tables .= self::get_ig_es_421_schema();
|
||||
$tables .= self::get_ig_es_424_schema();
|
||||
$tables .= self::get_ig_es_441_schema();
|
||||
$tables = self::get_ig_es_400_schema( $collate );
|
||||
$tables .= self::get_ig_es_420_schema( $collate );
|
||||
$tables .= self::get_ig_es_421_schema( $collate );
|
||||
$tables .= self::get_ig_es_424_schema( $collate );
|
||||
$tables .= self::get_ig_es_441_schema( $collate );
|
||||
|
||||
return $tables;
|
||||
}
|
||||
@@ -1591,6 +1590,8 @@ if ( ! class_exists( 'ES_Install' ) ) {
|
||||
|
||||
if ( $force || ( $plan !== $templates_loaded_for ) ) {
|
||||
|
||||
set_time_limit( 0 );
|
||||
|
||||
$templates = array();
|
||||
$templates = apply_filters( 'ig_es_email_templates', $templates );
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ class ES_Admin_Settings {
|
||||
public $subscribers_obj;
|
||||
|
||||
public function __construct() {
|
||||
add_filter( 'ig_es_registered_email_sending_settings', array( $this, 'show_cron_info' ) );
|
||||
}
|
||||
|
||||
public function es_settings_callback() {
|
||||
@@ -881,4 +882,148 @@ public function field_callback( $arguments, $id_key = '' ) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ES cron info
|
||||
*
|
||||
* @return array $email_sending_settings ES send email settings.
|
||||
*
|
||||
* @since 4.4.9
|
||||
*/
|
||||
public function show_cron_info( $email_sending_settings ) {
|
||||
$es_cron_enabled = ES()->cron->is_wp_cron_enable();
|
||||
if( $es_cron_enabled ) {
|
||||
$es_cron_info = array(
|
||||
'ig_es_cron_info' => array(
|
||||
'id' => 'ig_es_cron_info',
|
||||
'name' => __( 'Cron Info', 'email-subscribers' ),
|
||||
'type' => 'html',
|
||||
'html' => self::render_cron_info_html(),
|
||||
),
|
||||
);
|
||||
$email_sending_settings = ig_es_array_insert_after( $email_sending_settings, 'ig_es_cronurl', $es_cron_info );
|
||||
}
|
||||
|
||||
return $email_sending_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render ES cron info html
|
||||
*
|
||||
* @return false|string
|
||||
*
|
||||
* @since 4.4.9
|
||||
*/
|
||||
public static function render_cron_info_html() {
|
||||
$site_crons = get_option( 'cron' );
|
||||
|
||||
if( empty( $site_crons ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$es_cron_enabled = ES()->cron->is_wp_cron_enable();
|
||||
|
||||
$es_crons_data = array();
|
||||
$es_cron_events = array(
|
||||
'ig_es_cron',
|
||||
'ig_es_cron_worker',
|
||||
'ig_es_cron_auto_responder',
|
||||
);
|
||||
|
||||
$cron_schedules = wp_get_schedules();
|
||||
$time_offset = get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
|
||||
$date_format = get_option( 'date_format' );
|
||||
$time_format = get_option( 'time_format' );
|
||||
|
||||
foreach ( $site_crons as $next_scheduled_time => $scheduled_crons ) {
|
||||
if( ! empty( $scheduled_crons ) && is_array( $scheduled_crons ) ) {
|
||||
foreach( $scheduled_crons as $cron_event => $cron_data ) {
|
||||
if( ! in_array( $cron_event, $es_cron_events, true ) ) {
|
||||
continue;
|
||||
}
|
||||
foreach( $cron_data as $cron_info ) {
|
||||
if( ! empty( $cron_info['schedule'] ) ) {
|
||||
$cron_schedule = $cron_info['schedule'];
|
||||
$cron_interval = ! empty( $cron_schedules[ $cron_schedule ]['interval'] ) ? $cron_schedules[ $cron_schedule ]['interval'] : 0;
|
||||
$es_crons_data[$cron_event] = array(
|
||||
'cron_interval' => $cron_interval,
|
||||
'next_scheduled_time' => $next_scheduled_time,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$html = '';
|
||||
if( ! empty( $es_crons_data ) ) {
|
||||
ob_start();
|
||||
?>
|
||||
<table class="min-w-full rounded-lg">
|
||||
<thead>
|
||||
<tr class="bg-blue-50 text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
<th class="px-5 py-4"><?php echo esc_html__( 'Event', 'email-subscribers' ); ?></th>
|
||||
<th class="px-2 py-4 text-center"><?php echo esc_html__( 'Interval', 'email-subscribers' ); ?></th>
|
||||
<th class="px-2 py-4 text-center"><?php echo esc_html__( 'Next Execution', 'email-subscribers' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-blue-50">
|
||||
<?php
|
||||
foreach( $es_cron_events as $cron_event ) {
|
||||
$cron_interval = '';
|
||||
$next_scheduled_time = '';
|
||||
if( ! empty( $es_crons_data[ $cron_event ] ) ) {
|
||||
$es_cron_data = $es_crons_data[ $cron_event ];
|
||||
$cron_interval = $es_cron_data['cron_interval'];
|
||||
$next_scheduled_time = $es_cron_data['next_scheduled_time'];
|
||||
} else {
|
||||
if( 'ig_es_cron_auto_responder' === $cron_event ) {
|
||||
wp_schedule_event( floor( time() / 300 ) * 300 - 120, 'ig_es_cron_interval', 'ig_es_cron_auto_responder' );
|
||||
} else if( 'ig_es_cron_worker' === $cron_event ) {
|
||||
wp_schedule_event( floor( time() / 300 ) * 300, 'ig_es_cron_interval', 'ig_es_cron_worker' );
|
||||
} else if( 'ig_es_cron' === $cron_event ) {
|
||||
wp_schedule_event( strtotime( 'midnight' ) - 300, 'hourly', 'ig_es_cron' );
|
||||
}
|
||||
$next_scheduled_time = wp_next_scheduled( $cron_event );
|
||||
if( 'ig_es_cron' === $cron_event ) {
|
||||
$cron_interval = 3600; // Hourly interval for ig_es_cron.
|
||||
} else {
|
||||
$cron_interval = ES()->cron->get_cron_interval();
|
||||
}
|
||||
}
|
||||
if( empty( $cron_interval ) || empty( $next_scheduled_time ) ) {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<tr class="border-b border-gray-200">
|
||||
<td class="pl-8 py-4 ">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0">
|
||||
<span class="text-sm leading-5 font-medium text-center text-gray-800"><?php echo $cron_event; ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="whitespace-no-wrap text-center">
|
||||
<?php
|
||||
echo ig_es_get_human_interval( $cron_interval );
|
||||
?>
|
||||
</td>
|
||||
<td class="whitespace-no-wrap text-center">
|
||||
<b><?php echo esc_html( sprintf( __( "In %s", 'email-subscribers' ), human_time_diff( time(), $next_scheduled_time ) ) ); ?></b><br>
|
||||
<span title="<?php echo esc_attr( 'UTC: ' . date_i18n( $date_format . ' ' . $time_format, $next_scheduled_time ) ); ?>">
|
||||
<?php echo date_i18n( $date_format . ' ' . $time_format, $next_scheduled_time + $time_offset ); ?>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
$html = ob_get_clean();
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -90,60 +90,60 @@ class ES_Campaigns_Table extends WP_List_Table {
|
||||
public function render() {
|
||||
$action = ig_es_get_request_data( 'action' );
|
||||
global $ig_es_tracker;
|
||||
if( 'broadcast_created' === $action ) {
|
||||
if ( 'broadcast_created' === $action ) {
|
||||
|
||||
// Trigger feedback popup for broadcast creation.
|
||||
do_action( 'ig_es_broadcast_created' );
|
||||
|
||||
$message = __( 'Broadcast has been created successfully.', 'email-subscribers' );
|
||||
$message = __( 'Broadcast has been created successfully.', 'email-subscribers' );
|
||||
ES_Common::show_message( $message, 'success' );
|
||||
}
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1 class="wp-heading-inline"><span class="text-2xl font-medium leading-7 text-gray-900 sm:leading-9 sm:truncate"><?php _e( 'Campaigns', 'email-subscribers' ) ?>
|
||||
<div class="wrap">
|
||||
<h1 class="wp-heading-inline"><span class="text-2xl font-medium leading-7 text-gray-900 sm:leading-9 sm:truncate"><?php _e( 'Campaigns', 'email-subscribers' ) ?>
|
||||
<a href="admin.php?page=es_notifications&action=new" class="ig-es-title-button px-2 py-2 mx-1"><?php _e( 'Create Post Notification', 'email-subscribers' ) ?></a></span>
|
||||
<a href="admin.php?page=es_newsletters" class="ig-es-title-button px-2 py-2 mx-1"><?php _e( 'Send Broadcast', 'email-subscribers' ) ?></a>
|
||||
<?php do_action( 'ig_es_after_campaign_type_buttons' );
|
||||
<a href="admin.php?page=es_newsletters" class="ig-es-title-button px-2 py-2 mx-1"><?php _e( 'Send Broadcast', 'email-subscribers' ) ?></a>
|
||||
<?php do_action( 'ig_es_after_campaign_type_buttons' );
|
||||
|
||||
$icegram_plugin = 'icegram/icegram.php';
|
||||
$active_plugins = $ig_es_tracker::get_active_plugins();
|
||||
if ( in_array( $icegram_plugin, $active_plugins ) ) {
|
||||
$redirect_url = admin_url( 'post-new.php?post_type=ig_campaign' );
|
||||
?>
|
||||
<a href="<?php echo $redirect_url; ?>" class="ig-es-link-button px-2 py-2 mx-1"><?php _e( 'Onsite Campaigns', 'email-subscribers' ) ?></a>
|
||||
<?php } else { ?>
|
||||
<a href="admin.php?page=go_to_icegram&action=create_campaign" class="ig-es-link-button px-2 py-2 mx-1"><?php _e( 'Onsite Campaigns', 'email-subscribers' ) ?></a>
|
||||
<?php } ?>
|
||||
$icegram_plugin = 'icegram/icegram.php';
|
||||
$active_plugins = $ig_es_tracker::get_active_plugins();
|
||||
if ( in_array( $icegram_plugin, $active_plugins ) ) {
|
||||
$redirect_url = admin_url( 'post-new.php?post_type=ig_campaign' );
|
||||
?>
|
||||
<a href="<?php echo $redirect_url; ?>" class="ig-es-link-button px-2 py-2 mx-1"><?php _e( 'Onsite Campaigns', 'email-subscribers' ) ?></a>
|
||||
<?php } else { ?>
|
||||
<a href="admin.php?page=go_to_icegram&action=create_campaign" class="ig-es-link-button px-2 py-2 mx-1"><?php _e( 'Onsite Campaigns', 'email-subscribers' ) ?></a>
|
||||
<?php } ?>
|
||||
|
||||
<a href="edit.php?post_type=es_template" class="ig-es-imp-button px-2 py-2 mx-1"><?php _e( 'Manage Templates', 'email-subscribers' ) ?></a>
|
||||
<a href="edit.php?post_type=es_template" class="ig-es-imp-button px-2 py-2 mx-1"><?php _e( 'Manage Templates', 'email-subscribers' ) ?></a>
|
||||
|
||||
|
||||
</h1>
|
||||
<div id="poststuff" class="es-items-lists">
|
||||
<div id="post-body" class="metabox-holder column-1">
|
||||
<div id="post-body-content">
|
||||
<div class="meta-box-sortables ui-sortable">
|
||||
<form method="post">
|
||||
<?php
|
||||
$this->prepare_items();
|
||||
$this->display(); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br class="clear">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function custom_admin_notice() {
|
||||
$es_note_cat = ig_es_get_request_data( 'es_note_cat' );
|
||||
|
||||
if ( $es_note_cat ) {
|
||||
echo '<div class="updated"><p>' . esc_html( 'Notification Added Successfully!', 'email-subscribers' ) . '</p></div>';
|
||||
</h1>
|
||||
<div id="poststuff" class="es-items-lists">
|
||||
<div id="post-body" class="metabox-holder column-1">
|
||||
<div id="post-body-content">
|
||||
<div class="meta-box-sortables ui-sortable">
|
||||
<form method="post">
|
||||
<?php
|
||||
$this->prepare_items();
|
||||
$this->display(); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br class="clear">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function custom_admin_notice() {
|
||||
$es_note_cat = ig_es_get_request_data( 'es_note_cat' );
|
||||
|
||||
if ( $es_note_cat ) {
|
||||
echo '<div class="updated"><p>' . esc_html( 'Notification Added Successfully!', 'email-subscribers' ) . '</p></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve lists data from the database
|
||||
@@ -157,10 +157,10 @@ public function custom_admin_notice() {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$order_by = sanitize_sql_orderby( ig_es_get_request_data( 'orderby' ) );
|
||||
$order = ig_es_get_request_data( 'order' );
|
||||
$search = ig_es_get_request_data( 's' );
|
||||
$filter_by_campaign_type = ig_es_get_request_data( 'filter_by_campaign_type' );
|
||||
$order_by = sanitize_sql_orderby( ig_es_get_request_data( 'orderby' ) );
|
||||
$order = ig_es_get_request_data( 'order' );
|
||||
$search = ig_es_get_request_data( 's' );
|
||||
$filter_by_campaign_type = ig_es_get_request_data( 'filter_by_campaign_type' );
|
||||
$filter_by_campaign_status = ig_es_get_request_data( 'filter_by_campaign_status' );
|
||||
|
||||
if ( $do_count_only ) {
|
||||
@@ -194,20 +194,20 @@ public function custom_admin_notice() {
|
||||
}
|
||||
|
||||
if ( ! empty( $filter_by_campaign_status ) || ( '0' === $filter_by_campaign_status ) ) {
|
||||
if ( $add_where_clause ) {
|
||||
$sql .= $wpdb->prepare( " AND status = %s", $filter_by_campaign_status );
|
||||
} else {
|
||||
$sql .= $wpdb->prepare( " WHERE status = %s", $filter_by_campaign_status );
|
||||
}
|
||||
if ( $add_where_clause ) {
|
||||
$sql .= $wpdb->prepare( " AND status = %s", $filter_by_campaign_status );
|
||||
} else {
|
||||
$sql .= $wpdb->prepare( " WHERE status = %s", $filter_by_campaign_status );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( ! empty( $filter_by_campaign_type ) ) {
|
||||
if ( $add_where_clause ) {
|
||||
$sql .= $wpdb->prepare( " AND type = %s", $filter_by_campaign_type );
|
||||
} else {
|
||||
$sql .= $wpdb->prepare( " WHERE type = %s", $filter_by_campaign_type );
|
||||
}
|
||||
if ( ! empty( $filter_by_campaign_type ) ) {
|
||||
if ( $add_where_clause ) {
|
||||
$sql .= $wpdb->prepare( " AND type = %s", $filter_by_campaign_type );
|
||||
} else {
|
||||
$sql .= $wpdb->prepare( " WHERE type = %s", $filter_by_campaign_type );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ public function custom_admin_notice() {
|
||||
|
||||
$default_order_by = esc_sql( 'created_at' );
|
||||
|
||||
$expected_order_by_values = array( 'base_template_id', 'type' );
|
||||
$expected_order_by_values = array( 'name', 'type', 'created_at' );
|
||||
if ( ! in_array( $order_by, $expected_order_by_values ) ) {
|
||||
$order_by_clause = " ORDER BY {$default_order_by} DESC";
|
||||
} else {
|
||||
@@ -293,30 +293,34 @@ public function custom_admin_notice() {
|
||||
switch ( $column_name ) {
|
||||
|
||||
case 'list_ids':
|
||||
if ( ! empty( $item[ $column_name ] ) ) {
|
||||
return ES()->lists_db->get_list_id_name_map( $item[ $column_name ] );
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
break;
|
||||
if ( ! empty( $item[ $column_name ] ) ) {
|
||||
$list_ids = explode( ',', $item[ $column_name ] );
|
||||
return ES_Common::prepare_list_name_by_ids( $list_ids );
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
break;
|
||||
case 'type':
|
||||
$type = ( $item[ $column_name ] === 'newsletter' ) ? __( 'Broadcast', 'email-subscribers' ) : $item[ $column_name ];
|
||||
$type = ucwords( str_replace( '_', ' ', $type ) );
|
||||
$type = ( $item[ $column_name ] === 'newsletter' ) ? __( 'Broadcast', 'email-subscribers' ) : $item[ $column_name ];
|
||||
$type = ucwords( str_replace( '_', ' ', $type ) );
|
||||
|
||||
return $type;
|
||||
break;
|
||||
return $type;
|
||||
break;
|
||||
case 'created_at':
|
||||
return ig_es_format_date_time( $item[ $column_name ] );
|
||||
break;
|
||||
case 'categories':
|
||||
if ( ! empty( $item[ $column_name ] ) ) {
|
||||
$categories = ES_Common::convert_categories_string_to_array( $item[ $column_name ], false );
|
||||
$categories = strpos( $item[ $column_name ], '{a}All{a}' ) ? __( 'All', 'email-subscribers' ) : trim( trim( implode( ', ', $categories ) ), ',' );
|
||||
if ( ! empty( $item[ $column_name ] ) ) {
|
||||
$categories = ES_Common::convert_categories_string_to_array( $item[ $column_name ], false );
|
||||
$categories = strpos( $item[ $column_name ], '{a}All{a}' ) ? __( 'All', 'email-subscribers' ) : trim( trim( implode( ', ', $categories ) ), ',' );
|
||||
|
||||
return $categories;
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
break;
|
||||
return $categories;
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return $item[ $column_name ];
|
||||
return $item[ $column_name ];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,11 +344,10 @@ public function custom_admin_notice() {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function column_base_template_id( $item ) {
|
||||
function column_name( $item ) {
|
||||
|
||||
$type = $item['type'];
|
||||
|
||||
|
||||
$nonce = wp_create_nonce( 'es_post_notification' );
|
||||
|
||||
$template = get_post( $item['base_template_id'] );
|
||||
@@ -352,17 +355,22 @@ public function custom_admin_notice() {
|
||||
$report = ES_DB_Mailing_Queue::get_notification_by_campaign_id( $item['id'] );
|
||||
|
||||
if ( $type !== 'newsletter' ) {
|
||||
/*
|
||||
if ( $template instanceof WP_Post ) {
|
||||
$title = '<strong>' . $template->post_title . '</strong>';
|
||||
} else {
|
||||
$title = ! empty( $item['name'] ) ? $item['name'] : '';
|
||||
}
|
||||
$slug = ( in_array( $item['type'], array( 'post_notification', 'post_digest' ) ) ) ? esc_attr( 'es_notifications' ) : 'es_' . $item['type'];
|
||||
$actions ['edit'] = sprintf( __( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s" class="text-indigo-600">Edit</a>', 'email-subscribers' ), $slug, 'edit', absint( $item['id'] ), $nonce );
|
||||
*/
|
||||
|
||||
if( in_array( $type, array( 'post_notification', 'post_digest' ) ) ) {
|
||||
$title = ! empty( $item['name'] ) ? $item['name'] : '';
|
||||
|
||||
$slug = ( in_array( $item['type'], array( 'post_notification', 'post_digest' ) ) ) ? esc_attr( 'es_notifications' ) : 'es_' . $item['type'];
|
||||
$actions ['edit'] = sprintf( __( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s" class="text-indigo-600">Edit</a>', 'email-subscribers' ), $slug, 'edit', absint( $item['id'] ), $nonce );
|
||||
|
||||
if ( in_array( $type, array( 'post_notification', 'post_digest' ) ) ) {
|
||||
// Add reports link if there are any reports related to the post notification.
|
||||
if( ! empty( $report ) ) {
|
||||
if ( ! empty( $report ) ) {
|
||||
$actions['report'] = sprintf( '<a href="?page=%s&campaign_id=%d" class="text-indigo-600">%s</a>', esc_attr( 'es_reports' ), $item['id'], __( 'Report', 'email-subscribers' ) );
|
||||
}
|
||||
}
|
||||
@@ -377,8 +385,8 @@ public function custom_admin_notice() {
|
||||
IG_ES_CAMPAIGN_STATUS_SCHEDULED
|
||||
);
|
||||
|
||||
if( in_array( $status, $broadcast_allowed_edit_statuses ) ) {
|
||||
$actions ['edit'] = sprintf( __( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s" class="text-indigo-600">Edit</a>', 'email-subscribers' ), $slug, 'edit', absint( $item['id'] ), $nonce );
|
||||
if ( in_array( $status, $broadcast_allowed_edit_statuses ) ) {
|
||||
$actions ['edit'] = sprintf( __( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s" class="text-indigo-600">Edit</a>', 'email-subscribers' ), $slug, 'edit', absint( $item['id'] ), $nonce );
|
||||
}
|
||||
|
||||
$broadcast_allowed_report_statuses = array(
|
||||
@@ -388,8 +396,8 @@ public function custom_admin_notice() {
|
||||
IG_ES_CAMPAIGN_STATUS_FINISHED
|
||||
);
|
||||
|
||||
if( in_array( $status, $broadcast_allowed_report_statuses ) && ! empty( $report ) ) {
|
||||
$es_nonce = wp_create_nonce( 'es_notification' );
|
||||
if ( in_array( $status, $broadcast_allowed_report_statuses ) && ! empty( $report ) ) {
|
||||
$es_nonce = wp_create_nonce( 'es_notification' );
|
||||
$actions['report'] = sprintf( '<a href="?page=%s&action=%s&list=%s&_wpnonce=%s" class="text-indigo-600">%s</a>', esc_attr( 'es_reports' ), 'view', $report['hash'], $es_nonce, __( 'Report', 'email-subscribers' ) );
|
||||
}
|
||||
}
|
||||
@@ -409,103 +417,106 @@ public function custom_admin_notice() {
|
||||
* @since 4.4.4
|
||||
*/
|
||||
function column_status( $item ) {
|
||||
$campaign_id = ! empty( $item['id'] ) ? $item['id'] : 0;
|
||||
$campaign_status = ! empty( $item['status'] ) ? (int) $item['status'] : 0;
|
||||
$campaign_id = ! empty( $item['id'] ) ? $item['id'] : 0;
|
||||
$campaign_status = ! empty( $item['status'] ) ? (int) $item['status'] : 0;
|
||||
$campaign_statuses = array(
|
||||
IG_ES_CAMPAIGN_STATUS_ACTIVE,
|
||||
IG_ES_CAMPAIGN_STATUS_IN_ACTIVE
|
||||
);
|
||||
|
||||
$campaign_type = '';
|
||||
if( ! empty( $campaign_id ) ) {
|
||||
if ( ! empty( $campaign_id ) ) {
|
||||
$campaign_type = ES()->campaigns_db->get_campaign_type_by_id( $campaign_id );
|
||||
}
|
||||
|
||||
if( 'newsletter' !== $campaign_type && in_array( $campaign_status, $campaign_statuses, true ) ) {
|
||||
if ( 'newsletter' !== $campaign_type && in_array( $campaign_status, $campaign_statuses, true ) ) {
|
||||
?>
|
||||
<label for="<?php echo esc_attr( 'ig-es-campaign-status-toggle-' . $campaign_id ); ?>" class="ig-es-campaign-status-toggle-label inline-flex items-center cursor-pointer">
|
||||
<label for="<?php echo esc_attr( 'ig-es-campaign-status-toggle-' . $campaign_id ); ?>" class="ig-es-campaign-status-toggle-label inline-flex items-center cursor-pointer">
|
||||
<span class="relative">
|
||||
<input id="<?php echo esc_attr( 'ig-es-campaign-status-toggle-' . $campaign_id ); ?>" type="checkbox" class="absolute es-check-toggle opacity-0 w-0 h-0" name="<?php echo esc_attr( 'ig-es-campaign-status-toggle-' . $campaign_id ); ?>" value="<?php echo esc_attr( $campaign_id ); ?>" <?php checked( IG_ES_CAMPAIGN_STATUS_ACTIVE, $campaign_status ); ?>>
|
||||
<input id="<?php echo esc_attr( 'ig-es-campaign-status-toggle-' . $campaign_id ); ?>" type="checkbox" class="absolute es-check-toggle opacity-0 w-0 h-0" name="<?php echo esc_attr( 'ig-es-campaign-status-toggle-' . $campaign_id ); ?>" value="<?php echo esc_attr( $campaign_id ); ?>" <?php checked( IG_ES_CAMPAIGN_STATUS_ACTIVE,
|
||||
$campaign_status ); ?>>
|
||||
<span class="es-mail-toggle-line inline-block w-10 h-6 bg-gray-300 rounded-full shadow-inner"></span>
|
||||
<span class="es-mail-toggle-dot absolute transition-all duration-300 ease-in-out block w-4 h-4 mt-1 ml-1 bg-white rounded-full shadow inset-y-0 left-0 focus-within:shadow-outline"></span>
|
||||
</span>
|
||||
</label>
|
||||
</label>
|
||||
<?php
|
||||
} else {
|
||||
switch ( $campaign_status ) {
|
||||
|
||||
case IG_ES_CAMPAIGN_STATUS_ACTIVE:
|
||||
$notification = ES_DB_Mailing_Queue::get_notification_by_campaign_id( $campaign_id );
|
||||
if( ! empty( $notification ) ) {
|
||||
$notification_status = $notification['status'];
|
||||
if( 'In Queue' === $notification_status ) {
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-orange-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Scheduled', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
} else if( 'Sending' === $notification_status ) {
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Sending', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-8.707l-3-3a1 1 0 00-1.414 1.414L10.586 9H7a1 1 0 100 2h3.586l-1.293 1.293a1 1 0 101.414 1.414l3-3a1 1 0 000-1.414z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-green-400" fill="currentColor" viewBox="0 0 20 20" >
|
||||
<title><?php echo esc_attr__( 'Sent', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
$notification = ES_DB_Mailing_Queue::get_notification_by_campaign_id( $campaign_id );
|
||||
if ( ! empty( $notification ) ) {
|
||||
$notification_status = $notification['status'];
|
||||
if ( 'In Queue' === $notification_status ) {
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-orange-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Scheduled', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
} elseif ( 'Sending' === $notification_status ) {
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Sending', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-8.707l-3-3a1 1 0 00-1.414 1.414L10.586 9H7a1 1 0 100 2h3.586l-1.293 1.293a1 1 0 101.414 1.414l3-3a1 1 0 000-1.414z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-green-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Sent', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case IG_ES_CAMPAIGN_STATUS_IN_ACTIVE:
|
||||
?>
|
||||
<svg fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" stroke="currentColor" viewBox="0 0 24 24" class="ml-2 h-6 w-6 text-indigo-600">
|
||||
<title><?php echo esc_attr__( 'Draft', 'email-subscribers' ); ?></title>
|
||||
<path d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
|
||||
</svg>
|
||||
<?php
|
||||
break;
|
||||
?>
|
||||
<svg fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" stroke="currentColor" viewBox="0 0 24 24" class="ml-2 h-6 w-6 text-indigo-600">
|
||||
<title><?php echo esc_attr__( 'Draft', 'email-subscribers' ); ?></title>
|
||||
<path d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
|
||||
</svg>
|
||||
<?php
|
||||
break;
|
||||
|
||||
case IG_ES_CAMPAIGN_STATUS_SCHEDULED:
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-orange-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Scheduled', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
break;
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-orange-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Scheduled', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
break;
|
||||
|
||||
case IG_ES_CAMPAIGN_STATUS_QUEUED:
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Sending', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-8.707l-3-3a1 1 0 00-1.414 1.414L10.586 9H7a1 1 0 100 2h3.586l-1.293 1.293a1 1 0 101.414 1.414l3-3a1 1 0 000-1.414z" clip-rule="evenodd"/></svg>
|
||||
</svg>
|
||||
<?php
|
||||
break;
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Sending', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-8.707l-3-3a1 1 0 00-1.414 1.414L10.586 9H7a1 1 0 100 2h3.586l-1.293 1.293a1 1 0 101.414 1.414l3-3a1 1 0 000-1.414z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</svg>
|
||||
<?php
|
||||
break;
|
||||
|
||||
case IG_ES_CAMPAIGN_STATUS_PAUSED:
|
||||
?>
|
||||
<svg fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" stroke="currentColor" viewBox="0 0 24 24" class="ml-2 h-6 w-6 text-blue-400">
|
||||
<title><?php echo esc_attr__( 'Paused', 'email-subscribers' ); ?></title>
|
||||
<path d="M10 9v6m4-6v6m7-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||
?>
|
||||
<svg fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" stroke="currentColor" viewBox="0 0 24 24" class="ml-2 h-6 w-6 text-blue-400">
|
||||
<title><?php echo esc_attr__( 'Paused', 'email-subscribers' ); ?></title>
|
||||
<path d="M10 9v6m4-6v6m7-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
<?php
|
||||
break;
|
||||
|
||||
default:
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-green-400" fill="currentColor" viewBox="0 0 20 20" >
|
||||
<title><?php echo esc_attr__( 'Sent', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
break;
|
||||
?>
|
||||
<svg class="flex-shrink-0 ml-2 h-6 w-6 text-green-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<title><?php echo esc_attr__( 'Sent', 'email-subscribers' ); ?></title>
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -519,12 +530,13 @@ public function custom_admin_notice() {
|
||||
*/
|
||||
function get_columns() {
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />',
|
||||
'base_template_id' => __( 'Name', 'email-subscribers' ),
|
||||
'type' => __( 'Type', 'email-subscribers' ),
|
||||
'list_ids' => __( 'List', 'email-subscribers' ),
|
||||
'categories' => __( 'Categories', 'email-subscribers' ),
|
||||
'status' => __( 'Status', 'email-subscribers' )
|
||||
'cb' => '<input type="checkbox" />',
|
||||
'name' => __( 'Name', 'email-subscribers' ),
|
||||
'type' => __( 'Type', 'email-subscribers' ),
|
||||
'list_ids' => __( 'List(s)', 'email-subscribers' ),
|
||||
'categories' => __( 'Categories', 'email-subscribers' ),
|
||||
'created_at' => __( 'Created On', 'email-subscribers' ),
|
||||
'status' => __( 'Status', 'email-subscribers' )
|
||||
);
|
||||
|
||||
return $columns;
|
||||
@@ -541,7 +553,9 @@ public function custom_admin_notice() {
|
||||
//'base_template_id' => array( 'base_template_id', true ),
|
||||
//'list_ids' => array( 'list_ids', true ),
|
||||
//'status' => array( 'status', true )
|
||||
'type' => array( 'type', true )
|
||||
'name' => array( 'name', true ),
|
||||
'type' => array( 'type', true ),
|
||||
'created_at' => array( 'created_at', true )
|
||||
);
|
||||
|
||||
return $sortable_columns;
|
||||
@@ -570,23 +584,23 @@ public function custom_admin_notice() {
|
||||
* @since 4.3.4 Added esc_attr()
|
||||
*/
|
||||
public function search_box( $text = '', $input_id = '' ) { ?>
|
||||
<p class="search-box">
|
||||
<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo esc_attr( $text ); ?>:</label>
|
||||
<input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>"/>
|
||||
<p class="search-box">
|
||||
<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo esc_attr( $text ); ?>:</label>
|
||||
<input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>"/>
|
||||
<?php submit_button( __( 'Search Campaigns', 'email-subscribers' ), 'button', false, false, array( 'id' => 'search-submit' ) ); ?>
|
||||
</p>
|
||||
<p class="search-box search-group-box box-ma10">
|
||||
</p>
|
||||
<p class="search-box search-group-box box-ma10">
|
||||
<?php $filter_by_status = ig_es_get_request_data( 'filter_by_campaign_status' ); ?>
|
||||
<select name="filter_by_campaign_status" id="ig_es_filter_campaign_status_by_type">
|
||||
<select name="filter_by_campaign_status" id="ig_es_filter_campaign_status_by_type">
|
||||
<?php echo ES_Common::prepare_campaign_statuses_dropdown_options( $filter_by_status, __( 'All Statuses', 'email-subscribers' ) ); ?>
|
||||
</select>
|
||||
</p>
|
||||
<p class="search-box search-group-box box-ma10">
|
||||
</select>
|
||||
</p>
|
||||
<p class="search-box search-group-box box-ma10">
|
||||
<?php $filter_by_campaign_type = ig_es_get_request_data( 'filter_by_campaign_type' ); ?>
|
||||
<select name="filter_by_campaign_type" id="ig_es_filter_campaign_type">
|
||||
<select name="filter_by_campaign_type" id="ig_es_filter_campaign_type">
|
||||
<?php echo ES_Common::prepare_campaign_type_dropdown_options( $filter_by_campaign_type, __( 'All Type', 'email-subscribers' ) ); ?>
|
||||
</select>
|
||||
</p>
|
||||
</select>
|
||||
</p>
|
||||
<?php }
|
||||
|
||||
/**
|
||||
|
||||
@@ -491,7 +491,7 @@ class ES_Contacts_Table extends WP_List_Table {
|
||||
?>
|
||||
|
||||
<div class="wrap max-w-full mt-1 font-sans">
|
||||
<header class="ml-12 mr-8 wp-heading-inline">
|
||||
<header class="wp-heading-inline">
|
||||
<div class="md:flex md:items-center md:justify-between justify-center">
|
||||
<div class="flex-1 min-w-0">
|
||||
<h2 class="text-2xl leading-7 text-gray-900 sm:leading-9 sm:truncate">
|
||||
@@ -517,8 +517,8 @@ class ES_Contacts_Table extends WP_List_Table {
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="ml-12 mr-8"><hr class="wp-header-end"></div>
|
||||
<div class="meta-box-sortables ui-sortable bg-white shadow-md ml-12 mr-8 mt-6 rounded-lg">
|
||||
<div class=""><hr class="wp-header-end"></div>
|
||||
<div class="bg-white shadow-md rounded-lg">
|
||||
<?php echo $this->prepare_contact_form( $data, $is_new ); ?>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -315,7 +315,6 @@ public function export_subscribers_page() {
|
||||
|
||||
$lists_id_name_map = ES()->lists_db->get_list_id_name_map();
|
||||
$csv_output .= implode( ',', $headers );
|
||||
$csv_output .= "\n";
|
||||
|
||||
foreach ( $subscribers as $key => $subscriber ) {
|
||||
|
||||
@@ -330,8 +329,8 @@ public function export_subscribers_page() {
|
||||
$data['status'] = ucfirst( $list_details['status'] );
|
||||
$data['optin_type'] = ( $list_details['optin_type'] == 1 ) ? 'Single Opt-In' : 'Double Opt-In';
|
||||
$data['created_at'] = $subscriber['created_at'];
|
||||
$csv_output .= '"' . implode( '","', $data ) . '"';
|
||||
$csv_output .= "\n";
|
||||
$csv_output .= '"' . implode( '","', $data ) . '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,16 @@ class ES_Forms_Table extends WP_List_Table {
|
||||
</a>
|
||||
</span>
|
||||
</h1>
|
||||
<?php
|
||||
if( 'form_created' === $action ){
|
||||
$message = __( 'Form has been added successfully!', 'email-subscribers' );
|
||||
ES_Common::show_message( $message, 'success' );
|
||||
}
|
||||
elseif( 'form_updated' === $action ){
|
||||
$message = __( 'Form has been updated successfully!', 'email-subscribers' );
|
||||
ES_Common::show_message( $message, 'success' );
|
||||
}
|
||||
?>
|
||||
<div id="poststuff" class="es-items-lists">
|
||||
<div id="post-body" class="metabox-holder column-1">
|
||||
<div id="post-body-content">
|
||||
@@ -171,8 +181,9 @@ class ES_Forms_Table extends WP_List_Table {
|
||||
}
|
||||
|
||||
$this->save_form( null, $form_data );
|
||||
$message = __( 'Form has been added successfully!', 'email-subscribers' );
|
||||
ES_Common::show_message( $message, 'success' );
|
||||
$form_url = admin_url( 'admin.php?page=es_forms&action=form_created' );
|
||||
wp_safe_redirect( $form_url );
|
||||
exit();
|
||||
}
|
||||
|
||||
$this->prepare_list_form();
|
||||
@@ -219,8 +230,10 @@ class ES_Forms_Table extends WP_List_Table {
|
||||
}
|
||||
|
||||
$this->save_form( $id, $form_data );
|
||||
$message = __( 'Form has been updated successfully!', 'email-subscribers' );
|
||||
ES_Common::show_message( $message, 'success' );
|
||||
$form_url = admin_url( 'admin.php?page=es_forms&action=form_updated' );
|
||||
wp_safe_redirect( $form_url );
|
||||
exit();
|
||||
|
||||
} else {
|
||||
|
||||
$data = $data[0];
|
||||
@@ -267,7 +280,7 @@ class ES_Forms_Table extends WP_List_Table {
|
||||
?>
|
||||
|
||||
<div class="wrap max-w-full mt-1 font-sans">
|
||||
<header class="ml-12 mr-8 wp-heading-inline">
|
||||
<header class="wp-heading-inline">
|
||||
<div class="md:flex md:items-center md:justify-between justify-center">
|
||||
<div class="flex-1 min-w-0">
|
||||
<h1 class="text-2xl leading-7 text-gray-900 sm:leading-9 sm:truncate">
|
||||
@@ -285,11 +298,11 @@ class ES_Forms_Table extends WP_List_Table {
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="ml-12 mr-8"><hr class="wp-header-end"></div>
|
||||
<div class=""><hr class="wp-header-end"></div>
|
||||
<div id="poststuff">
|
||||
<div id="post-body" class="metabox-holder column-1">
|
||||
<div id="post-body-content">
|
||||
<div class="meta-box-sortables ui-sortable bg-white shadow-md ml-12 mr-8 mt-4 rounded-lg">
|
||||
<div class="bg-white shadow-md rounded-lg">
|
||||
<form class="pt-8 ml-5 mr-4 text-left flex-row mt-2 item-center " method="post" action="admin.php?page=es_forms&action=<?php echo $action; ?>&form=<?php echo $id; ?>&_wpnonce=<?php echo $nonce; ?>">
|
||||
|
||||
|
||||
@@ -316,7 +329,7 @@ class ES_Forms_Table extends WP_List_Table {
|
||||
<div class="flex ">
|
||||
<div class="ml-16 mb-4 h-10 mr-4 mt-4">
|
||||
<div class="h-10 relative ">
|
||||
<input id="ig_es_title" class="form-input block border-gray-400 w-full pl-3 pr-12 shadow-sm focus:bg-gray-100 sm:text-sm sm:leading-5" placeholder="Enter description" name="form_data[desc]" id="ig_es_title" value="<?php echo stripslashes( $form_data['desc'] ); ?>" size="30" maxlength="100"/>
|
||||
<input id="ig_es_title" class="form-input block border-gray-400 w-full pl-3 pr-12 shadow-sm focus:bg-gray-100 sm:text-sm sm:leading-5" placeholder="Enter description" name="form_data[desc]" id="ig_es_title" value="<?php echo stripslashes( $form_data['desc'] ); ?>" size="30" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -439,7 +452,6 @@ class ES_Forms_Table extends WP_List_Table {
|
||||
|
||||
<?php do_action('ig_es_add_additional_options', $form_data);?>
|
||||
|
||||
|
||||
|
||||
<div class="flex flex-row border-b border-gray-100">
|
||||
<div class="flex w-1/5">
|
||||
@@ -764,7 +776,7 @@ class ES_Forms_Table extends WP_List_Table {
|
||||
case 'shortcode':
|
||||
$shortcode = '[email-subscribers-form id="' . $item['id'] . '"]';
|
||||
|
||||
return '<code>' . $shortcode . '</code>';
|
||||
return '<code id="es-shortcode">' . $shortcode . '</code>';
|
||||
break;
|
||||
default:
|
||||
return '';
|
||||
|
||||
@@ -82,6 +82,7 @@ class ES_Handle_Post_Notification {
|
||||
$template = get_post( $template_id ); // to confirm if template exists in ES->Templates
|
||||
if ( is_object( $template ) ) {
|
||||
$list_id = $notification['list_ids'];
|
||||
$list_id = explode( ',', $list_id );
|
||||
$subscribers = ES()->contacts_db->get_active_contacts_by_list_id( $list_id );
|
||||
|
||||
//schedule
|
||||
@@ -226,6 +227,30 @@ class ES_Handle_Post_Notification {
|
||||
$post_author = get_the_author_meta( 'display_name', $post_author_id );
|
||||
$es_templ_body = str_replace( '{{POSTAUTHOR}}', $post_author, $es_templ_body );
|
||||
$es_templ_body = str_replace( '{{POSTLINK-ONLY}}', $post_link, $es_templ_body );
|
||||
|
||||
// Check if template has {{POSTCATS}} placeholder.
|
||||
if( strpos( $es_templ_body, '{{POSTCATS}}' ) >= 0 ) {
|
||||
$taxonomies = get_object_taxonomies( $post );
|
||||
$post_cats = array();
|
||||
|
||||
if( ! empty( $taxonomies ) ) {
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
$taxonomy_object = get_taxonomy( $taxonomy );
|
||||
// Check if taxonomy is hierarchical e.g. have parent-child relationship like categories
|
||||
if( $taxonomy_object->hierarchical ) {
|
||||
$post_terms = get_the_terms( $post, $taxonomy );
|
||||
if( ! empty( $post_terms ) ) {
|
||||
foreach ( $post_terms as $term ) {
|
||||
$term_name = $term->name;
|
||||
$post_cats[] = $term_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$es_templ_body = str_replace( '{{POSTCATS}}', implode( ', ', $post_cats ), $es_templ_body );
|
||||
}
|
||||
|
||||
if ( $post_link != "" ) {
|
||||
$post_link_with_title = "<a href='" . $post_link . "' target='_blank'>" . $post_title . "</a>";
|
||||
|
||||
@@ -246,7 +246,7 @@ class ES_Lists_Table extends WP_List_Table {
|
||||
?>
|
||||
|
||||
<div class="wrap max-w-full mt-8 font-sans">
|
||||
<header class="ml-12 mr-8 wp-heading-inline">
|
||||
<header class="wp-heading-inline">
|
||||
<div class="md:flex md:items-center md:justify-between justify-center">
|
||||
<div class="flex-1 min-w-0">
|
||||
<h2 class="text-2xl font-medium leading-7 text-gray-900 sm:leading-9 sm:truncate">
|
||||
@@ -266,12 +266,12 @@ class ES_Lists_Table extends WP_List_Table {
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="ml-12 mr-8"><hr class="wp-header-end"></div>
|
||||
<div class=""><hr class="wp-header-end"></div>
|
||||
<div class="rounded max-w-full ">
|
||||
<div id="poststuff">
|
||||
<div id="post-body" class="metabox-holder column-1">
|
||||
<div id="post-body-content">
|
||||
<div class="meta-box-sortables ui-sortable bg-white shadow-md ml-12 mr-8 mt-4 rounded-lg">
|
||||
<div class="bg-white shadow-md rounded-lg">
|
||||
<form class="ml-5 mr-4 text-left pt-8 flex-row mt-2 item-center " method="post" action="admin.php?page=es_lists&action=<?php echo $action; ?>&list=<?php echo $id; ?>&_wpnonce=<?php echo $nonce; ?>">
|
||||
|
||||
<div class="flex flex-row ">
|
||||
|
||||
@@ -796,9 +796,7 @@ if ( ! class_exists( 'ES_Mailer' ) ) {
|
||||
// Convert text equivalent of smilies to images.
|
||||
$content = convert_smilies( wptexturize( $content ) );
|
||||
|
||||
if ( isset( $GLOBALS['wp_embed'] ) ) {
|
||||
$content = $GLOBALS['wp_embed']->autoembed( $content );
|
||||
}
|
||||
$content = ES_Common::handle_oembed_content( $content );
|
||||
|
||||
// Replaces double line-breaks with paragraph elements.
|
||||
//$content = wpautop( $content );
|
||||
|
||||
@@ -29,6 +29,7 @@ class ES_Newsletters {
|
||||
// Ajax handler for broadcast preview
|
||||
add_action( 'wp_ajax_ig_es_preview_broadcast', array( $this, 'preview_broadcast' ) );
|
||||
|
||||
// Ajax handler for starting processing of broadcast in background when 'Send Now' option is chosen while creating broadcast
|
||||
add_action( 'wp_ajax_ig_es_trigger_broadcast_processing', array( $this, 'trigger_broadcast_processing' ) );
|
||||
|
||||
add_action( 'admin_init', array( $this, 'process_broadcast_submission' ) );
|
||||
@@ -211,6 +212,9 @@ class ES_Newsletters {
|
||||
}
|
||||
}
|
||||
|
||||
$select_list_attr = ES()->is_pro() ? 'multiple="multiple"' : '';
|
||||
$select_list_name = ES()->is_pro() ? 'broadcast_data[list_ids][]' : 'broadcast_data[list_ids]';
|
||||
$select_list_class = ES()->is_pro() ? 'ig-es-form-multiselect' : 'form-select';
|
||||
?>
|
||||
|
||||
<div class="font-sans wrap">
|
||||
@@ -225,8 +229,8 @@ class ES_Newsletters {
|
||||
<input type="hidden" id="broadcast_id" name="broadcast_data[id]" value="<?php echo esc_attr( $broadcast_id ); ?>"/>
|
||||
<input type="hidden" id="broadcast_status" name="broadcast_data[status]" value="<?php echo esc_attr( $broadcast_status ); ?>"/>
|
||||
<fieldset class="block es_fieldset">
|
||||
<div class="mx-auto wp-heading-inline max-w-7xl sm:px-6 lg:px-3">
|
||||
<header class="mx-auto max-w-7xl sm:px-6 lg:px-4">
|
||||
<div class="mx-auto wp-heading-inline max-w-7xl">
|
||||
<header class="mx-auto max-w-7xl">
|
||||
<div class="pb-2 md:flex md:items-center md:justify-between">
|
||||
<div class="flex md:3/5 lg:w-7/12 xl:w-3/5">
|
||||
<div class="flex min-w-0 md:w-3/5 lg:w-1/2">
|
||||
@@ -310,13 +314,13 @@ class ES_Newsletters {
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<div class="mx-auto max-w-7xl sm:px-8 lg:px-7">
|
||||
<div class="mx-auto max-w-7xl">
|
||||
<hr class="wp-header-end">
|
||||
</div>
|
||||
<div class="px-4 mx-auto my-4 es_broadcast_first max-w-7xl sm:px-6 lg:px-3">
|
||||
<div class="sm:px-6 lg:px-4">
|
||||
<div class="py-4 bg-white rounded-lg shadow-md md:flex">
|
||||
<div class="broadcast_main_content pl-2">
|
||||
<div class="mx-auto my-4 es_broadcast_first max-w-7xl">
|
||||
<div>
|
||||
<div class=" bg-white rounded-lg shadow-md md:flex">
|
||||
<div class="broadcast_main_content py-4 pl-2">
|
||||
<div class="block px-4 py-2">
|
||||
<label for="ig_es_broadcast_subject" class="text-sm font-medium leading-5 text-gray-700"><?php echo esc_html__( 'Subject', 'email-subscribers' ); ?></label>
|
||||
<input id="ig_es_broadcast_subject" class="block w-full mt-1 text-sm leading-5 border-gray-400 rounded-md shadow-sm form-input" name="broadcast_data[subject]" value="<?php echo esc_attr( $broadcast_subject ); ?>"/>
|
||||
@@ -347,8 +351,8 @@ class ES_Newsletters {
|
||||
</div>
|
||||
<?php do_action( 'ig_es_after_broadcast_left_pan_settings', $broadcast_data ); ?>
|
||||
</div>
|
||||
<div class="broadcast_side_content ml-2 mr-4 bg-gray-100 rounded-md">
|
||||
<div class="block mt-0.5 mx-4 py-2">
|
||||
<div class="broadcast_side_content ml-2 bg-gray-100 rounded-r-lg">
|
||||
<div class="block pt-6 mx-4 pb-3">
|
||||
<label for="template" class="text-sm font-medium leading-5 text-gray-700"><?php echo esc_html__( 'Design Template', 'email-subscribers' ); ?></label>
|
||||
<select class="block w-full h-8 mt-1 text-sm rounded-md cursor-pointer h-9 form-select" name="broadcast_data[template_id]" id="base_template_id">
|
||||
<?php echo $templates ?>
|
||||
@@ -356,16 +360,15 @@ class ES_Newsletters {
|
||||
</div>
|
||||
<div class="block py-2 mx-4 ">
|
||||
<label for="recipients" class="text-sm font-medium leading-5 text-gray-700"><?php echo esc_html__( 'Recipients', 'email-subscribers' ); ?></label>
|
||||
<select class="block w-full h-8 mt-1 text-sm rounded-md cursor-pointer h-9 form-select" name="broadcast_data[list_ids]" id="ig_es_broadcast_list_ids">
|
||||
<select <?php echo $select_list_attr; ?> class="block w-full h-8 mt-1 text-sm rounded-md cursor-pointer h-9 <?php echo esc_attr( $select_list_class ); ?>" name="<?php echo esc_attr( $select_list_name ); ?>" id="ig_es_broadcast_list_ids">
|
||||
<?php echo $lists ?>
|
||||
</select>
|
||||
|
||||
<div class="block mt-1">
|
||||
<span id="ig_es_total_contacts"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block py-2 mx-4">
|
||||
<div class="block pt-1 mx-4">
|
||||
<span class="block pt-2 text-sm font-medium leading-5 text-gray-700 border-t border-gray-200"><?php echo esc_html__( 'Preview', 'email-subscribers' ); ?></span>
|
||||
<div class="py-2">
|
||||
<input type="radio" name="preview_option" class="form-radio" id="preview_in_popup" value="preview_in_popup" checked>
|
||||
@@ -374,13 +377,6 @@ class ES_Newsletters {
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<label class=" text-sm font-medium leading-5 text-gray-700"><?php echo esc_html__( 'Preview', 'email-subscribers' ); ?></label>
|
||||
<button type="button" id="es_preview_template"
|
||||
class="rounded-md border text-indigo-600 border-indigo-500 text-sm leading-5 font-medium transition ease-in-out duration-150 select-none inline-flex justify-center hover:text-indigo-500 hover:border-indigo-600 hover:shadow-md focus:outline-none focus:shadow-outline-indigo focus:shadow-lg px-3 py-1.5 mx-2">
|
||||
<?php echo esc_html__( 'In Browser', 'email-subscribers' ); ?>
|
||||
</button> -->
|
||||
|
||||
<img class="es-loader inline-flex align-middle" src="<?php echo ES_PLUGIN_URL ?>lite/public/images/spinner.gif" style="display:none;"/>
|
||||
|
||||
<div class="hidden" id="preview_template">
|
||||
@@ -414,13 +410,13 @@ class ES_Newsletters {
|
||||
|
||||
<fieldset class="es_fieldset">
|
||||
|
||||
<div class="hidden px-4 mx-auto my-4 es_broadcast_second max-w-7xl sm:px-6 lg:px-3">
|
||||
<div class="my-4 hidden mx-auto es_broadcast_second max-w-7xl">
|
||||
<?php
|
||||
$inline_preview_data = $this->get_broadcast_inline_preview_data( $broadcast_data );
|
||||
?>
|
||||
<div class="max-w-7xl sm:px-6 lg:px-4">
|
||||
<div class="py-4 bg-white rounded-lg shadow md:flex">
|
||||
<div class="broadcast_main_content pt-3 pl-2">
|
||||
<div class="max-w-7xl">
|
||||
<div class=" bg-white rounded-lg shadow md:flex">
|
||||
<div class="py-4 my-4 broadcast_main_content pt-3 pl-2">
|
||||
<div class="block pb-2 mx-4">
|
||||
<span class="text-sm font-medium text-gray-500"><?php echo esc_html__( 'Email Content Preview', 'email-subscribers' ); ?></span>
|
||||
</div>
|
||||
@@ -450,8 +446,8 @@ class ES_Newsletters {
|
||||
|
||||
</div>
|
||||
|
||||
<div class="broadcast_side_content ml-2 mr-4 bg-gray-100 rounded-md">
|
||||
<div id="ig_es_total_recipients" class="block mt-1.5 mx-4 py-2 border-b border-gray-200">
|
||||
<div class="broadcast_side_content ml-2 bg-gray-100 rounded-r-lg">
|
||||
<div id="ig_es_total_recipients" class="block mx-4 border-b border-gray-200">
|
||||
|
||||
</div>
|
||||
|
||||
@@ -750,6 +746,11 @@ class ES_Newsletters {
|
||||
$email = '';
|
||||
|
||||
if ( ! empty( $list_id ) ) {
|
||||
// Check if multiple lists selection is enabled.
|
||||
if( is_array( $list_id ) && ! empty( $list_id ) ) {
|
||||
// Since we need to get only one sample email for showing the preview, we can get it from the first list itself.
|
||||
$list_id = $list_id[0];
|
||||
}
|
||||
$subscribed_contacts = ES()->lists_contacts_db->get_subscribed_contacts_from_list( $list_id );
|
||||
if ( ! empty( $subscribed_contacts ) ) {
|
||||
$subscribed_contact = array_shift( $subscribed_contacts );
|
||||
|
||||
@@ -69,6 +69,7 @@ class ES_Post_Notifications_Table {
|
||||
'name' => $title,
|
||||
'slug' => sanitize_title( $title )
|
||||
);
|
||||
|
||||
$data = apply_filters( 'ig_es_post_notification_data', $data );
|
||||
if ( empty( $data['base_template_id'] ) ) {
|
||||
$message = __( 'Please select template.', 'email-subscribers' );
|
||||
@@ -248,13 +249,18 @@ class ES_Post_Notifications_Table {
|
||||
}
|
||||
$cat = isset( $data['categories'] ) ? $data['categories'] : '';
|
||||
$list_id = isset( $data['list_ids'] ) ? $data['list_ids'] : '';
|
||||
|
||||
$template_id = isset( $data['base_template_id'] ) ? $data['base_template_id'] : '';
|
||||
$status = isset( $data['status'] ) ? $data['status'] : 0 ;
|
||||
$nonce = wp_create_nonce( 'es_post_notification' );
|
||||
|
||||
$select_list_attr = ES()->is_pro() ? 'multiple="multiple"' : '';
|
||||
$select_list_name = ES()->is_pro() ? 'list_id[]' : 'list_id';
|
||||
$select_list_class = ES()->is_pro() ? 'ig-es-form-multiselect' : 'form-select';
|
||||
?>
|
||||
|
||||
<div class="wrap max-w-full mt-1 font-sans">
|
||||
<header class="ml-12 mr-8 wp-heading-inline">
|
||||
<header class="wp-heading-inline">
|
||||
<div class="sm:grid sm:grid-cols lg:grid lg:grid-cols-2 max-w-full">
|
||||
<div class="mt-2">
|
||||
<h2 class="text-2xl font-medium mt-2 text-gray-900 sm:leading-9 sm:truncate">
|
||||
@@ -275,9 +281,9 @@ class ES_Post_Notifications_Table {
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="ml-12 mr-8"><hr class="wp-header-end"></div>
|
||||
<div class=""><hr class="wp-header-end"></div>
|
||||
|
||||
<div class="meta-box-sortables ui-sortable bg-white shadow-md ml-12 mr-8 mt-6 rounded-lg">
|
||||
<div class="bg-white shadow-md rounded-lg">
|
||||
<form class="ml-5 mr-4 text-left pt-4 mt-2 item-center" method="post" action="admin.php?page=es_notifications&action=<?php echo $action; ?>&list=<?php echo $id; ?>&_wpnonce=<?php echo $nonce; ?>">
|
||||
|
||||
<table class="max-w-full form-table">
|
||||
@@ -291,11 +297,16 @@ class ES_Post_Notifications_Table {
|
||||
<?php _e( 'Select List', 'email-subscribers' ); ?></span>
|
||||
<p class="italic text-xs font-normal text-gray-400 mt-2 ml-6 leading-snug"><?php _e( 'Contacts from the selected list will be notified about new post notification.', 'email-subscribers' ); ?></p></label>
|
||||
</th>
|
||||
|
||||
<td class="w-9/12 pb-3 ">
|
||||
<select class="relative form-select shadow-sm border border-gray-400 w-1/3 ml-12" name="list_id" id="ig_es_post_notification_list_ids">
|
||||
<?php echo ES_Common::prepare_list_dropdown_options( $list_id ); ?>
|
||||
</select>
|
||||
<div class="flex">
|
||||
<div class="w-2/4 inline-flex ml-12 relative">
|
||||
<select <?php echo $select_list_attr; ?> class="absolute shadow-sm border border-gray-400 w-2/3 <?php echo esc_attr( $select_list_class ); ?>" name="<?php echo esc_attr( $select_list_name ); ?>" id="ig_es_post_notification_list_ids">
|
||||
<?php echo ES_Common::prepare_list_dropdown_options( $list_id ); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<?php do_action('ig_es_add_multilist_options');?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-gray-100">
|
||||
|
||||
@@ -131,6 +131,7 @@ if ( ! class_exists( 'ES_Queue' ) ) {
|
||||
$campaign['start_at'] = date( 'Y-m-d H:i:s', $start_time );
|
||||
|
||||
$list_id = $campaign['list_ids'];
|
||||
$list_id = explode( ',', $list_id );
|
||||
|
||||
// Do we have active subscribers?
|
||||
$contacts = ES()->contacts_db->get_active_contacts_by_list_id( $list_id );
|
||||
@@ -214,6 +215,7 @@ if ( ! class_exists( 'ES_Queue' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$now = time();
|
||||
|
||||
foreach ( $campaigns as $campaign ) {
|
||||
|
||||
@@ -406,9 +406,28 @@ if ( ! function_exists( 'ig_es_get_upcoming_weekly_datetime' ) ) {
|
||||
6 => 'saturday'
|
||||
);
|
||||
|
||||
$next_week_day_str = 'next ' . $week_days_map[ $frequency_interval ];
|
||||
$current_day = (int) current_time( 'N' );
|
||||
|
||||
$timestamp = strtotime( $next_week_day_str ) + $time;
|
||||
// If campaign day is same as the current day then check campaign time also with current time since campaign time may have not already been passed.
|
||||
if( $current_day === (int) $frequency_interval ) {
|
||||
// Get curret time.
|
||||
$current_hours = (int) current_time( 'H' );
|
||||
$current_minutes = (int) current_time( 'i' );
|
||||
$current_seconds = (int) current_time( 's' );
|
||||
|
||||
$current_time = $current_hours * HOUR_IN_SECONDS + $current_minutes * MINUTE_IN_SECONDS + $current_seconds;
|
||||
|
||||
// Check if campaign time has not yet passed then we can use today's date/time else use date/time when campaign day comes next time.
|
||||
if( $current_time < $time ) {
|
||||
$week_day_str = 'today';
|
||||
} else {
|
||||
$week_day_str = 'next ' . $week_days_map[ $frequency_interval ];
|
||||
}
|
||||
} else {
|
||||
$week_day_str = 'next ' . $week_days_map[ $frequency_interval ];
|
||||
}
|
||||
|
||||
$timestamp = strtotime( $week_day_str ) + $time;
|
||||
|
||||
return $timestamp;
|
||||
|
||||
@@ -599,3 +618,81 @@ if ( ! function_exists( 'ig_es_array_insert_after' ) ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'ig_es_get_raw_human_interval' ) ) {
|
||||
/**
|
||||
* Gets interval split by days, hours, minutes and seconds
|
||||
*
|
||||
* @param $interval_in_seconds
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.4.9
|
||||
*/
|
||||
function ig_es_get_raw_human_interval( $interval_in_seconds = 0 ) {
|
||||
|
||||
$interval = array();
|
||||
|
||||
$seconds_in_minute = 60;
|
||||
$seconds_in__hour = 60 * $seconds_in_minute;
|
||||
$seconds_in_day = 24 * $seconds_in__hour;
|
||||
|
||||
// extract days
|
||||
$interval['days'] = floor( $interval_in_seconds / $seconds_in_day );
|
||||
|
||||
// extract hours
|
||||
$hour_seconds = $interval_in_seconds % $seconds_in_day;
|
||||
$interval['hours'] = floor( $hour_seconds / $seconds_in__hour );
|
||||
|
||||
// extract minutes
|
||||
$minute_seconds = $hour_seconds % $seconds_in__hour;
|
||||
$interval['minutes'] = floor( $minute_seconds / $seconds_in_minute );
|
||||
|
||||
// extract the remaining seconds
|
||||
$remaining_seconds = $minute_seconds % $seconds_in_minute;
|
||||
$interval['seconds'] = ceil( $remaining_seconds );
|
||||
|
||||
return $interval;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'ig_es_get_human_interval' ) ) {
|
||||
/**
|
||||
* Gets interval in human readable format
|
||||
*
|
||||
* @param $interval_in_seconds
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 4.4.9
|
||||
*/
|
||||
function ig_es_get_human_interval( $interval_in_seconds = 0 ) {
|
||||
|
||||
$interval = ig_es_get_raw_human_interval( $interval_in_seconds );
|
||||
|
||||
$human_time = '';
|
||||
|
||||
if ( $interval['days'] > 0 ) {
|
||||
$human_time .= $interval['days'] . 'd ';
|
||||
}
|
||||
|
||||
if ( $interval['hours'] > 0 ) {
|
||||
$human_time .= $interval['hours'] . 'h ';
|
||||
}
|
||||
|
||||
if ( $interval['minutes'] > 0 ) {
|
||||
$human_time .= $interval['minutes'] . 'm ';
|
||||
}
|
||||
|
||||
if ( $interval['seconds'] > 0 ) {
|
||||
$human_time .= $interval['seconds'] . 's ';
|
||||
}
|
||||
|
||||
if ( empty( $human_time ) ) {
|
||||
$human_time = '0s';
|
||||
}
|
||||
|
||||
return trim( $human_time );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
* Description: A robust scheduling library for use in WordPress plugins.
|
||||
* Author: Automattic
|
||||
* Author URI: https://automattic.com/
|
||||
* Version: 3.1.4
|
||||
* Version: 3.1.6
|
||||
* License: GPLv3
|
||||
*
|
||||
* Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
|
||||
@@ -25,28 +25,28 @@
|
||||
*
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'action_scheduler_register_3_dot_1_dot_4' ) ) {
|
||||
if ( ! function_exists( 'action_scheduler_register_3_dot_1_dot_6' ) ) {
|
||||
|
||||
if ( ! class_exists( 'ActionScheduler_Versions' ) ) {
|
||||
require_once( 'classes/ActionScheduler_Versions.php' );
|
||||
add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
|
||||
}
|
||||
|
||||
add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_1_dot_4', 0, 0 );
|
||||
add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_1_dot_6', 0, 0 );
|
||||
|
||||
function action_scheduler_register_3_dot_1_dot_4() {
|
||||
function action_scheduler_register_3_dot_1_dot_6() {
|
||||
$versions = ActionScheduler_Versions::instance();
|
||||
$versions->register( '3.1.4', 'action_scheduler_initialize_3_dot_1_dot_4' );
|
||||
$versions->register( '3.1.6', 'action_scheduler_initialize_3_dot_1_dot_6' );
|
||||
}
|
||||
|
||||
function action_scheduler_initialize_3_dot_1_dot_4() {
|
||||
function action_scheduler_initialize_3_dot_1_dot_6() {
|
||||
require_once( 'classes/abstracts/ActionScheduler.php' );
|
||||
ActionScheduler::init( __FILE__ );
|
||||
}
|
||||
|
||||
// Support usage in themes - load this version if no plugin has loaded a version yet.
|
||||
if ( did_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler' ) ) {
|
||||
action_scheduler_initialize_3_dot_1_dot_4();
|
||||
action_scheduler_initialize_3_dot_1_dot_6();
|
||||
do_action( 'action_scheduler_pre_theme_init' );
|
||||
ActionScheduler_Versions::initialize_latest_version();
|
||||
}
|
||||
|
||||
@@ -50,16 +50,15 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
|
||||
|
||||
add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) );
|
||||
|
||||
// Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param
|
||||
$next_timestamp = wp_next_scheduled( self::WP_CRON_HOOK );
|
||||
if ( $next_timestamp ) {
|
||||
wp_unschedule_event( $next_timestamp, self::WP_CRON_HOOK );
|
||||
}
|
||||
|
||||
$cron_context = array( 'WP Cron' );
|
||||
|
||||
if ( ! wp_next_scheduled( self::WP_CRON_HOOK, $cron_context ) ) {
|
||||
|
||||
// Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param
|
||||
$next_timestamp = wp_next_scheduled( self::WP_CRON_HOOK );
|
||||
if ( $next_timestamp ) {
|
||||
wp_unschedule_event( $next_timestamp, self::WP_CRON_HOOK );
|
||||
}
|
||||
|
||||
$schedule = apply_filters( 'action_scheduler_run_schedule', self::WP_CRON_SCHEDULE );
|
||||
wp_schedule_event( time(), $schedule, self::WP_CRON_HOOK, $cron_context );
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ abstract class ActionScheduler {
|
||||
private static $plugin_file = '';
|
||||
/** @var ActionScheduler_ActionFactory */
|
||||
private static $factory = NULL;
|
||||
/** @var bool */
|
||||
private static $data_store_initialized = false;
|
||||
|
||||
public static function factory() {
|
||||
if ( !isset(self::$factory) ) {
|
||||
@@ -170,6 +172,8 @@ abstract class ActionScheduler {
|
||||
}
|
||||
}
|
||||
|
||||
self::$data_store_initialized = true;
|
||||
|
||||
/**
|
||||
* Handle WP comment cleanup after migration.
|
||||
*/
|
||||
@@ -180,6 +184,21 @@ abstract class ActionScheduler {
|
||||
add_action( 'action_scheduler/migration_complete', 'ActionScheduler_WPCommentCleaner::maybe_schedule_cleanup' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the AS data store has been initialized.
|
||||
*
|
||||
* @param string $function_name The name of the function being called. Optional. Default `null`.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_initialized( $function_name = null ) {
|
||||
if ( ! self::$data_store_initialized && ! empty( $function_name ) ) {
|
||||
$message = sprintf( __( '%s() was called before the Action Scheduler data store was initialized', 'action-scheduler' ), esc_attr( $function_name ) );
|
||||
error_log( $message, E_WARNING );
|
||||
}
|
||||
|
||||
return self::$data_store_initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the class is one of our abstract classes.
|
||||
*
|
||||
@@ -272,4 +291,14 @@ abstract class ActionScheduler {
|
||||
_deprecated_function( __METHOD__, '2.0', 'wcs_add_months()' );
|
||||
return as_get_datetime_object( $when, $timezone );
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue deprecated warning if an Action Scheduler function is called in the shutdown hook.
|
||||
*
|
||||
* @param string $function_name The name of the function being called.
|
||||
* @deprecated 3.1.6.
|
||||
*/
|
||||
public static function check_shutdown_hook( $function_name ) {
|
||||
_deprecated_function( __FUNCTION__, '3.1.6' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ class Controller {
|
||||
add_filter( 'action_scheduler_store_class', array( $this, 'get_store_class' ), 100, 1 );
|
||||
add_filter( 'action_scheduler_logger_class', array( $this, 'get_logger_class' ), 100, 1 );
|
||||
add_action( 'init', array( $this, 'maybe_hook_migration' ) );
|
||||
add_action( 'shutdown', array( $this, 'schedule_migration' ), 0, 0 );
|
||||
add_action( 'wp_loaded', array( $this, 'schedule_migration' ) );
|
||||
|
||||
// Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen
|
||||
add_action( 'load-tools_page_action-scheduler', array( $this, 'hook_admin_notices' ), 10, 0 );
|
||||
|
||||
@@ -83,7 +83,7 @@ class Scheduler {
|
||||
}
|
||||
|
||||
if ( empty( $when ) ) {
|
||||
$when = time();
|
||||
$when = time() + MINUTE_IN_SECONDS;
|
||||
}
|
||||
|
||||
return as_schedule_single_action( $when, self::HOOK, array(), self::GROUP );
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
* @return int The action ID.
|
||||
*/
|
||||
function as_enqueue_async_action( $hook, $args = array(), $group = '' ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
return 0;
|
||||
}
|
||||
return ActionScheduler::factory()->async( $hook, $args, $group );
|
||||
}
|
||||
|
||||
@@ -27,6 +30,9 @@ function as_enqueue_async_action( $hook, $args = array(), $group = '' ) {
|
||||
* @return int The action ID.
|
||||
*/
|
||||
function as_schedule_single_action( $timestamp, $hook, $args = array(), $group = '' ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
return 0;
|
||||
}
|
||||
return ActionScheduler::factory()->single( $hook, $args, $timestamp, $group );
|
||||
}
|
||||
|
||||
@@ -42,6 +48,9 @@ function as_schedule_single_action( $timestamp, $hook, $args = array(), $group =
|
||||
* @return int The action ID.
|
||||
*/
|
||||
function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '' ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
return 0;
|
||||
}
|
||||
return ActionScheduler::factory()->recurring( $hook, $args, $timestamp, $interval_in_seconds, $group );
|
||||
}
|
||||
|
||||
@@ -69,6 +78,9 @@ function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook,
|
||||
* @return int The action ID.
|
||||
*/
|
||||
function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(), $group = '' ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
return 0;
|
||||
}
|
||||
return ActionScheduler::factory()->cron( $hook, $args, $timestamp, $schedule, $group );
|
||||
}
|
||||
|
||||
@@ -89,6 +101,9 @@ function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(),
|
||||
* @return string|null The scheduled action ID if a scheduled action was found, or null if no matching action found.
|
||||
*/
|
||||
function as_unschedule_action( $hook, $args = array(), $group = '' ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
return 0;
|
||||
}
|
||||
$params = array();
|
||||
if ( is_array($args) ) {
|
||||
$params['args'] = $args;
|
||||
@@ -113,6 +128,9 @@ function as_unschedule_action( $hook, $args = array(), $group = '' ) {
|
||||
* @param string $group The group the job is assigned to.
|
||||
*/
|
||||
function as_unschedule_all_actions( $hook, $args = array(), $group = '' ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
return;
|
||||
}
|
||||
if ( empty( $args ) ) {
|
||||
if ( ! empty( $hook ) && empty( $group ) ) {
|
||||
ActionScheduler_Store::instance()->cancel_actions_by_hook( $hook );
|
||||
@@ -144,6 +162,9 @@ function as_unschedule_all_actions( $hook, $args = array(), $group = '' ) {
|
||||
* @return int|bool The timestamp for the next occurrence of a pending scheduled action, true for an async or in-progress action or false if there is no matching action.
|
||||
*/
|
||||
function as_next_scheduled_action( $hook, $args = NULL, $group = '' ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
return false;
|
||||
}
|
||||
$params = array();
|
||||
if ( is_array($args) ) {
|
||||
$params['args'] = $args;
|
||||
@@ -196,6 +217,9 @@ function as_next_scheduled_action( $hook, $args = NULL, $group = '' ) {
|
||||
* @return array
|
||||
*/
|
||||
function as_get_scheduled_actions( $args = array(), $return_format = OBJECT ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
return array();
|
||||
}
|
||||
$store = ActionScheduler::store();
|
||||
foreach ( array('date', 'modified') as $key ) {
|
||||
if ( isset($args[$key]) ) {
|
||||
|
||||
@@ -22,6 +22,7 @@ add_action( 'ig_es_after_broadcast_content_left_pan_settings','ig_es_additional_
|
||||
add_action( 'ig_es_after_broadcast_tracking_options_settings', 'ig_es_additional_track_option');
|
||||
add_action( 'ig_es_broadcast_scheduling_options_settings', 'ig_es_additional_schedule_option');
|
||||
add_action( 'ig_es_after_broadcast_right_pan_settings', 'ig_es_additional_spam_score_option');
|
||||
add_action( 'ig_es_add_multilist_options', 'ig_es_additional_multilist_option' );
|
||||
|
||||
/**
|
||||
* Promote SMTP mailer for free
|
||||
@@ -652,6 +653,48 @@ function ig_es_add_captcha_option( $form_data ) {
|
||||
<?php }
|
||||
}
|
||||
|
||||
function ig_es_additional_multilist_option(){
|
||||
|
||||
if ( ! ES()->is_premium_installed() ) {
|
||||
|
||||
$utm_args = array(
|
||||
"utm_medium" => "post_notifications_multiple_lists"
|
||||
);
|
||||
|
||||
$pricing_url = ES_Common::get_utm_tracking_url( $utm_args );
|
||||
|
||||
?>
|
||||
<div class="w-2/4 ml-2">
|
||||
<div class="inline-flex rounded-md bg-teal-50 px-2 pt-1 w-full">
|
||||
<div class="px-2 pt-2 pb-2">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
<svg class='h-5 w-5 text-teal-400' fill='currentColor' viewBox='0 0 20 20'>
|
||||
<path fill-rule='evenodd' d='M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z' clip-rule='evenodd'/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm leading-5 font-medium text-blue-800">
|
||||
<?php _e( sprintf("<a href='%s' target='_blank'>Upgrade to ES PRO</a>", $pricing_url), 'email-subscribers' ); ?>
|
||||
</h3>
|
||||
<div class="mt-2 text-sm leading-5 text-teal-700">
|
||||
<p>
|
||||
<?php _e( 'Get rid of setting Post Notifications for each list and avoid chances of sending duplicate emails to your subscribers.', 'email-subscribers' ); ?>
|
||||
<br /><br />
|
||||
<?php _e( ' Upgrade to Email Subscribers PRO and select multiple lists.', 'email-subscribers' ); ?>
|
||||
<br /><br />
|
||||
<?php if(ES_Common::can_show_coupon('PREMIUM10')) { _e( 'Get a <b>10% flat discount</b> if you upgrade now!. <br /><br />Use coupon code <b>PREMIUM10</b>', 'email-subscribers' );}?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php }
|
||||
|
||||
}
|
||||
|
||||
function ig_es_additional_send_email_option() {
|
||||
|
||||
if ( ! ES()->is_pro() ) { ?>
|
||||
|
||||
@@ -132,7 +132,7 @@ function ig_es_update_330_import_options() {
|
||||
update_option( $new_option_name, $option_value );
|
||||
delete_option( $old_option_name );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Do not pull data for new users as there is no pluginconfig table created on activation
|
||||
@@ -432,12 +432,7 @@ function ig_es_update_400_delete_tables() {
|
||||
}
|
||||
|
||||
function ig_es_update_400_create_tables() {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->hide_errors();
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( ES_Install::get_ig_es_400_schema() );
|
||||
|
||||
ES_Install::create_tables( '4.0.0' );
|
||||
}
|
||||
|
||||
function ig_es_update_400_import_options() {
|
||||
@@ -839,12 +834,7 @@ function ig_es_update_420_alter_campaigns_table() {
|
||||
* @since 4.2.0
|
||||
*/
|
||||
function ig_es_update_420_create_tables() {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->hide_errors();
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( ES_Install::get_ig_es_420_schema() );
|
||||
ES_Install::create_tables( '4.2.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -915,11 +905,7 @@ function ig_es_update_421_drop_tables() {
|
||||
* @since 4.2.1
|
||||
*/
|
||||
function ig_es_update_421_create_tables() {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->hide_errors();
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( ES_Install::get_ig_es_421_schema() );
|
||||
ES_Install::create_tables( '4.2.1' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,11 +948,7 @@ function ig_es_update_424_drop_tables() {
|
||||
* @since 4.2.4
|
||||
*/
|
||||
function ig_es_update_424_create_tables() {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->hide_errors();
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( ES_Install::get_ig_es_424_schema() );
|
||||
ES_Install::create_tables( '4.2.4' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1027,7 +1009,7 @@ function ig_es_update_431_permanently_delete_lists() {
|
||||
global $wpdb;
|
||||
|
||||
$query = "DELETE FROM {$wpdb->prefix}ig_lists WHERE deleted_at IS NOT NULL";
|
||||
$wpdb->query($query);
|
||||
$wpdb->query( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1039,8 +1021,9 @@ function ig_es_update_431_permanently_delete_forms() {
|
||||
global $wpdb;
|
||||
|
||||
$query = "DELETE FROM {$wpdb->prefix}ig_forms WHERE deleted_at IS NOT NULL";
|
||||
$wpdb->query($query);
|
||||
$wpdb->query( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete unwanted options
|
||||
*
|
||||
@@ -1061,11 +1044,12 @@ function ig_es_update_431_delete_options() {
|
||||
'ig_es_unsubcontent',
|
||||
);
|
||||
|
||||
$options_str = "'" . implode($options_to_delete, "', '") . "'";
|
||||
$options_str = "'" . implode( $options_to_delete, "', '" ) . "'";
|
||||
|
||||
$query = "DELETE FROM {$wpdb->prefix}options WHERE option_name IN ($options_str)";
|
||||
$wpdb->query($query);
|
||||
$wpdb->query( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable autoload for all ES options
|
||||
*
|
||||
@@ -1086,6 +1070,7 @@ function ig_es_update_431_disable_autoload_options() {
|
||||
function ig_es_update_431_db_version() {
|
||||
ES_Install::update_db_version( '4.3.1' );
|
||||
}
|
||||
|
||||
/* --------------------- ES 4.3.1(End)--------------------------- */
|
||||
|
||||
/**
|
||||
@@ -1093,9 +1078,10 @@ function ig_es_update_431_db_version() {
|
||||
*
|
||||
* @sicne 4.3.2
|
||||
*/
|
||||
function ig_es_update_432_import_bfcm_templates(){
|
||||
function ig_es_update_432_import_bfcm_templates() {
|
||||
ES_Install::load_templates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update DB Update history
|
||||
*
|
||||
@@ -1104,6 +1090,7 @@ function ig_es_update_432_import_bfcm_templates(){
|
||||
function ig_es_update_432_db_version() {
|
||||
ES_Install::update_db_version( '4.3.2' );
|
||||
}
|
||||
|
||||
/* --------------------- ES 4.3.2(End)--------------------------- */
|
||||
/**
|
||||
* Delete Campaigns Permanently
|
||||
@@ -1115,7 +1102,7 @@ function ig_es_update_434_permanently_delete_campaigns() {
|
||||
global $wpdb;
|
||||
|
||||
$query = "DELETE FROM {$wpdb->prefix}ig_campaigns WHERE deleted_at IS NOT NULL AND deleted_at != '0000-00-00 00:00:00' ";
|
||||
$wpdb->query($query);
|
||||
$wpdb->query( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1126,6 +1113,7 @@ function ig_es_update_434_permanently_delete_campaigns() {
|
||||
function ig_es_update_434_db_version() {
|
||||
ES_Install::update_db_version( '4.3.4' );
|
||||
}
|
||||
|
||||
/* --------------------- ES 4.3.4(End)--------------------------- */
|
||||
|
||||
|
||||
@@ -1136,16 +1124,12 @@ function ig_es_update_434_db_version() {
|
||||
* @since 4.4.1
|
||||
*/
|
||||
function ig_es_update_441_create_tables() {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->hide_errors();
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( ES_Install::get_ig_es_441_schema() );
|
||||
ES_Install::create_tables( '4.4.1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate audience sync setting to related workflows/admin settings.
|
||||
*
|
||||
*
|
||||
* @since 4.4.1
|
||||
*/
|
||||
function ig_es_update_441_migrate_audience_sync_settings() {
|
||||
@@ -1161,6 +1145,7 @@ function ig_es_update_441_migrate_audience_sync_settings() {
|
||||
function ig_es_update_441_db_version() {
|
||||
ES_Install::update_db_version( '4.4.1' );
|
||||
}
|
||||
|
||||
/* --------------------- ES 4.4.1(End)--------------------------- */
|
||||
|
||||
|
||||
@@ -1175,7 +1160,7 @@ function ig_es_update_442_set_workflows_default_permission() {
|
||||
$user_role_permissions = get_option( 'ig_es_user_roles', false );
|
||||
if ( false === $user_role_permissions ) {
|
||||
update_option( 'ig_es_user_roles', ES_Install::get_default_permissions() );
|
||||
} else if( ! empty( $user_role_permissions ) && is_array( $user_role_permissions ) ) {
|
||||
} elseif ( ! empty( $user_role_permissions ) && is_array( $user_role_permissions ) ) {
|
||||
$user_role_permissions['workflows'] = array(
|
||||
'administrator' => 'yes'
|
||||
);
|
||||
@@ -1184,7 +1169,7 @@ function ig_es_update_442_set_workflows_default_permission() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update DB version
|
||||
* Update DB version
|
||||
*
|
||||
* @since 4.4.2
|
||||
*/
|
||||
@@ -1192,4 +1177,45 @@ function ig_es_update_442_db_version() {
|
||||
ES_Install::update_db_version( '4.4.2' );
|
||||
}
|
||||
|
||||
/* --------------------- ES 4.4.2(End)--------------------------- */
|
||||
/* --------------------- ES 4.4.2(End)--------------------------- */
|
||||
|
||||
/* --------------------- ES 4.4.9(Start)--------------------------- */
|
||||
|
||||
/*
|
||||
* Verify table structure. If table is not created, this will create table
|
||||
*/
|
||||
function ig_es_update_449_create_tables() {
|
||||
ES_Install::create_tables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update DB version
|
||||
*
|
||||
* @since 4.4.2
|
||||
*/
|
||||
function ig_es_update_449_db_version() {
|
||||
ES_Install::update_db_version( '4.4.9' );
|
||||
}
|
||||
/* --------------------- ES 4.4.9(End)--------------------------- */
|
||||
|
||||
/* --------------------- ES 4.4.10(Start)--------------------------- */
|
||||
|
||||
/**
|
||||
* Load templates
|
||||
*
|
||||
* @since 4.4.10
|
||||
*/
|
||||
function ig_es_update_4410_load_templates() {
|
||||
ES_Install::load_templates( true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update DB version
|
||||
*
|
||||
* @since 4.4.10
|
||||
*/
|
||||
function ig_es_update_4410_db_version() {
|
||||
ES_Install::update_db_version( '4.4.10' );
|
||||
}
|
||||
|
||||
/* --------------------- ES 4.4.10(End)--------------------------- */
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -129,7 +129,7 @@ class Email_Subscribers_Public {
|
||||
public function es_email_subscribe_init() {
|
||||
global $wpdb, $ig_es_tracker;
|
||||
//initialize
|
||||
|
||||
ob_start();
|
||||
new ES_Handle_Subscription();
|
||||
new ES_Shortcode();
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
|
||||
Author URI: https://www.icegram.com/
|
||||
Tags: email marketing, subscription, autoresponder, post notification, welcome email
|
||||
Requires at least: 3.9
|
||||
Tested up to: 5.4.1
|
||||
Tested up to: 5.4.2
|
||||
Requires PHP: 5.6
|
||||
Stable tag: 4.4.8
|
||||
Stable tag: 4.4.10
|
||||
License: GPLv3
|
||||
License URI: http://www.gnu.org/licenses
|
||||
|
||||
@@ -18,57 +18,65 @@ Email Subscribers is a complete newsletter plugin that lets you **collect leads,
|
||||
|
||||
Email Subscribers is a fully-featured subscription plugin specially created keeping in mind all the needs and requirements of a **regular blogger, website owner, marketer and developers**. It helps you achieve all the things you need to build a list and keep them engaged within a single plugin.
|
||||
|
||||
**Easily Collect Leads On Your Website** : Insert a neat looking subscription box anywhere on your website. This subscription box is beautifully designed and grabs audiences attention instantly.
|
||||
**Easily Collect Leads On Your Website** : Insert a neat looking subscription box anywhere on your website. This subscription box is beautifully designed and grabs the audience's attention instantly.
|
||||
|
||||
**Send Automated Updates when a Post is published** : Save on time by automating the process of sending emails each time a blog post is published.
|
||||
|
||||
**Quickly Create and Send Broadcasts** : Create beautiful broadcasts using the HTML editor and send them to your subscribers either manually or via CRON.
|
||||
|
||||
**Grow your impact. Stop worrying about email.**
|
||||
|
||||
[youtube https://youtu.be/znh_bif3Kic]
|
||||
|
||||
#### **Benefits of Email Subscribers**
|
||||
|
||||
* **Own your data** - Keep your data on your server.
|
||||
* **Store unlimited Contacts**
|
||||
* **Create unlimited Broadcasts**
|
||||
* **Create unlimited Post Notifications**
|
||||
* **Create unlimited email templates**
|
||||
* **Create unlimited forms**
|
||||
* **Subscription spam check** with domain black lists,
|
||||
* **GDPR** ready
|
||||
* **Workflows**
|
||||
* **Seamless integration** with WordPress users
|
||||
* **Single** And **Double Opt-In** plus privacy checkbox for EU laws compliance
|
||||
* **Compatible with every SMTP plugin**: WP Mail SMTP, Post SMTP (aka Postman), Easy WP SMTP, Easy SMTP Mail, WP Mail Bank
|
||||
* Send **Post Notifications** to contacts when new posts are published.
|
||||
* **Collect customer emails by adding a subscription box using Widget, Form Shortcode or PHP code**.
|
||||
* **Email notification** to admin when user **signs up** (Optional).
|
||||
* **Automatic welcome email** to contacts (Optional).
|
||||
* Automatically add **Unsubscribe link** in the email.
|
||||
* **Import/Export contacts**
|
||||
* **HTML editor** to create broadcasts and post notifications.
|
||||
* Email **Open/ Viewed status**
|
||||
* Support **localization or internationalization**.
|
||||
* Send **Post Notifications based on Post categories**
|
||||
* Easy Integration with Popups, Welcome Bar, Optins and Lead Generation Plugin **[Icegram](https://wordpress.org/plugins/icegram/)** and form plugin **[Rainmaker](https://wordpress.org/plugins/icegram-rainmaker/)**
|
||||
> ➡️ **Own your data** - Keep your data on your server.
|
||||
> ➡️ **Store Unlimited Contacts**
|
||||
> ➡️ **Send Unlimited Broadcasts**
|
||||
> ➡️ **Create Unlimited Post Notifications**
|
||||
> ➡️ **Use Unlimited Email Templates**
|
||||
> ➡️ **Create Unlimited Lists**
|
||||
> ➡️ **Create Unlimited Forms**
|
||||
> ➡️ **Subscription spam check** with domain black lists,
|
||||
> ➡️ **GDPR** ready
|
||||
> ➡️ **Workflows**
|
||||
> ➡️ **Seamless integration** with WordPress users
|
||||
> ➡️ **Single** And **Double Opt-In** plus privacy checkbox for EU laws compliance
|
||||
> ➡️ **Compatible with every SMTP plugin**: WP Mail SMTP, Post SMTP (aka Postman), Easy WP SMTP, Easy SMTP Mail, WP Mail Bank
|
||||
> ➡️ Send **Post Notifications** to contacts when new posts are published.
|
||||
> ➡️ **Collect customer emails by adding a subscription box using Widget, Form Shortcode or PHP code**.
|
||||
> ➡️ **Email notification** to admin when user **signs up** (Optional).
|
||||
> ➡️ **Automatic welcome email** to contacts (Optional).
|
||||
> ➡️ Automatically add **Unsubscribe link** in the email.
|
||||
> ➡️ **Import/Export contacts**
|
||||
> ➡️ **HTML editor** to create broadcasts and post notifications.
|
||||
> ➡️ Email **Open/ Viewed status**
|
||||
> ➡️ Support **localization or internationalization**.
|
||||
> ➡️ Send **Post Notifications based on Post categories**
|
||||
> ➡️ Easy Integration with Popups, Welcome Bar, Optins and Lead Generation Plugin **[Icegram](https://wordpress.org/plugins/icegram/)** and form plugin **[Rainmaker](https://wordpress.org/plugins/icegram-rainmaker/)**
|
||||
|
||||
#### **Email Subscribers PRO benefits**
|
||||
|
||||
* Create & Send **Post Digest**
|
||||
* Create **Autoresponder Sequences**. It's really useful to onboard your contacts or sends them a series of update notification
|
||||
* **Schedule email sending**
|
||||
* **Protect your list from bot attacks** - Use captcha to protect your email list from bots. The simple maths captcha helps to identify bots from humans and eliminates spam signups.
|
||||
* **Email List Cleanup** - Automatically clean up your list.
|
||||
* **Access Control** - Give/ Restrict access to various Email Subscribers' features to the specific role
|
||||
* **Newsletter email templates** - Elegant newsletter templates to keep your leads engaged with your content
|
||||
* **Offer & promotional email templates** - High converting ready-to-use templates for any occasion, events or holiday season.
|
||||
* **New blog post notification email templates** - Awesome templates that will encourage contacts to read your blog post
|
||||
* **Automatic Background Sending**
|
||||
* **Active Contacts Growth, Campaigns Reports**
|
||||
* **Connect with SMTP / Email Sending Services**
|
||||
* **Link Tracking**
|
||||
* **UTM Tracking**
|
||||
* **Automatic Spam Score Checking**
|
||||
* **Create Workflows to automatically add people to your mailing list whenever someone posts a comment on your website**
|
||||
* Integrate with **[WooCommerce](https://wordpress.org/plugins/woocommerce/)**, **[EDD – Easy Digital Downloads](https://wordpress.org/plugins/easy-digital-downloads)**, **[Give](https://wordpress.org/plugins/give/)**, **[Contact Form 7](https://wordpress.org/plugins/contact-form-7/)**, **[Ninja Forms](https://wordpress.org/plugins/ninja-forms/)**, **[WPForms](https://wordpress.org/plugins/wpforms-lite/)**, **[Gravity Forms](https://www.gravityforms.com/)**, **[Forminator](http://wordpress.org/plugins/forminator)**
|
||||
> 👉 Create Unlimited **Autoresponder Sequences**. It's really useful to onboard your contacts or sends them a series of update notification
|
||||
> 👉 Create Unlimited **Post Digest**
|
||||
> 👉 **Schedule email sending**
|
||||
> 👉 **Protect your list from bot attacks** - Use captcha to protect your email list from bots. The simple maths captcha helps to identify bots from humans and eliminates spam signups.
|
||||
> 👉 **Email List Cleanup** - Automatically clean up your list.
|
||||
> 👉 **Access Control** - Give/ Restrict access to various Email Subscribers' features to the specific role
|
||||
> 👉 **Newsletter email templates** - Elegant newsletter templates to keep your leads engaged with your content
|
||||
> 👉 **Offer & promotional email templates** - High converting ready-to-use templates for any occasion, events or holiday season.
|
||||
> 👉 **New blog post notification email templates** - Awesome templates that will encourage contacts to read your blog post
|
||||
> 👉 **Automatic Background Sending**
|
||||
> 👉 **Active Contacts Growth, Campaigns Reports**
|
||||
> 👉 **Connect with SMTP / Email Sending Services**
|
||||
> 👉 **Email Open Tracking**
|
||||
> 👉 **Link Tracking**
|
||||
> 👉 **UTM Tracking**
|
||||
> 👉 **Automatic Spam Score Checking**
|
||||
> 👉 **Create Workflows to automatically add people to your mailing list whenever someone posts a comment on your website**
|
||||
> 👉 Integrate with **[WooCommerce](https://wordpress.org/plugins/woocommerce/)**, **[EDD – Easy Digital Downloads](https://wordpress.org/plugins/easy-digital-downloads)**, **[Give](https://wordpress.org/plugins/give/)**, **[Contact Form 7](https://wordpress.org/plugins/contact-form-7/)**, **[Ninja Forms](https://wordpress.org/plugins/ninja-forms/)**, **[WPForms](https://wordpress.org/plugins/wpforms-lite/)**, **[Gravity Forms](https://www.gravityforms.com/)**, **[Forminator](http://wordpress.org/plugins/forminator)**
|
||||
> 👉 Redirect subscribers to a specific page after unsubscribing
|
||||
> 👉 Allow subscribers to select list(s) while unsubscribing
|
||||
|
||||
Learn more about [Email Subscribers PRO](https://www.icegram.com/email-subscribers-pricing/)
|
||||
|
||||
@@ -89,27 +97,39 @@ We at **[icegram](https://icegram.com)** continuously improving the Email Subscr
|
||||
|
||||
Don’t believe it? Have a look at the review section. The support guys are friendly and ever willing to assist you with whatever be your query. Feel free to contact them with both pre-sales, after-sales questions.
|
||||
|
||||
> **Lightning support** -
|
||||
> Had 3 questions about the plugin, got extensive support with each one. Continue doing what you’re doing! Thanks a lot! 5/5
|
||||
* 👉 **Must Have Plugin** -
|
||||
> I highly recommend it because he has amazing email marketing tools and the support team is knowledgeable and kind. I would suggest you get rid of your conventional email marketing external provider and on the other hand, put your mind into the Email Subscribers & Newsletters plugin because it will help you to have a better flow and you will become more consistent with your email marketing development as well. I am not getting paid on anything for this feedback. I had a problem with Mailchimp so I decided to test the Email Subscribers & Newsletters and it saved my life. I believe I will use it for a very long time. Thanks, guys for developing it.
|
||||
> - [Mauro](https://wordpress.org/support/topic/must-have-plugin-371/)
|
||||
|
||||
* 👉 **Just what the doctor ordered!** -
|
||||
> needed a way to have my own email list software that included sign-up forms and newsletter capability, that would work through my SMTP host. This did the job perfectly and was super easy to setup. Kudos!
|
||||
> - [codekitten55](https://wordpress.org/support/topic/just-what-the-doctor-ordered-50/)
|
||||
|
||||
* 👉 **Incredible!** -
|
||||
> Incredible! We love this plugin! It’s very important to our company!
|
||||
> - [maxwelltg1](https://wordpress.org/support/topic/incredible-189/)
|
||||
|
||||
* 👉 **Lightning support** -
|
||||
> I highly recommend it because he has amazing email marketing tools and the support team is knowledgeable and kind. I would suggest you to get rid of your conventional email marketing external provider and on the other hand put your mind into the Email Subscribers & Newsletters plugin because it will help you to have a better flow and you will become more consistent with your email marketing development as well. I am not getting paid on anything for this feedback. I had a problem with Mailchimp so I decided to test the Email Subscribers & Newsletters and it saved my life. I believe I will use it for a very long time. Thanks guys for developing it. Mauro
|
||||
> - [DomLaurin](https://wordpress.org/support/topic/lightning-support/)
|
||||
|
||||
* **Easy to use but super powerfull** -
|
||||
> **Easy to configure, tweak and manage**. And works like a charm
|
||||
* 👉 **Easy to use but super powerfull** -
|
||||
> **Easy to configure, tweak and manage**. And works like a charm
|
||||
> - [Aleksander](https://wordpress.org/support/topic/easy-to-use-but-super-powerfull/)
|
||||
|
||||
* **Impressive and simple** -
|
||||
* 👉 **Impressive and simple** -
|
||||
> Found this plugin, most impressed, simple to set up, easy to use and the support is overwhelming
|
||||
> - [Closeburn](https://wordpress.org/support/topic/impressive-and-simple/)
|
||||
|
||||
* **Great product and support** -
|
||||
* 👉 **Great product and support** -
|
||||
> I highly recommend this product. It does everything it says it will do, is easily adaptable to your website, and Mansi’s level of support is fantastic. Unlike some of the other similar plugins, this one gives you total control over who requests to subscribe to your newsletter or blog.
|
||||
> - [ForPm](https://wordpress.org/support/topic/great-product-and-support-11/)
|
||||
|
||||
Go to [Email Subscribers review section](https://wordpress.org/support/plugin/email-subscribers/reviews/) to know more about our recent reviews.
|
||||
|
||||
**Help Fellow WordPressers by Writing a Review**
|
||||
**Help Fellow WordPressers by Writing a Review ❤️**
|
||||
|
||||
If you like Email Subscribers, please leave a [5 stars](https://wordpress.org/support/view/plugin-reviews/email-subscribers?filter=5#postform) review on WordPress. That helps fellow website owners access Email Subscribers easily and benefit from it!
|
||||
If you like Email Subscribers, please leave us a [⭐⭐⭐⭐⭐](https://wordpress.org/support/view/plugin-reviews/email-subscribers?filter=5#new-post) review and also spread the word about it via Facebook and Twitter. That helps fellow website owners assess Email Subscribers easily and benefit from it!
|
||||
|
||||
**Some of our other free plugins on WordPress.org**
|
||||
|
||||
@@ -136,59 +156,59 @@ Option 2:
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
|
||||
= 1. How to install and activate Email Subscribers on multisite installation? =
|
||||
= 1. How to install and activate Email Subscribers on multisite installation =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-install-and-activate-plugin-single-multisite/).
|
||||
|
||||
= 2. How to add subscription box to your website? =
|
||||
= 2. How to add a subscription box to your website =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-add-subscription-box-to-website/).
|
||||
|
||||
= 3. How to modify the existing emails like emails like Confirmation, Welcome, Admin emails and Cron Settings and Assign User Roles? =
|
||||
= 3. How to modify the existing emails like Confirmation, Welcome, Admin emails and Cron Settings and Assign User Roles =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-general-plugin-settings/).
|
||||
|
||||
= 4. How does Sync work? =
|
||||
= 4. How does Sync work =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-does-sync-work/).
|
||||
|
||||
= 5. How to Import and export email address? =
|
||||
= 5. How to Import and export email address =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-import-or-export-email-address-to-subscriber-list/).
|
||||
|
||||
= 6. How to change/update/translate any strings from the plugin? =
|
||||
= 6. How to change/update/translate any strings from the plugin =
|
||||
|
||||
Refer steps from [here](https://www.icegram.com/documentation/es-how-to-change-update-translate-any-texts-from-email-subscribers/).
|
||||
|
||||
= 7. How to add unsubscribe link in emails? =
|
||||
= 7. How to add unsubscribe link in emails =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-add-unsubscribe-link-in-emails/).
|
||||
|
||||
= 8. How to Create and Send Newsletter Emails? =
|
||||
= 8. How to Create and Send Newsletter Emails =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-create-and-send-newsletter-emails/).
|
||||
|
||||
= 9. What are the available keywords in the Newsletters? =
|
||||
= 9. What are the available keywords in the Newsletters =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-what-are-the-available-keywords-in-the-newsletters/).
|
||||
|
||||
= 10. How to Create and Send Post Notification Emails when new posts are published? =
|
||||
= 10. How to Create and Send Post Notification Emails when new posts are published =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-create-and-send-post-notification-emails-when-new-posts-are-published/).
|
||||
|
||||
= 11. What are the available keywords in the Post Notifications? =
|
||||
= 11. What are the available keywords in the Post Notifications =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-what-are-the-available-keywords-in-the-post-notifications/).
|
||||
|
||||
= 12. How to send a sample new post notification email to testgroup/myself? =
|
||||
= 12. How to send a sample new post notification email to test group/me =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-send-a-sample-new-post-notification-email-to-testgroup-myself/).
|
||||
|
||||
= 13. How to check sent emails reports? =
|
||||
= 13. How to check sent emails reports =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-check-sent-emails/).
|
||||
|
||||
= 14. How to Add/Update Existing Subscribers Group & Status? =
|
||||
= 14. How to Add/Update Existing Subscribers Group & Status =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-add-update-existing-subscribers-group/).
|
||||
|
||||
@@ -196,35 +216,35 @@ Refer [here](https://www.icegram.com/documentation/es-how-to-add-update-existing
|
||||
|
||||
Check steps from [here](https://www.icegram.com/documentation/es-subscribers-are-not-receiving-emails/).
|
||||
|
||||
= 16. How to show subscribe form inside a popup? =
|
||||
= 16. How to show subscribe form inside a popup =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-show-subscribe-form-inside-a-popup/).
|
||||
|
||||
= 17. How to use Rainmaker’s form in Email Subscribers? =
|
||||
= 17. How to use Rainmaker’s form in Email Subscribers =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-use-rainmakers-form-in-email-subscribers/).
|
||||
|
||||
= 18. How to Redirect Subscribers to a new page/url after successful sign up? =
|
||||
= 18. How to Redirect Subscribers to a new page/URL after successful sign up =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-redirect-subscribers-to-a-new-page-url-after-successful-sign-up/).
|
||||
|
||||
= 19. How to add captcha in Subscribe form of Email Subscribers? =
|
||||
= 19. How to add captcha in Subscribe form of Email Subscribers =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-add-captcha-in-subscribe-form-of-email-subscribers/).
|
||||
|
||||
= 20. How to Schedule Cron Emails/auto emails? =
|
||||
= 20. How to Schedule Cron Emails/auto emails =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-schedule-cron-emails/).
|
||||
|
||||
= 21. How to Schedule Cron Emails in cPanel? =
|
||||
= 21. How to Schedule Cron Emails in cPanel =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-schedule-cron-emails-in-cpanel/).
|
||||
|
||||
= 22. How to Schedule Cron Emails in Parallels Plesk? =
|
||||
= 22. How to Schedule Cron Emails in Parallels Plesk =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-how-to-schedule-cron-emails-in-parallels-plesk/).
|
||||
|
||||
= 23. What to do if Hosting doesn’t support Cron Jobs? =
|
||||
= 23. What to do if Hosting doesn’t support Cron Jobs =
|
||||
|
||||
Refer [here](https://www.icegram.com/documentation/es-what-to-do-if-hosting-doesnt-support-cron-jobs/).
|
||||
|
||||
@@ -254,7 +274,7 @@ Refer [here](https://www.icegram.com/documentation/es-faq/).
|
||||
|
||||
8. Forms
|
||||
|
||||
9. Create New Form
|
||||
9. Create a New Form
|
||||
|
||||
10. Workflows
|
||||
|
||||
@@ -281,6 +301,20 @@ Refer [here](https://www.icegram.com/documentation/es-faq/).
|
||||
|
||||
== Changelog ==
|
||||
|
||||
**4.4.10 (29.06.2020)**
|
||||
|
||||
* New: Added {{POSTCATS}} keyword for Post Notification
|
||||
* New: Added option to select multiple lists while sending Broadcast, creating Post Notification and Post Digest [PRO]
|
||||
* New: Added new email templates for Broadcast, Post Notifications & Post Digst [PRO]
|
||||
|
||||
**4.4.9 (24.06.2020)**
|
||||
|
||||
* Update: Redirect to forms list page after creating a form
|
||||
* Update: YouTube video embedding issue
|
||||
* Update: Action Scheduler Library to 3.1.6
|
||||
* Fix: {{POSTLINK-ONLY}} keyword issue
|
||||
* Fix: Post Digest issue [PRO]
|
||||
|
||||
**4.4.8 (22.05.2020)**
|
||||
|
||||
* New: Filter Campaigns by type
|
||||
@@ -306,16 +340,16 @@ Refer [here](https://www.icegram.com/documentation/es-faq/).
|
||||
* Update: Improved Import/ Export feature
|
||||
* Update: Improved manage lists UI
|
||||
* Update: Improved Export contacts UI
|
||||
* Update: Show date based on format set in WordPress settings
|
||||
* Update: Show date based on the format set in WordPress settings
|
||||
* Fix: Import contact issue
|
||||
* Fix: "Continu Reading" link doesn't work in Post Notifications
|
||||
* Fix: Audience lists stick to bottom
|
||||
* Fix: "Continue Reading" link doesn't work in Post Notifications
|
||||
* Fix: Audience lists stick to the bottom
|
||||
|
||||
**4.4.5 (15.04.2020)**
|
||||
|
||||
* Update: Improved Import & Export contacts UI
|
||||
* Fix: Importing contacts progress stays at 0%
|
||||
* Fix: Test email send acknowledgement was not showing
|
||||
* Fix: Test email send acknowledgment was not showing
|
||||
|
||||
**4.4.4 (10.04.2020)**
|
||||
|
||||
@@ -336,9 +370,9 @@ Refer [here](https://www.icegram.com/documentation/es-faq/).
|
||||
* Update: Improved Active Contacts Growth based on cumulative contacts
|
||||
* Fix: Migration issue
|
||||
* Fix: Campaign was sent while previewing campaign
|
||||
* Fix: Empty campaign body if any error occur
|
||||
* Fix: Empty campaign body if any error occurred
|
||||
* Fix: Optimize images
|
||||
* Fix: Campaigns list stick to bottom of the page
|
||||
* Fix: Campaigns list stick to the bottom of the page
|
||||
* Fix: PHP Warning during installation on multisite
|
||||
|
||||
**4.4.1.1 (12.03.2020)**
|
||||
|
||||
@@ -8,6 +8,7 @@ use luckywp\tableOfContents\core\front\BaseFront;
|
||||
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
||||
use luckywp\tableOfContents\plugin\dom\Dom;
|
||||
use luckywp\tableOfContents\plugin\PostSettings;
|
||||
use luckywp\tableOfContents\plugin\Shortcode;
|
||||
|
||||
class Front extends BaseFront
|
||||
{
|
||||
@@ -99,7 +100,7 @@ class Front extends BaseFront
|
||||
{
|
||||
global $post;
|
||||
|
||||
if (!is_single($post) && !is_page($post)) {
|
||||
if (!Shortcode::allow()) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Plugin Name: LuckyWP Table of Contents
|
||||
Plugin URI: https://theluckywp.com/product/table-of-contents/
|
||||
Description: Creates a table of contents for your posts/pages. Works automatically or manually (via shortcode, Gutenberg block or widget).
|
||||
Version: 2.1.2
|
||||
Version: 2.1.3
|
||||
Author: LuckyWP
|
||||
Author URI: https://theluckywp.com/
|
||||
Text Domain: luckywp-table-of-contents
|
||||
@@ -47,6 +47,6 @@ $lwptocAutoloader->register();
|
||||
$lwptocAutoloader->addNamespace('luckywp\tableOfContents', __DIR__);
|
||||
|
||||
$config = require(__DIR__ . '/config/plugin.php');
|
||||
(new \luckywp\tableOfContents\plugin\Plugin($config))->run('2.1.2', __FILE__, 'lwptoc_');
|
||||
(new \luckywp\tableOfContents\plugin\Plugin($config))->run('2.1.3', __FILE__, 'lwptoc_');
|
||||
|
||||
require_once __DIR__ . '/functions.php';
|
||||
|
||||
@@ -61,8 +61,7 @@ class Shortcode extends BaseObject
|
||||
global $post;
|
||||
if ($this->isDiactivated() ||
|
||||
($this->theContentApplied && $this->headingsCache === null) ||
|
||||
(!is_single($post) && !is_page($post)) ||
|
||||
!$this->isMainQueryPost()
|
||||
!static::allow()
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
@@ -220,7 +219,7 @@ class Shortcode extends BaseObject
|
||||
{
|
||||
global $post;
|
||||
|
||||
if (!$this->isMainQueryPost()) {
|
||||
if (!static::allow()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -244,11 +243,17 @@ class Shortcode extends BaseObject
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isMainQueryPost()
|
||||
public static function allow()
|
||||
{
|
||||
global $post, $wp_query;
|
||||
return ($post instanceof WP_Post) &&
|
||||
$post->ID == $wp_query->get_queried_object_id();
|
||||
if (!($post instanceof WP_Post)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$allow = (is_single($post->ID) || is_page($post->ID)) && // Это страница записи
|
||||
($post->ID == $wp_query->get_queried_object_id()); // Это главный запрос на странице
|
||||
|
||||
return apply_filters('lwptoc_allow', $allow, $post);
|
||||
}
|
||||
|
||||
private $_tag;
|
||||
|
||||
@@ -4,7 +4,7 @@ Donate link: https://theluckywp.com/product/table-of-contents/
|
||||
Tags: table of contents, toc, navigation, links, seo
|
||||
Requires at least: 4.7
|
||||
Tested up to: 5.4
|
||||
Stable tag: 2.1.2
|
||||
Stable tag: 2.1.3
|
||||
Requires PHP: 5.6.20
|
||||
License: GPLv2 or later
|
||||
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
@@ -160,6 +160,9 @@ For non-English websites it is recommended to enable the `Intl` PHP extension.
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 2.1.3 — 2020-06-07 =
|
||||
+ Added hook filter `lwptoc_allow`.
|
||||
|
||||
= 2.1.2 — 2020-05-08 =
|
||||
+ Added hook filter `lwptoc_title_tag`.
|
||||
|
||||
|
||||
@@ -1,77 +1,83 @@
|
||||
.tc-box {
|
||||
padding:20px 0;
|
||||
border-top:1px solid #dfdfdf;
|
||||
}
|
||||
.tc-warning, .tc-required, .tc-fail {
|
||||
color:red;
|
||||
}
|
||||
.tc-recommended, .tc-pass {
|
||||
color: green;
|
||||
}
|
||||
.tc-info {
|
||||
color: blue;
|
||||
}
|
||||
.tc-grep span {
|
||||
background: yellow;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.tc-success {
|
||||
margin:0 20px 20px 20px;
|
||||
background:#e6ffe2;
|
||||
border:1px solid #d1eecc;
|
||||
}
|
||||
form {
|
||||
margin:20px auto;
|
||||
}
|
||||
.theme-check {
|
||||
margin:20px auto;
|
||||
border:1px solid #dfdfdf;
|
||||
-moz-border-radius:5px;
|
||||
-khtml-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
border-radius:5px;
|
||||
}
|
||||
.theme-check h2 {
|
||||
margin:0 0 20px 0;
|
||||
padding:0 20px;
|
||||
background:#dfdfdf url("gray-grad.png") repeat-x left top;
|
||||
font-size:20px;
|
||||
border-bottom:1px solid #ccc;
|
||||
}
|
||||
.theme-check p {
|
||||
padding:5px 20px;
|
||||
}
|
||||
.theme-check form {
|
||||
margin-left:20px;
|
||||
}
|
||||
.theme-check ul {
|
||||
margin-left:20px;
|
||||
}
|
||||
.theme-check h3 {
|
||||
margin:0 0 10px 20px;
|
||||
padding:0;
|
||||
}
|
||||
.theme-check ul {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.theme-info {
|
||||
padding:10px;
|
||||
border:1px solid #dfdfdf;
|
||||
margin:10px 20px 0 20px;
|
||||
}
|
||||
.theme-info p {
|
||||
padding:0;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.theme-info label {
|
||||
float:left;
|
||||
width:100px;
|
||||
font-weight:bold;
|
||||
display:block;
|
||||
}
|
||||
.theme-info span.info {
|
||||
margin-left:100px;
|
||||
display:block;
|
||||
}
|
||||
.tc-box {
|
||||
padding:20px 0;
|
||||
border-top:1px solid #dfdfdf;
|
||||
}
|
||||
.tc-required, .tc-fail {
|
||||
color:red;
|
||||
}
|
||||
.tc-warning {
|
||||
color: orange;
|
||||
}
|
||||
.tc-recommended, .tc-pass {
|
||||
color: green;
|
||||
}
|
||||
.tc-info {
|
||||
color: blue;
|
||||
}
|
||||
.tc-grep span {
|
||||
background: yellow;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.tc-success {
|
||||
margin:0 20px 20px 20px;
|
||||
background:#e6ffe2;
|
||||
border:1px solid #d1eecc;
|
||||
}
|
||||
form {
|
||||
margin: 1.5em auto;
|
||||
}
|
||||
.theme-check {
|
||||
margin: 1em auto;
|
||||
border:1px solid #dfdfdf;
|
||||
-moz-border-radius:5px;
|
||||
-khtml-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
border-radius:5px;
|
||||
}
|
||||
.theme-check h2 {
|
||||
margin: 0 0 1em 0;
|
||||
padding: 1em;
|
||||
background:#dfdfdf url("gray-grad.png") repeat-x left top;
|
||||
font-size:20px;
|
||||
border-bottom:1px solid #ccc;
|
||||
}
|
||||
.theme-check p {
|
||||
padding:5px 20px;
|
||||
}
|
||||
.theme-check form {
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
.theme-check ul {
|
||||
margin-left:20px;
|
||||
}
|
||||
.theme-check h3 {
|
||||
margin:0 0 10px 20px;
|
||||
padding:0;
|
||||
}
|
||||
.theme-check ul {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.theme-info {
|
||||
padding: 1em;
|
||||
border:1px solid #dfdfdf;
|
||||
margin: 1em 1em 0 1em;
|
||||
}
|
||||
.theme-info p {
|
||||
padding:0;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.theme-info label {
|
||||
float:left;
|
||||
width:100px;
|
||||
font-weight:bold;
|
||||
display:block;
|
||||
}
|
||||
.theme-info span.info {
|
||||
margin-left:100px;
|
||||
display:block;
|
||||
}
|
||||
.theme-check input[name="s_info"] {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
@@ -1,3 +1,45 @@
|
||||
= 20200612.1 =
|
||||
* Release to WordPress.org plugins directory
|
||||
|
||||
= 20200611.1 =
|
||||
* Added escaping checks
|
||||
* Added tested up to and Requires PHP checks for the style.css
|
||||
* Added register_block_type to plugin territory check
|
||||
* Check for remove_action wp_head
|
||||
* Changed some checks from errors to warnings
|
||||
* Updated error messages
|
||||
* Updated regex for non printable characters
|
||||
* Fixed parse errors
|
||||
* Removed unused functions
|
||||
|
||||
= 20200504.1 =
|
||||
* Contributor and URI adjustments
|
||||
* site_url checks
|
||||
* smarter nav menu and favicon checks
|
||||
* additional filename blacklist checks
|
||||
* developer files added to github (phpcs, composer, attributes, gitignore, etc)
|
||||
* improvements to existing checks, move some warnings to required to reflect updated guidelines
|
||||
* check for themes being copies of underscores
|
||||
* check for non-gpl-compatible sites used for images
|
||||
* Add warnings for demo content
|
||||
* Update links in messages to point to new development and documentation locations
|
||||
* disallow dashboard widgets in themes
|
||||
|
||||
= 20190801.1 =
|
||||
* Fix missing nonce and nonce check on admin page. props Steven Stern for reporting the issue to the plugins team. Though this is technically a CSRF, there is no vulnerability arising from it, as the only thing that could be done with the form is to scan a theme.
|
||||
|
||||
= 20190208.1 =
|
||||
* Add new styles for the block editor. See https://meta.trac.wordpress.org/ticket/3921
|
||||
|
||||
= 20160523.1 =
|
||||
* Fix for theme-names with dashes in them
|
||||
* Comments stripping changes
|
||||
* Many changes by the theme review team and others. See Github for full change list.
|
||||
|
||||
= 20151211.1 =
|
||||
* Full sync with Github and all the changes that have happened there.
|
||||
* Release for 4.4 deprecated functions.
|
||||
|
||||
= 20140929.1 =
|
||||
* Added new checks and updates from Frank Klein at Automattic. Thanks Frank!
|
||||
* Updated deprecated function listings
|
||||
@@ -48,11 +90,11 @@
|
||||
* Add check for wp_link_pages() + fix eval() check
|
||||
|
||||
= 20110219.2 =
|
||||
* Merged new UI props Gua Bob [1](http://guabob.com/)
|
||||
* Merged new UI props Gua Bob [1](http://guabob.com/)
|
||||
* Last tested theme is always pre-selected in the themes list.
|
||||
* Fixed php error in admin_menu.php
|
||||
|
||||
= 20110219.1 =
|
||||
= 20110219.1 =
|
||||
* See [commit log](https://github.com/Pross/theme-check/commits/) for changes.
|
||||
|
||||
= 20110201.2 =
|
||||
|
||||
@@ -124,22 +124,6 @@ function tc_preg( $preg, $file ) {
|
||||
return str_replace( $error, '<span class="tc-grep">' . $error . '</span>', $bad_lines );
|
||||
}
|
||||
|
||||
function tc_strxchr($haystack, $needle, $l_inclusive = 0, $r_inclusive = 0){
|
||||
if(strrpos($haystack, $needle)){
|
||||
//Everything before last $needle in $haystack.
|
||||
$left = substr($haystack, 0, strrpos($haystack, $needle) + $l_inclusive);
|
||||
//Switch value of $r_inclusive from 0 to 1 and viceversa.
|
||||
$r_inclusive = ($r_inclusive == 0) ? 1 : 0;
|
||||
//Everything after last $needle in $haystack.
|
||||
$right = substr(strrchr($haystack, $needle), $r_inclusive);
|
||||
//Return $left and $right into an array.
|
||||
return array($left, $right);
|
||||
} else {
|
||||
if(strrchr($haystack, $needle)) return array('', substr(strrchr($haystack, $needle), $r_inclusive));
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
|
||||
function tc_filename( $file ) {
|
||||
$filename = ( preg_match( '/themes\/[a-z0-9-]*\/(.*)/', $file, $out ) ) ? $out[1] : basename( $file );
|
||||
return $filename;
|
||||
@@ -170,37 +154,6 @@ function listdir( $dir ) {
|
||||
return $files;
|
||||
}
|
||||
|
||||
function old_listdir( $start_dir='.' ) {
|
||||
$files = array();
|
||||
if ( is_dir( $start_dir ) ) {
|
||||
$fh = opendir( $start_dir );
|
||||
while ( ( $file = readdir( $fh ) ) !== false ) {
|
||||
# loop through the files, skipping . and .., and recursing if necessary
|
||||
if ( strcmp( $file, '.' )==0 || strcmp( $file, '..' )==0 ) continue;
|
||||
$filepath = $start_dir . '/' . $file;
|
||||
if ( is_dir( $filepath ) )
|
||||
$files = array_merge( $files, listdir( $filepath ) );
|
||||
else
|
||||
array_push( $files, $filepath );
|
||||
}
|
||||
closedir( $fh );
|
||||
|
||||
} else {
|
||||
|
||||
# false if the function was called with an invalid non-directory argument
|
||||
$files = false;
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
function tc_print_r( $data ) {
|
||||
$out = "\n<pre class='html-print-r'";
|
||||
$out .= " style='border: 1px solid #ccc; padding: 7px;'>\n";
|
||||
$out .= esc_html( print_r( $data, TRUE ) );
|
||||
$out .= "\n</pre>\n";
|
||||
echo $out;
|
||||
}
|
||||
|
||||
function get_theme_data_from_contents( $theme_data ) {
|
||||
$themes_allowed_tags = array(
|
||||
'a' => array(
|
||||
|
||||
@@ -10,8 +10,8 @@ class AdminMenu implements themecheck {
|
||||
//check for levels deprecated in 2.0 in creating menus.
|
||||
|
||||
$checks = array(
|
||||
'/([^_](add_(admin|submenu|menu|dashboard|posts|media|links|pages|comments|theme|plugins|users|management|options)_page)\s?\([^,]*,[^,]*,\s[\'|"]?(level_[0-9]|[0-9])[^;|\r|\r\n]*)/' => __( 'User levels were deprecated in <strong>2.0</strong>. Please see <a href="https://codex.wordpress.org/Roles_and_Capabilities">Roles_and_Capabilities</a>', 'theme-check' ),
|
||||
'/[^a-z0-9](current_user_can\s?\(\s?[\'\"]level_[0-9][\'\"]\s?\))[^\r|\r\n]*/' => __( 'User levels were deprecated in <strong>2.0</strong>. Please see <a href="https://codex.wordpress.org/Roles_and_Capabilities">Roles_and_Capabilities</a>', 'theme-check' )
|
||||
'/([^_](add_(admin|submenu|menu|dashboard|posts|media|links|pages|comments|theme|plugins|users|management|options)_page)\s?\([^,]*,[^,]*,\s[\'|"]?(level_[0-9]|[0-9])[^;|\r|\r\n]*)/' => __( 'User levels were deprecated in <strong>2.0</strong>. Please see <a href="https://wordpress.org/support/article/roles-and-capabilities/">Roles_and_Capabilities</a>', 'theme-check' ),
|
||||
'/[^a-z0-9](current_user_can\s?\(\s?[\'\"]level_[0-9][\'\"]\s?\))[^\r|\r\n]*/' => __( 'User levels were deprecated in <strong>2.0</strong>. Please see <a href="https://wordpress.org/support/article/roles-and-capabilities/">Roles_and_Capabilities</a>', 'theme-check' )
|
||||
);
|
||||
|
||||
foreach ( $php_files as $php_key => $phpfile ) {
|
||||
|
||||
@@ -1,41 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* This checks, if the admin bar gets hidden by the theme
|
||||
* This checks if the admin bar gets hidden by the theme.
|
||||
**/
|
||||
class NoHiddenAdminBar implements themecheck {
|
||||
protected $error = array();
|
||||
|
||||
function check( $php_files, $css_files, $other_files ) {
|
||||
$ret = true;
|
||||
checkcount();
|
||||
$php_regex = "/(add_filter(\s*)\((\s*)(\"|')show_admin_bar(\"|')(\s*)(.*))|(([^\S])show_admin_bar(\s*)\((.*))/";
|
||||
$css_regex = "/(#wpadminbar)/";
|
||||
function check( $php_files, $css_files, $other_files ) {
|
||||
$ret = true;
|
||||
|
||||
//Check php files for filter show_admin_bar and show_admin_bar()
|
||||
foreach ( $php_files as $file_path => $file_content ) {
|
||||
$php_regex = "/(add_filter(\s*)\((\s*)(\"|')show_admin_bar(\"|')(\s*)(.*))|(([^\S])show_admin_bar(\s*)\((.*))/";
|
||||
$css_regex = "/(#wpadminbar)/";
|
||||
|
||||
$filename = tc_filename( $file_path );
|
||||
checkcount();
|
||||
// Check php files for filter show_admin_bar, show_admin_bar_front, and show_admin_bar().
|
||||
foreach ( $php_files as $file_path => $file_content ) {
|
||||
|
||||
if ( preg_match( $php_regex, $file_content, $matches ) ) {
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( 'You are not allowed to hide the admin bar.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>');
|
||||
$ret = false;
|
||||
}
|
||||
$filename = tc_filename( $file_path );
|
||||
|
||||
if ( preg_match( $php_regex, $file_content, $matches ) ) {
|
||||
|
||||
$error = '/show_admin_bar/';
|
||||
$grep = tc_preg( $error, $file_path );
|
||||
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . __( '%1$s Themes are not allowed to hide the admin bar. This warning must be manually checked.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>' ) . $grep;
|
||||
}
|
||||
}
|
||||
|
||||
checkcount();
|
||||
// Check CSS Files for #wpadminbar.
|
||||
foreach ( $css_files as $file_path => $file_content ) {
|
||||
|
||||
$filename = tc_filename( $file_path );
|
||||
$error = '/#wpadminbar/';
|
||||
// Don't print minified files.
|
||||
if ( strpos( $filename, '.min.' ) === false ) {
|
||||
$grep = tc_preg( $error, $file_path );
|
||||
} else {
|
||||
$grep = '';
|
||||
}
|
||||
|
||||
//Check CSS Files for #wpadminbar
|
||||
foreach ( $css_files as $file_path => $file_content ) {
|
||||
|
||||
$filename = tc_filename( $file_path );
|
||||
|
||||
if ( preg_match( $css_regex, $file_content, $matches ) ) {
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check').'</span>: ' . __( 'The theme is using `#wpadminbar`. Hiding the admin bar is not allowed.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>');
|
||||
}
|
||||
if ( preg_match( $css_regex, $file_content, $matches ) ) {
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . __( 'The theme is using `#wpadminbar` in %1$s. Hiding the admin bar is not allowed. This warning must be manually checked.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>' ) . $grep;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
$themechecks[] = new NoHiddenAdminBar;
|
||||
|
||||
$themechecks[] = new NoHiddenAdminBar();
|
||||
|
||||
@@ -26,7 +26,7 @@ class Bad_Checks implements themecheck {
|
||||
$filename = tc_filename( $php_key );
|
||||
$error = ltrim( trim( $matches[0], '(' ) );
|
||||
$grep = tc_grep( $error, $php_key );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-warning">'. __( 'WARNING', 'theme-check' ) . '</span>: ' . __( 'Found %1$s in the file %2$s. %3$s. %4$s', 'theme-check' ), '<strong>' . $error . '</strong>', '<strong>' . $filename . '</strong>', $check, $grep );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-required">'. __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found %1$s in the file %2$s. %3$s. %4$s', 'theme-check' ), '<strong>' . $error . '</strong>', '<strong>' . $filename . '</strong>', $check, $grep );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ class Bad_Checks implements themecheck {
|
||||
$filename = tc_filename( $php_key );
|
||||
$error = ltrim( rtrim( $matches[0],'(' ) );
|
||||
$grep = tc_grep( $error, $php_key );
|
||||
$this->error[] = sprintf(__('<span class="tc-lead tc-warning">WARNING</span>: Found <strong>%1$s</strong> in the file <strong>%2$s</strong>. %3$s.%4$s', 'theme-check'), $error, $filename, $check, $grep);
|
||||
$this->error[] = sprintf(__('<span class="tc-lead tc-required">REQUIRED</span>: Found <strong>%1$s</strong> in the file <strong>%2$s</strong>. %3$s.%4$s', 'theme-check'), $error, $filename, $check, $grep);
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,17 +12,18 @@ class Basic_Checks implements themecheck {
|
||||
|
||||
$checks = array(
|
||||
'DOCTYPE' => __( 'See: <a href="https://codex.wordpress.org/HTML_to_XHTML">https://codex.wordpress.org/HTML_to_XHTML</a><pre><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br />"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"?></pre>', 'theme-check' ),
|
||||
'wp_footer\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/wp_footer">wp_footer</a><pre> <?php wp_footer(); ?></pre>', 'theme-check' ),
|
||||
'wp_head\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/wp_head">wp_head</a><pre> <?php wp_head(); ?></pre>', 'theme-check' ),
|
||||
'language_attributes' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/language_attributes">language_attributes</a><pre><html <?php language_attributes(); ?></pre>', 'theme-check' ),
|
||||
'(wp_body_open\s*\()|(do_action\s*\(\s*["\']wp_body_open)' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_body_open/">wp_body_open</a><pre> <?php wp_body_open(); ?></pre>', 'theme-check' ),
|
||||
'wp_footer\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_footer/">wp_footer</a><pre> <?php wp_footer(); ?></pre>', 'theme-check' ),
|
||||
'wp_head\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_head/">wp_head</a><pre> <?php wp_head(); ?></pre>', 'theme-check' ),
|
||||
'language_attributes' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/language_attributes/">language_attributes</a><pre><html <?php language_attributes(); ?></pre>', 'theme-check' ),
|
||||
'charset' => __( 'There must be a charset defined in the Content-Type or the meta charset tag in the head.', 'theme-check' ),
|
||||
'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/add_theme_support">add_theme_support</a><pre> <?php add_theme_support( $feature ); ?></pre>', 'theme-check' ),
|
||||
'comments_template\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/comments_template">comments_template</a><pre> <?php comments_template( $file, $separate_comments ); ?></pre>', 'theme-check' ),
|
||||
'wp_list_comments\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/wp_list_comments">wp_list_comments</a><pre> <?php wp_list_comments( $args ); ?></pre>', 'theme-check' ),
|
||||
'comment_form\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/comment_form">comment_form</a><pre> <?php comment_form(); ?></pre>', 'theme-check' ),
|
||||
'body_class\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/body_class">body_class</a><pre> <?php body_class( $class ); ?></pre>', 'theme-check' ),
|
||||
'wp_link_pages\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/wp_link_pages">wp_link_pages</a><pre> <?php wp_link_pages( $args ); ?></pre>', 'theme-check' ),
|
||||
'post_class\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/post_class">post_class</a><pre> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>></pre>', 'theme-check' )
|
||||
'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/add_theme_support/">add_theme_support</a><pre> <?php add_theme_support( $feature ); ?></pre>', 'theme-check' ),
|
||||
'comments_template\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/comments_template/">comments_template</a><pre> <?php comments_template( $file, $separate_comments ); ?></pre>', 'theme-check' ),
|
||||
'wp_list_comments\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_list_comments/">wp_list_comments</a><pre> <?php wp_list_comments( $args ); ?></pre>', 'theme-check' ),
|
||||
'comment_form\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/comment_form/">comment_form</a><pre> <?php comment_form(); ?></pre>', 'theme-check' ),
|
||||
'body_class\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/body_class/">body_class</a><pre> <?php body_class( $class ); ?></pre>', 'theme-check' ),
|
||||
'wp_link_pages\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_link_pages/">wp_link_pages</a><pre> <?php wp_link_pages( $args ); ?></pre>', 'theme-check' ),
|
||||
'post_class\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/post_class/">post_class</a><pre> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>></pre>', 'theme-check' )
|
||||
);
|
||||
|
||||
foreach ($checks as $key => $check) {
|
||||
@@ -30,6 +31,7 @@ class Basic_Checks implements themecheck {
|
||||
if ( !preg_match( '/' . $key . '/i', $php ) ) {
|
||||
if ( $key === 'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' ) $key = __( 'add_theme_support( \'automatic-feed-links\' )', 'theme-check');
|
||||
if ( $key === 'body_class\s*\(' ) $key = __( 'body_class call in body tag', 'theme-check');
|
||||
if ( $key === '(wp_body_open\s*\()|(do_action\s*\(\s*["\']wp_body_open)' ) $key = __( 'wp_body_open action or function call at the very top of the body just after the opening body tag', 'theme-check');
|
||||
$key = str_replace( '\s*\(', '', $key );
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Could not find %1$s. %2$s', 'theme-check' ), '<strong>' . $key . '</strong>', $check );
|
||||
$ret = false;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Checks for resources being loaded from CDNs.
|
||||
*/
|
||||
@@ -17,22 +16,24 @@ class CDNCheck implements themecheck {
|
||||
checkcount();
|
||||
|
||||
$cdn_list = array(
|
||||
'bootstrap-maxcdn' => 'maxcdn.bootstrapcdn.com/bootstrap',
|
||||
'bootstrap-netdna' => 'netdna.bootstrapcdn.com/bootstrap',
|
||||
'bootswatch-maxcdn' => 'maxcdn.bootstrapcdn.com/bootswatch',
|
||||
'bootswatch-netdna' => 'netdna.bootstrapcdn.com/bootswatch',
|
||||
'font-awesome-maxcdn' => 'maxcdn.bootstrapcdn.com/font-awesome',
|
||||
'font-awesome-netdna' => 'netdna.bootstrapcdn.com/font-awesome',
|
||||
'html5shiv-google' => 'html5shiv.googlecode.com/svn/trunk/html5.js',
|
||||
'html5shiv-maxcdn' => 'oss.maxcdn.com/libs/html5shiv',
|
||||
'bootstrap-maxcdn' => 'maxcdn.bootstrapcdn.com',
|
||||
'bootstrap-netdna' => 'netdna.bootstrapcdn.com',
|
||||
'bootstrap-stackpath' => 'stackpath.bootstrapcdn.com',
|
||||
'fontawesome' => 'kit.fontawesome.com',
|
||||
'googlecode' => 'googlecode.com/svn/',
|
||||
'oss.maxcdn' => 'oss.maxcdn.com',
|
||||
'jquery' => 'code.jquery.com/jquery-',
|
||||
'respond-js' => 'oss.maxcdn.com/libs/respond.js',
|
||||
'aspnetcdn' => 'aspnetcdn.com',
|
||||
'cloudflare' => 'cloudflare.com',
|
||||
'keycdn' => 'keycdn.com',
|
||||
'pxgcdn' => 'pxgcdn.com',
|
||||
'vimeocdn' => 'vimeocdn.com', //usually in JS files
|
||||
);
|
||||
|
||||
foreach( $cdn_list as $cdn_slug => $cdn_url ) {
|
||||
if ( false !== strpos( $all_code, $cdn_url ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-recommended">' . __('RECOMMENDED','theme-check') . '</span>: ' . sprintf( __( 'Found the URL of a CDN in the code: %s. You should not load CSS or Javascript resources from a CDN, please bundle them with the theme.', 'theme-check' ), '<code>' . esc_html( $cdn_url ) . '</code>' );
|
||||
//$ret = false;
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED','theme-check' ) . '</span>: ' . sprintf( __( 'Found the URL of a CDN in the code: %s. You should not load CSS or Javascript resources from a CDN, please bundle them with the theme.', 'theme-check' ), '<code>' . esc_html( $cdn_url ) . '</code>' );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
<?php
|
||||
class Comment_Reply implements themecheck {
|
||||
protected $error = array();
|
||||
|
||||
function check( $php_files, $css_files, $other_files) {
|
||||
|
||||
$php = implode( ' ', $php_files );
|
||||
$ret = true;
|
||||
|
||||
checkcount();
|
||||
|
||||
if ( ! preg_match( '/wp_enqueue_script\(\s?("|\')comment-reply("|\')/i', $php ) ) {
|
||||
if ( ! preg_match( '/comment-reply/', $php ) ) {
|
||||
$check = __( 'See: <a href="https://codex.wordpress.org/Migrating_Plugins_and_Themes_to_2.7/Enhanced_Comment_Display">Migrating Plugins and Themes to 2.7/Enhanced Comment Display</a><pre> <?php if ( is_singular() ) wp_enqueue_script( "comment-reply" ); ?></pre>', 'theme-check' );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued. %1$s', 'theme-check'), $check);
|
||||
$ret = false;
|
||||
} else {
|
||||
$this->error[] = '<span class="tc-lead tc-info">'.__('INFO','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued, however a reference to \'comment-reply\' was found. Make sure that the comment-reply script is being enqueued properly on singular pages.', 'theme-check');
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
|
||||
$themechecks[] = new Comment_Reply;
|
||||
<?php
|
||||
class Comment_Reply implements themecheck {
|
||||
protected $error = array();
|
||||
|
||||
function check( $php_files, $css_files, $other_files) {
|
||||
|
||||
$php = implode( ' ', $php_files );
|
||||
$ret = true;
|
||||
|
||||
checkcount();
|
||||
|
||||
if ( ! preg_match( '/wp_enqueue_script\(\s?("|\')comment-reply("|\')/i', $php ) ) {
|
||||
if ( ! preg_match( '/comment-reply/', $php ) ) {
|
||||
$check = __( 'See: <a href="https://codex.wordpress.org/Migrating_Plugins_and_Themes_to_2.7/Enhanced_Comment_Display">Migrating Plugins and Themes to 2.7/Enhanced Comment Display</a><pre> <?php if ( is_singular() ) wp_enqueue_script( "comment-reply" ); ?></pre>', 'theme-check' );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued. %1$s', 'theme-check'), $check);
|
||||
$ret = false;
|
||||
} else {
|
||||
$this->error[] = '<span class="tc-lead tc-info">'.__('INFO','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued, however a reference to \'comment-reply\' was found. Make sure that the comment-reply script is being enqueued properly on singular pages.', 'theme-check');
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
|
||||
$themechecks[] = new Comment_Reply;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Checks for the Customizer.
|
||||
*/
|
||||
@@ -7,7 +6,7 @@
|
||||
class CustomizerCheck implements themecheck {
|
||||
protected $error = array();
|
||||
|
||||
function check( $php_files, $css_files, $other_files) {
|
||||
function check( $php_files, $css_files, $other_files ) {
|
||||
|
||||
$ret = true;
|
||||
|
||||
@@ -17,18 +16,33 @@ class CustomizerCheck implements themecheck {
|
||||
* Check whether every Customizer setting has a sanitization callback set.
|
||||
*/
|
||||
foreach ( $php_files as $file_path => $file_content ) {
|
||||
// Get the arguments passed to the add_setting method
|
||||
// Get the arguments passed to the add_setting method.
|
||||
if ( preg_match_all( '/\$wp_customize->add_setting\(([^;]+)/', $file_content, $matches ) ) {
|
||||
// The full match is in [0], the match group in [1]
|
||||
// The full match is in [0], the match group in [1].
|
||||
foreach ( $matches[1] as $match ) {
|
||||
// Check if we have sanitize_callback or sanitize_js_callback
|
||||
// Check if we have sanitize_callback or sanitize_js_callback.
|
||||
if ( false === strpos( $match, 'sanitize_callback' ) && false === strpos( $match, 'sanitize_js_callback' ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __('REQUIRED','theme-check') . '</span>: ' . __( 'Found a Customizer setting that did not have a sanitization callback function. Every call to the <strong>add_setting()</strong> method needs to have a sanitization callback function passed.', 'theme-check' );
|
||||
/* Clean up our match to be able to present the results better. */
|
||||
$match = preg_split( '/,/', $match );
|
||||
$filename = tc_filename( $file_path );
|
||||
$grep = tc_preg( $match[0], $file_path );
|
||||
$grep = preg_split( '/,/', $grep );
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found a Customizer setting called %1$s in %2$s that did not have a sanitization callback function. ', 'theme-check' ) . __( 'Every call to the <strong>add_setting()</strong> method needs to have a sanitization callback function passed.', 'theme-check' ),
|
||||
'<strong>' . $match[0] . '</strong>',
|
||||
'<strong>' . $filename . '</strong>'
|
||||
) . $grep[0];
|
||||
$ret = false;
|
||||
} else {
|
||||
// There's a callback, check that no empty parameter is passed.
|
||||
if ( preg_match( '/[\'"](?:sanitize_callback|sanitize_js_callback)[\'"]\s*=>\s*[\'"]\s*[\'"]/', $match ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __('REQUIRED','theme-check') . '</span>: ' . __( 'Found a Customizer setting that had an empty value passed as sanitization callback. You need to pass a function name as sanitization callback.', 'theme-check' );
|
||||
$match = preg_split( '/,/', $match );
|
||||
$filename = tc_filename( $file_path );
|
||||
$grep = tc_preg( '/[\'"](?:sanitize_callback|sanitize_js_callback)[\'"]\s*=>\s*[\'"]\s*[\'"]/', $file_path );
|
||||
$grep = preg_split( '/,/', $grep );
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found a Customizer setting called %1$s in %2$s that had an empty value passed as sanitization callback. You need to pass a function name as sanitization callback.', 'theme-check' ),
|
||||
'<strong>' . $match[0] . '</strong>',
|
||||
'<strong>' . $filename . '</strong>'
|
||||
) . $grep[0];
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
@@ -41,4 +55,5 @@ class CustomizerCheck implements themecheck {
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
$themechecks[] = new CustomizerCheck;
|
||||
|
||||
$themechecks[] = new CustomizerCheck();
|
||||
|
||||
@@ -254,7 +254,13 @@ class Deprecated implements themecheck {
|
||||
array( 'prepreview_added_widget_instance' => 'customize_dynamic_setting_args', '4.2' ),
|
||||
array( 'remove_prepreview_filters' => 'customize_dynamic_setting_args', '4.2' ),
|
||||
|
||||
array( 'wp_htmledit_pre' => 'format_for_editor', '4.3' ),
|
||||
array( 'wp_richedit_pre' => 'format_for_editor', '4.3' ),
|
||||
array( 'preview_theme' => '', '4.3' ),
|
||||
|
||||
array( 'wp_get_http' => 'WP_Http', '4.4' ),
|
||||
array( 'post_permalink' => 'get_permalink', '4.4' ),
|
||||
array( 'force_ssl_login' => 'force_ssl_admin', '4.4' ),
|
||||
|
||||
array( 'is_comments_popup' => '', '4.5' ),
|
||||
array( 'add_object_page' => 'add_menu_page', '4.5' ),
|
||||
@@ -264,6 +270,38 @@ class Deprecated implements themecheck {
|
||||
array( 'popuplinks' => '', '4.5' ),
|
||||
array( 'get_currentuserinfo' => 'wp_get_current_user', '4.5' ),
|
||||
|
||||
array( 'wp_embed_handler_googlevideo' => '', '4.6' ),
|
||||
array( 'wp_get_sites' => 'get_sites', '4.6' ),
|
||||
array( 'post_form_autocomplete_off' => '', '4.6' ),
|
||||
|
||||
array( 'wp_die_handler' => '', '4.7' ),
|
||||
array( 'wp_redirect_status' => '', '4.7' ),
|
||||
array( 'customize_preview_override_404_status' => '', '4.7' ),
|
||||
array( 'customize_preview_base' => '', '4.7' ),
|
||||
array( 'customize_preview_html5' => '', '4.7' ),
|
||||
array( 'customize_preview_signature' => '', '4.7' ),
|
||||
array( 'remove_preview_signature' => '', '4.7' ),
|
||||
array( '_cmp_priority' => 'wp_list_sort', '4.7' ),
|
||||
array( 'reinit' => 'WP_Roles::for_site()', '4.7' ),
|
||||
array( 'get_paged_template' => '', '4.7' ),
|
||||
array( 'wp_kses_js_entities' => '', '4.7' ),
|
||||
array( 'wp_get_network' => 'get_network()', '4.7' ),
|
||||
array( '_sort_menus_by_orderby' => 'wp_list_sort', '4.7' ),
|
||||
|
||||
array( 'wp_dashboard_plugins_output' => '', '4.8' ),
|
||||
|
||||
array( '_init' => 'WP_Roles::for_site()', '4.9' ),
|
||||
array( '_init_caps' => 'WP_User::for_site()', '4.9' ),
|
||||
array( 'for_blog' => 'WP_User::for_site()', '4.9' ),
|
||||
array( 'get_shortcut_link' => '', '4.9' ),
|
||||
array( 'wp_ajax_press_this_save_post' => '', '4.9' ),
|
||||
array( 'wp_ajax_press_this_add_category' => '', '4.9' ),
|
||||
array( 'is_user_option_local' => '', '4.9' ),
|
||||
array( 'maybe_log_events_response' => '', '4.9' ),
|
||||
|
||||
array( 'insert_blog' => 'wp_insert_site()', '5.1' ),
|
||||
array( 'install_blog' => '', '5.1' ),
|
||||
|
||||
);
|
||||
foreach ( $php_files as $php_key => $phpfile ) {
|
||||
foreach ( $checks as $alt => $check ) {
|
||||
|
||||
@@ -17,8 +17,7 @@ class DeregisterCheck implements themecheck {
|
||||
$grep = tc_preg( $error, $file_path );
|
||||
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-warning">' . __('WARNING','theme-check') . '</span>: ' . __( 'Found wp_deregister_script in %1$s. Themes must not deregister core scripts.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>') . $grep;
|
||||
$ret = false;
|
||||
'<strong>' . $filename . '</strong>') . $grep;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
@@ -27,4 +26,4 @@ class DeregisterCheck implements themecheck {
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
$themechecks[] = new DeregisterCheck;
|
||||
$themechecks[] = new DeregisterCheck;
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Checks for favicons.
|
||||
* Note that the check for the icon file is in filenames.php.
|
||||
*/
|
||||
|
||||
class FaviconCheck implements themecheck {
|
||||
protected $error = array();
|
||||
@@ -6,16 +10,18 @@ class FaviconCheck implements themecheck {
|
||||
function check( $php_files, $css_files, $other_files ) {
|
||||
|
||||
$ret = true;
|
||||
|
||||
|
||||
checkcount();
|
||||
|
||||
foreach ( $php_files as $file_path => $file_content ) {
|
||||
|
||||
$filename = tc_filename( $file_path );
|
||||
|
||||
if ( preg_match( '/(<link rel=[\'"]icon[\'"])|(<link rel=[\'"]apple-touch-icon-precomposed[\'"])|(<meta name=[\'"]msapplication-TileImage[\'"])/', $file_content, $matches ) ) {
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-info">' . __('INFO','theme-check') . '</span>: ' . __( 'Possible Favicon found in %1$s. Favicons are handled by the Site Icon setting in the customizer since version 4.3.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>');
|
||||
if ( preg_match( '/(<link rel=[\'"]icon[\'"])|(<link rel=[\'"]shortcut icon[\'"])|(<link rel=[\'"]apple-touch-icon.*[\'"])|(<meta name=[\'"]msapplication-TileImage[\'"])/i', $file_content, $matches ) ) {
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Possible Favicon found in %1$s. Favicons are handled by the Site Icon setting in the customizer since version 4.3.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>'
|
||||
);
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
@@ -23,4 +29,5 @@ class FaviconCheck implements themecheck {
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
$themechecks[] = new FaviconCheck;
|
||||
|
||||
$themechecks[] = new FaviconCheck();
|
||||
|
||||
@@ -17,45 +17,63 @@ class File_Checks implements themecheck {
|
||||
foreach ( $css_files as $php_key => $phpfile ) {
|
||||
array_push( $filenames, strtolower( basename( $php_key ) ) );
|
||||
}
|
||||
$blacklist = array(
|
||||
'thumbs.db' => __( 'Windows thumbnail store', 'theme-check' ),
|
||||
'desktop.ini' => __( 'windows system file', 'theme-check' ),
|
||||
'project.properties' => __( 'NetBeans Project File', 'theme-check' ),
|
||||
'project.xml' => __( 'NetBeans Project File', 'theme-check' ),
|
||||
'\.kpf' => __( 'Komodo Project File', 'theme-check' ),
|
||||
'^\.+[a-zA-Z0-9]' => __( 'Hidden Files or Folders', 'theme-check' ),
|
||||
'php.ini' => __( 'PHP server settings file', 'theme-check' ),
|
||||
'dwsync.xml' => __( 'Dreamweaver project file', 'theme-check' ),
|
||||
'error_log' => __( 'PHP error log', 'theme-check' ),
|
||||
'web.config' => __( 'Server settings file', 'theme-check' ),
|
||||
'\.sql' => __( 'SQL dump file', 'theme-check' ),
|
||||
'__MACOSX' => __( 'OSX system file', 'theme-check' ),
|
||||
'\.lubith' => __( 'Lubith theme generator file', 'theme-check' ),
|
||||
);
|
||||
|
||||
$musthave = array( 'index.php', 'style.css' );
|
||||
$rechave = array( 'readme.txt' => __( 'Please see <a href="https://codex.wordpress.org/Theme_Review#Theme_Documentation">Theme_Documentation</a> for more information.', 'theme-check' ) );
|
||||
$whitelist = 'wpml-config.xml';
|
||||
|
||||
$blacklist = array(
|
||||
'thumbs\.db' => __( 'Windows thumbnail store', 'theme-check' ),
|
||||
'desktop\.ini' => __( 'windows system file', 'theme-check' ),
|
||||
'project\.properties' => __( 'NetBeans Project File', 'theme-check' ),
|
||||
'project\.xml' => __( 'NetBeans Project File', 'theme-check' ),
|
||||
'\.kpf' => __( 'Komodo Project File', 'theme-check' ),
|
||||
'^\.+[a-zA-Z0-9]' => __( 'Hidden Files or Folders', 'theme-check' ),
|
||||
'php\.ini' => __( 'PHP server settings file', 'theme-check' ),
|
||||
'dwsync\.xml' => __( 'Dreamweaver project file', 'theme-check' ),
|
||||
'error_log' => __( 'PHP error log', 'theme-check' ),
|
||||
'web\.config' => __( 'Server settings file', 'theme-check' ),
|
||||
'\.sql' => __( 'SQL dump file', 'theme-check' ),
|
||||
'__MACOSX' => __( 'OSX system file', 'theme-check' ),
|
||||
'\.lubith' => __( 'Lubith theme generator file', 'theme-check' ),
|
||||
'\.wie' => __( 'Widget import file', 'theme-check' ),
|
||||
'\.dat' => __( 'Customizer import file', 'theme-check' ),
|
||||
'phpcs\.xml\.dist' => __( 'PHPCS file', 'theme-check' ),
|
||||
'phpcs\.xml' => __( 'PHPCS file', 'theme-check' ),
|
||||
'\.xml' => __( 'XML file', 'theme-check' ),
|
||||
'\.sh' => __( 'Shell script file', 'theme-check' ),
|
||||
'postcss\.config\.js' => __( 'PostCSS config file', 'theme-check' ),
|
||||
'\.editorconfig.' => __( 'Editor config file', 'theme-check' ),
|
||||
'\.stylelintrc\.json' => __( 'Stylelint config file', 'theme-check' ),
|
||||
'\.map' => __( 'Map file', 'theme-check' ),
|
||||
'\.eslintrc' => __( 'ES lint config file', 'theme-check' ),
|
||||
'favicon\.ico' => __( 'Favicon', 'theme-check' ),
|
||||
);
|
||||
|
||||
$musthave = array( 'index.php', 'style.css', 'readme.txt' );
|
||||
$rechave = array();
|
||||
|
||||
checkcount();
|
||||
|
||||
foreach( $blacklist as $file => $reason ) {
|
||||
if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
|
||||
$error = implode( array_unique( $filename ), ' ' );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('%1$s %2$s found.', 'theme-check'), '<strong>' . $error . '</strong>', $reason) ;
|
||||
$ret = false;
|
||||
foreach ( $blacklist as $file => $reason ) {
|
||||
if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
|
||||
$error = implode( ' ', array_unique( $filename ) );
|
||||
if ( $error === $whitelist ) {
|
||||
continue;
|
||||
}
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( '%1$s %2$s found. This file must not be in a theme.', 'theme-check' ), '<strong>' . $error . '</strong>', $reason );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( $musthave as $file ) {
|
||||
if ( !in_array( $file, $filenames ) ) {
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('Could not find the file %s in the theme.', 'theme-check'), '<strong>' . $file . '</strong>' );
|
||||
$ret = false;
|
||||
foreach ( $musthave as $file ) {
|
||||
if ( ! in_array( $file, $filenames ) ) {
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Could not find the file %s in the theme.', 'theme-check' ), '<strong>' . $file . '</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( $rechave as $file => $reason ) {
|
||||
if ( !in_array( $file, $filenames ) ) {
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Could not find the file %1$s in the theme. %2$s', 'theme-check'), '<strong>' . $file . '</strong>', $reason );
|
||||
foreach ( $rechave as $file => $reason ) {
|
||||
if ( ! in_array( $file, $filenames ) ) {
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-recommended">' . __( 'RECOMMENDED', 'theme-check' ) . '</span>: ' . __( 'Could not find the file %1$s in the theme. %2$s', 'theme-check' ), '<strong>' . $file . '</strong>', $reason );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,4 +82,5 @@ class File_Checks implements themecheck {
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
$themechecks[] = new File_Checks;
|
||||
|
||||
$themechecks[] = new File_Checks();
|
||||
|
||||
@@ -30,7 +30,7 @@ class GeneratedCheck implements themecheck {
|
||||
//wpthemegenerator
|
||||
|| strpos ( $php, "wptg_") !== false
|
||||
) {
|
||||
$this->error[] = "<span class='tc-lead tc-warning'>" . __('WARNING', 'theme-check' ). "</span>: " . __( 'This theme appears to have been auto-generated. Generated themes are not allowed in the themes directory.', 'theme-check' );
|
||||
$this->error[] = "<span class='tc-lead tc-required'>" . __('REQUIRED', 'theme-check' ). "</span>: " . __( 'This theme appears to have been auto-generated. Generated themes are not allowed in the themes directory.', 'theme-check' );
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
@@ -39,4 +39,4 @@ class GeneratedCheck implements themecheck {
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
$themechecks[] = new GeneratedCheck;
|
||||
$themechecks[] = new GeneratedCheck;
|
||||
|
||||
@@ -1,70 +1,71 @@
|
||||
<?php
|
||||
|
||||
// check for various I18N errors
|
||||
|
||||
class I18NCheck implements themecheck {
|
||||
protected $error = array();
|
||||
|
||||
function check( $php_files, $css_files, $other_files ) {
|
||||
$ret = true;
|
||||
$error = '';
|
||||
checkcount();
|
||||
|
||||
// make sure the tokenizer is available
|
||||
if ( !function_exists( 'token_get_all' ) ) return true;
|
||||
|
||||
foreach ( $php_files as $php_key => $phpfile ) {
|
||||
$error='';
|
||||
|
||||
$stmts = array();
|
||||
foreach ( array('_e(', '__(', '_e (', '__ (') as $finder) {
|
||||
$search = $phpfile;
|
||||
while ( ( $pos = strpos($search, $finder) ) !== false ) {
|
||||
$search = substr($search,$pos);
|
||||
$open=1;
|
||||
$i=strpos($search,'(')+1;
|
||||
while( $open>0 ) {
|
||||
switch($search[$i]) {
|
||||
case '(':
|
||||
$open++; break;
|
||||
case ')':
|
||||
$open--; break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$stmts[] = substr($search,0,$i);
|
||||
$search = substr($search,$i);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $stmts as $match ) {
|
||||
$tokens = @token_get_all('<?php '.$match.';');
|
||||
if (!empty($tokens)) {
|
||||
foreach ($tokens as $token) {
|
||||
if (is_array($token) && in_array( $token[0], array( T_VARIABLE ) ) ) {
|
||||
$filename = tc_filename( $php_key );
|
||||
$grep = tc_grep( ltrim( $match ), $php_key );
|
||||
preg_match( '/[^\s]*\s[0-9]+/', $grep, $line);
|
||||
$error = '';
|
||||
if ( isset( $line[0] ) ) {
|
||||
$error = ( !strpos( $error, $line[0] ) ) ? $grep : '';
|
||||
}
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Possible variable %1$s found in translation function in %2$s. Translation function calls must NOT contain PHP variables. %3$s','theme-check'),
|
||||
'<strong>' . $token[1] . '</strong>',
|
||||
'<strong>' . $filename . '</strong>',
|
||||
$error
|
||||
);
|
||||
break; // stop looking at the tokens on this line once a variable is found
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
<?php
|
||||
|
||||
// check for various I18N errors
|
||||
|
||||
class I18NCheck implements themecheck {
|
||||
protected $error = array();
|
||||
|
||||
function check( $php_files, $css_files, $other_files ) {
|
||||
|
||||
$ret = true;
|
||||
$error = '';
|
||||
checkcount();
|
||||
|
||||
// make sure the tokenizer is available
|
||||
if ( !function_exists( 'token_get_all' ) ) return true;
|
||||
|
||||
foreach ( $php_files as $php_key => $phpfile ) {
|
||||
$error='';
|
||||
|
||||
$stmts = array();
|
||||
foreach ( array('_e(', '__(', '_e (', '__ (') as $finder) {
|
||||
$search = $phpfile;
|
||||
while ( ( $pos = strpos($search, $finder) ) !== false ) {
|
||||
$search = substr($search,$pos);
|
||||
$open=1;
|
||||
$i=strpos($search,'(')+1;
|
||||
while( $open>0 ) {
|
||||
switch($search[$i]) {
|
||||
case '(':
|
||||
$open++; break;
|
||||
case ')':
|
||||
$open--; break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$stmts[] = substr($search,0,$i);
|
||||
$search = substr($search,$i);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $stmts as $match ) {
|
||||
$tokens = @token_get_all('<?php '.$match.';');
|
||||
if (!empty($tokens)) {
|
||||
foreach ($tokens as $token) {
|
||||
if (is_array($token) && in_array( $token[0], array( T_VARIABLE ) ) ) {
|
||||
$filename = tc_filename( $php_key );
|
||||
$grep = tc_grep( ltrim( $match ), $php_key );
|
||||
preg_match( '/[^\s]*\s[0-9]+/', $grep, $line);
|
||||
$error = '';
|
||||
if ( isset( $line[0] ) ) {
|
||||
$error = ( !strpos( $error, $line[0] ) ) ? $grep : '';
|
||||
}
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Possible variable %1$s found in translation function in %2$s. Translation function calls must NOT contain PHP variables. %3$s','theme-check'),
|
||||
'<strong>' . $token[1] . '</strong>',
|
||||
'<strong>' . $filename . '</strong>',
|
||||
$error
|
||||
);
|
||||
break; // stop looking at the tokens on this line once a variable is found
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
$themechecks[] = new I18NCheck;
|
||||
@@ -19,7 +19,7 @@ class IncludedPlugins implements themecheck {
|
||||
|
||||
foreach ( $blacklist as $file => $reason ) {
|
||||
if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
|
||||
$error = implode( array_unique( $filename ), ' ' );
|
||||
$error = implode( ' ', array_unique( $filename ) );
|
||||
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED','theme-check' ) . '</span>: ' . __( '<strong>Zip file found.</strong> Plugins are not allowed in themes. The zip file found was <em>%s</em>.', 'theme-check' ), $error );
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ class LineEndingsCheck implements themecheck {
|
||||
if (preg_match("/\r\n/",$phpfile)) {
|
||||
if (preg_match("/[^\r]\n/",$phpfile)) {
|
||||
$filename = tc_filename( $php_key );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('Both DOS and UNIX style line endings were found in the file %1$s. This causes a problem with SVN repositories and must be corrected before the theme can be accepted. Please change the file to use only one style of line endings.', 'theme-check'), '<strong>' . $filename . '</strong>' );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Both DOS and UNIX style line endings were found in the file %1$s. This causes a problem with SVN repositories and must be corrected before the theme can be accepted. Please change the file to use only one style of line endings.', 'theme-check'), '<strong>' . $filename . '</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ class LineEndingsCheck implements themecheck {
|
||||
if (preg_match("/\r\n/",$cssfile)) {
|
||||
if (preg_match("/[^\r]\n/",$cssfile)) {
|
||||
$filename = tc_filename( $css_key );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('Both DOS and UNIX style line endings were found in the file %1$s. This causes a problem with SVN repositories and must be corrected before the theme can be accepted. Please change the file to use only one style of line endings.', 'theme-check'), '<strong>' . $filename . '</strong>' );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Both DOS and UNIX style line endings were found in the file %1$s. This causes a problem with SVN repositories and must be corrected before the theme can be accepted. Please change the file to use only one style of line endings.', 'theme-check'), '<strong>' . $filename . '</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ class LineEndingsCheck implements themecheck {
|
||||
if (preg_match("/\r\n/",$othfile)) {
|
||||
if (preg_match("/[^\r]\n/",$othfile)) {
|
||||
$filename = tc_filename( $oth_key );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('Both DOS and UNIX style line endings were found in the file %1$s. This causes a problem with SVN repositories and must be corrected before the theme can be accepted. Please change the file to use only one style of line endings.', 'theme-check'), '<strong>' . $filename . '</strong>' );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Both DOS and UNIX style line endings were found in the file %1$s. This causes a problem with SVN repositories and must be corrected before the theme can be accepted. Please change the file to use only one style of line endings.', 'theme-check'), '<strong>' . $filename . '</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,21 +5,63 @@ class NavMenuCheck implements themecheck {
|
||||
|
||||
function check( $php_files, $css_files, $other_files ) {
|
||||
|
||||
$ret = true;
|
||||
$ret = true;
|
||||
$name_check = false;
|
||||
|
||||
$php = implode( ' ', $php_files );
|
||||
|
||||
// combine all the php files into one string to make it easier to search
|
||||
$php = implode( ' ', $php_files );
|
||||
checkcount();
|
||||
if ( strpos( $php, 'nav_menu' ) === false ) {
|
||||
$this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__("No reference to nav_menu's was found in the theme. Note that if your theme has a menu bar, it is required to use the WordPress nav_menu functionality for it.", 'theme-check' );
|
||||
$this->error[] = '<span class="tc-lead tc-recommended">' . __( 'RECOMMENDED', 'theme-check' ) . '</span>: ' . __( "No reference to nav_menu's was found in the theme. Note that if your theme has a menu bar, it is required to use the WordPress nav_menu functionality for it.", 'theme-check' );
|
||||
}
|
||||
|
||||
// Look for add_theme_support( 'menus' ).
|
||||
checkcount();
|
||||
if ( preg_match( '/add_theme_support\s*\(\s?("|\')menus("|\')\s?\)/', $php ) ) {
|
||||
/* translators: 1: function found, 2: function to be used */
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check') . '</span>: ' . sprintf( __( 'Reference to %1$s was found in the theme. This should be removed and %2$s used instead.', 'theme-check' ), '<strong>add_theme_support( "menus" )</strong>', '<a href="https://developer.wordpress.org/reference/functions/register_nav_menus/">register_nav_menus()</a>' );
|
||||
$ret = false;
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'Reference to %1$s was found in the theme. This should be removed and %2$s used instead.', 'theme-check' ), '<strong>add_theme_support( "menus" )</strong>', '<a href="https://developer.wordpress.org/reference/functions/register_nav_menus/">register_nav_menus()</a>' );
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
foreach ( $php_files as $file_path => $file_content ) {
|
||||
$filename = tc_filename( $file_path );
|
||||
|
||||
// We are checking for wp_nav_menu( specifically, to allow wp_nav_menu and wp_nav_menu_item in filters etc.
|
||||
if ( strpos( $file_content, 'wp_nav_menu(' ) !== false ) {
|
||||
$menu_part = explode( 'wp_nav_menu(', $file_content );
|
||||
$menu_part = explode( ';', $menu_part[1] );
|
||||
|
||||
// If there is a menu, check for a theme location, which is required.
|
||||
// Check if the arguments are placed outside wp_nav_menu.
|
||||
checkcount();
|
||||
if ( strpos( $menu_part[0], '$' ) !== false && strpos( $menu_part[0], 'theme_location' ) === false ) {
|
||||
$menu_args = explode( '$', $menu_part[0], 1 );
|
||||
$name = explode( ')', $menu_args[0] );
|
||||
$this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . sprintf( __( 'A menu without a theme_location was found in %1$s. %2$s is used inside wp_nav_menu(). You must manually check if the theme_location is included.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>',
|
||||
'<code>' . $name[0] . '</code>'
|
||||
);
|
||||
$name_check = true;
|
||||
} else {
|
||||
checkcount();
|
||||
if ( strpos( $menu_part[0], 'theme_location' ) === false ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'A menu without a theme_location was found in %1$s.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>'
|
||||
);
|
||||
$ret = false;
|
||||
$name_check = true;
|
||||
}
|
||||
}
|
||||
|
||||
// We only need to warn for the menu name if theme location is not set.
|
||||
checkcount();
|
||||
if ( $name_check === true && preg_match( '/("|\')menu("|\').*?=>/', $menu_part[0] ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'A menu name is being used for a menu in %1$s. By using menu name, the menu would be required to have the exact same name in the WordPress admin area. Use a theme_location instead.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>'
|
||||
);
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
@@ -28,4 +70,4 @@ class NavMenuCheck implements themecheck {
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
|
||||
$themechecks[] = new NavMenuCheck;
|
||||
$themechecks[] = new NavMenuCheck();
|
||||
|
||||
@@ -10,10 +10,10 @@ class NonPrintableCheck implements themecheck {
|
||||
// 09 = tab
|
||||
// 0A = line feed
|
||||
// 0D = new line
|
||||
if ( preg_match('/[\x00-\x08\x0B-\x0C\x0E-\x1F\x80-\xFF]/', $content, $matches ) ) {
|
||||
if ( preg_match('/[\x00-\x08\x0B-\x0C\x0E-\x1F]/', $content, $matches ) ) {
|
||||
$filename = tc_filename( $name );
|
||||
$non_print = tc_preg( '/[\x00-\x08\x0B-\x0C\x0E-\x1F\x80-\xFF]/', $name );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-info">'.__('INFO','theme-check').'</span>: '.__('Non-printable characters were found in the %1$s file. You may want to check this file for errors.%2$s', 'theme-check'), '<strong>' . $filename . '</strong>', $non_print);
|
||||
$non_print = tc_preg( '/[\x00-\x08\x0B-\x0C\x0E-\x1F]/', $name );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . __( 'Non-printable characters were found in the %1$s file. You may want to check this file for errors.%2$s', 'theme-check' ), '<strong>' . $filename . '</strong>', $non_print);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ class NonPrintableCheck implements themecheck {
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
|
||||
$themechecks[] = new NonPrintableCheck;
|
||||
$themechecks[] = new NonPrintableCheck;
|
||||
|
||||
@@ -12,7 +12,6 @@ class PHPShortTagsCheck implements themecheck {
|
||||
$filename = tc_filename( $php_key );
|
||||
$grep = tc_preg( '/<\?(\=?)(?!php|xml)/', $php_key );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('Found PHP short tags in file %1$s.%2$s', 'theme-check'), '<strong>' . $filename . '</strong>', $grep);
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +21,4 @@ class PHPShortTagsCheck implements themecheck {
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
|
||||
$themechecks[] = new PHPShortTagsCheck;
|
||||
$themechecks[] = new PHPShortTagsCheck;
|
||||
|
||||
@@ -1,14 +1,29 @@
|
||||
<?php
|
||||
<?php // phpcs:ignore WordPress.Files.FileName
|
||||
/**
|
||||
* Checks for Plugin Territory Guidelines.
|
||||
*
|
||||
* See http://make.wordpress.org/themes/guidelines/guidelines-plugin-territory/
|
||||
* @link https://make.wordpress.org/themes/handbook/review/required/#presentation-vs-functionality
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks for Plugin Territory
|
||||
*/
|
||||
class Plugin_Territory implements themecheck {
|
||||
/**
|
||||
* Error messages, warnings and info notices.
|
||||
*
|
||||
* @var array $error
|
||||
*/
|
||||
protected $error = array();
|
||||
|
||||
function check( $php_files, $css_files, $other_files ) {
|
||||
/**
|
||||
* Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
|
||||
*
|
||||
* @param array $php_files File paths and content for PHP files.
|
||||
* @param array $css_files File paths and content for CSS files.
|
||||
* @param array $other_files Folder names, file paths and content for other files.
|
||||
*/
|
||||
public function check( $php_files, $css_files, $other_files ) {
|
||||
$ret = true;
|
||||
$php = implode( ' ', $php_files );
|
||||
|
||||
@@ -16,26 +31,107 @@ class Plugin_Territory implements themecheck {
|
||||
$forbidden_functions = array(
|
||||
'register_post_type',
|
||||
'register_taxonomy',
|
||||
'wp_add_dashboard_widget',
|
||||
'register_block_type',
|
||||
);
|
||||
|
||||
foreach ( $forbidden_functions as $function ) {
|
||||
checkcount();
|
||||
if ( preg_match( '/[\s?]' . $function . '\s?\(/', $php ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . sprintf( __( 'The theme uses the %s function, which is plugin-territory functionality.', 'theme-check' ), '<strong>' . esc_html( $function ) . '()</strong>' ) ;
|
||||
$ret = false;
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme uses the %s function, which is plugin-territory functionality.', 'theme-check' ), '<strong>' . esc_html( $function ) . '()</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Shortcodes can't be used in the post content, so warn about them.
|
||||
if ( false !== strpos( $php, 'add_shortcode' ) ) {
|
||||
if ( false !== strpos( $php, 'add_shortcode(' ) ) {
|
||||
checkcount();
|
||||
$this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check').'</span>: ' . sprintf( __( 'The theme uses the %s function. Custom post-content shortcodes are plugin-territory functionality.', 'theme-check' ), '<strong>add_shortcode()</strong>' ) ;
|
||||
$ret = false;
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme uses the %s function. Custom post-content shortcodes are plugin-territory functionality.', 'theme-check' ), '<strong>add_shortcode()</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
// Hooks (actions & filters) that are required to be removed from the theme.
|
||||
$forbidden_hooks = array(
|
||||
'filter' => array(
|
||||
'mime_types',
|
||||
'upload_mimes',
|
||||
'user_contactmethods',
|
||||
),
|
||||
'action' => array(
|
||||
'wp_dashboard_setup',
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $forbidden_hooks as $type => $hooks ) {
|
||||
foreach ( $hooks as $hook ) {
|
||||
checkcount();
|
||||
if ( preg_match( '/[\s?]add_' . $type . '\s*\(\s*([\'"])' . $hook . '([\'"])\s*,/', $php ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme uses the %1$s %2$s, which is plugin-territory functionality.', 'theme-check' ), '<strong>' . esc_html( $hook ) . '</strong>', esc_html( $type ) );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for removal of non presentational hooks.
|
||||
* Removing emojis is also not allowed.
|
||||
*/
|
||||
$blacklist = array(
|
||||
'wp_head' => array(
|
||||
'wp_generator', // @link https://developer.wordpress.org/reference/functions/wp_generator/
|
||||
'feed_links', // @link https://developer.wordpress.org/reference/functions/feed_links/
|
||||
'feed_links_extra', // @link https://developer.wordpress.org/reference/functions/feed_links_extra/
|
||||
'print_emoji_detection_script', // @link https://developer.wordpress.org/reference/functions/print_emoji_detection_script/
|
||||
'wp_resource_hints', // @link https://developer.wordpress.org/reference/functions/wp_resource_hints/
|
||||
'adjacent_posts_rel_link_wp_head', // @link https://developer.wordpress.org/reference/functions/adjacent_posts_rel_link_wp_head/
|
||||
'wp_shortlink_wp_head', // @link https://developer.wordpress.org/reference/functions/wp_shortlink_wp_head/
|
||||
'_admin_bar_bump_cb', // @link https://developer.wordpress.org/reference/functions/_admin_bar_bump_cb/
|
||||
'rsd_link', // @link https://developer.wordpress.org/reference/functions/rsd_link/
|
||||
'rest_output_link_wp_head', // @link https://developer.wordpress.org/reference/functions/rest_output_link_wp_head/
|
||||
'wp_oembed_add_discovery_links', // @link https://developer.wordpress.org/reference/functions/wp_oembed_add_discovery_links/
|
||||
'wp_oembed_add_host_js', // @link https://developer.wordpress.org/reference/functions/wp_oembed_add_host_js/
|
||||
'rel_canonical', // @link https://developer.wordpress.org/reference/functions/rel_canonical/
|
||||
),
|
||||
'wp_print_styles' => array(
|
||||
'print_emoji_styles', // @link https://developer.wordpress.org/reference/functions/print_emoji_styles/
|
||||
),
|
||||
'admin_print_scripts' => array(
|
||||
'print_emoji_detection_script', //@link https://developer.wordpress.org/reference/functions/print_emoji_detection_script/
|
||||
),
|
||||
'admin_print_styles' => array(
|
||||
'print_emoji_styles', // @link https://developer.wordpress.org/reference/functions/print_emoji_styles/
|
||||
),
|
||||
'template_redirect' => array(
|
||||
'rest_output_link_header', // @link https://developer.wordpress.org/reference/functions/rest_output_link_header/
|
||||
'wp_shortlink_header', // @link https://developer.wordpress.org/reference/functions/wp_shortlink_header/
|
||||
'redirect_canonical', // @link https://developer.wordpress.org/reference/functions/redirect_canonical/
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $blacklist as $hook => $functions ) {
|
||||
foreach ( $functions as $function ) {
|
||||
checkcount();
|
||||
if ( preg_match( '/[\s?]remove_action\s*\(\s*([\'"])' . $hook . '([\'"])\s*,\s*([\'"])' . $function . '([\'"])/', $php ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme uses <strong>remove_action %1$s %2$s</strong>, which is plugin-territory functionality.', 'theme-check' ),
|
||||
esc_html( $hook ),
|
||||
esc_html( $function )
|
||||
);
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getError() { return $this->error; }
|
||||
/**
|
||||
* Get error messages from the checks.
|
||||
*
|
||||
* @return array Error message.
|
||||
*/
|
||||
public function getError() {
|
||||
return $this->error;
|
||||
}
|
||||
}
|
||||
$themechecks[] = new Plugin_Territory;
|
||||
|
||||
$themechecks[] = new Plugin_Territory();
|
||||
|
||||
@@ -18,13 +18,15 @@ class Screenshot_Checks implements themecheck {
|
||||
foreach ( $other_files as $other_key => $otherfile ) {
|
||||
|
||||
if ( ( basename( $other_key ) === 'screenshot.png' || basename( $other_key ) === 'screenshot.jpg' ) && preg_match( '/.*themes\/[^\/]*\/screenshot\.(png|jpg)/', $other_key ) ) {
|
||||
// we have or screenshot!
|
||||
// we have our screenshot!
|
||||
$image = getimagesize( $other_key );
|
||||
if ( $image[0] > 1200 || $image[1] > 900 ) {
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-recommended">'. __( 'RECOMMENDED','theme-check' ) . '</span>: ' . __( 'Screenshot is wrong size! Detected: %1$sx%2$spx. Maximum allowed size is 1200x900px.', 'theme-check' ), '<strong>' . $image[0], $image[1] . '</strong>' );
|
||||
$this->error[] = sprintf('<span class="tc-lead tc-required">'. __( 'REQUIRED','theme-check' ) . '</span>: ' . __( 'Screenshot is wrong size! Detected: %1$sx%2$spx. Maximum allowed size is 1200x900px.', 'theme-check' ), '<strong>' . $image[0], $image[1] . '</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
if ( $image[1] / $image[0] != 0.75 ) {
|
||||
$this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Screenshot dimensions are wrong! Ratio of width to height should be 4:3.', 'theme-check');
|
||||
$this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Screenshot dimensions are wrong! Ratio of width to height should be 4:3.', 'theme-check');
|
||||
$ret = false;
|
||||
}
|
||||
if ( $image[0] != 1200 || $image[1] != 900 ) {
|
||||
$this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Screenshot size should be 1200x900, to account for HiDPI displays. Any 4:3 image size is acceptable, but 1200x900 is preferred.', 'theme-check');
|
||||
@@ -32,7 +34,7 @@ class Screenshot_Checks implements themecheck {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->error[] = '<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('No screenshot detected! Please include a screenshot.png or screenshot.jpg.', 'theme-check' );
|
||||
$this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('No screenshot detected! Please include a screenshot.png or screenshot.jpg.', 'theme-check' );
|
||||
$ret = false;
|
||||
}
|
||||
return $ret;
|
||||
|
||||
@@ -15,6 +15,8 @@ class Style_Needed implements themecheck {
|
||||
'[ \t\/*#]*License:' => __( '<strong>License:</strong> is missing from your style.css header.', 'theme-check' ),
|
||||
'[ \t\/*#]*License URI:' => __( '<strong>License URI:</strong> is missing from your style.css header.', 'theme-check' ),
|
||||
'[ \t\/*#]*Text Domain:' => __( '<strong>Text Domain:</strong> is missing from your style.css header.', 'theme-check' ),
|
||||
'[ \t\/*#]*Tested up to:' => __( '<strong>Tested up to:</strong> is missing from your style.css header. Also, this should be numbers only, so <em>5.0</em> and not <em>WP 5.0</em>', 'theme-check' ),
|
||||
'[ \t\/*#]*Requires PHP:' => __( '<strong>Requires PHP:</strong> is missing from your style.css header.', 'theme-check' ),
|
||||
'\.sticky' => __( '<strong>.sticky</strong> css class is needed in your theme css.', 'theme-check' ),
|
||||
'\.bypostauthor' => __( '<strong>.bypostauthor</strong> css class is needed in your theme css.', 'theme-check' ),
|
||||
'\.alignleft' => __( '<strong>.alignleft</strong> css class is needed in your theme css.', 'theme-check' ),
|
||||
|
||||
@@ -9,51 +9,55 @@ class Style_Tags implements themecheck {
|
||||
$filenames = array();
|
||||
|
||||
foreach( $css_files as $cssfile => $content ) {
|
||||
if ( basename( $cssfile ) === 'style.css' ) $data = get_theme_data_from_contents( $content );
|
||||
}
|
||||
if ( basename( $cssfile ) === 'style.css' ) {
|
||||
$data = get_theme_data_from_contents( $content );
|
||||
|
||||
if ( !$data[ 'Tags' ] ) {
|
||||
$this->error[] = '<span class="tc-lead tc-recommended">' . __('RECOMMENDED','theme-check') . '</span>: ' . __( '<strong>Tags:</strong> is either empty or missing in style.css header.', 'theme-check' );
|
||||
return $ret;
|
||||
}
|
||||
$deprecated_tags = array("flexible-width","fixed-width","black","blue","brown","gray","green","orange","pink","purple","red","silver","tan","white","yellow","dark","light","fixed-layout","fluid-layout","responsive-layout","blavatar","holiday","photoblogging","seasonal");
|
||||
$allowed_tags = array('grid-layout',"one-column","two-columns","three-columns","four-columns","left-sidebar","right-sidebar","wide-blocks","flexible-header",'footer-widgets',"accessibility-ready","block-styles","buddypress","custom-background","custom-colors","custom-header","custom-menu","custom-logo","editor-style","featured-image-header","featured-images","front-page-post-form","full-width-template","microformats","post-formats","rtl-language-support","sticky-post","theme-options","threaded-comments","translation-ready",'blog','e-commerce','education','entertainment','food-and-drink','holiday','news','photography','portfolio');
|
||||
$subject_tags = array('blog','e-commerce','education','entertainment','food-and-drink','holiday','news','photography','portfolio');
|
||||
$subject_tags_count = 0;
|
||||
$subject_tags_name = "";
|
||||
if ( !$data[ 'Tags' ] ) {
|
||||
$this->error[] = '<span class="tc-lead tc-recommended">' . __('RECOMMENDED','theme-check') . '</span>: ' . __( '<strong>Tags:</strong> is either empty or missing in style.css header.', 'theme-check' )
|
||||
. ' ('. basename( dirname( $cssfile)) . ')';
|
||||
}
|
||||
else {
|
||||
$deprecated_tags = array("flexible-width","fixed-width","black","blue","brown","gray","green","orange","pink","purple","red","silver","tan","white","yellow","dark","light","fixed-layout","fluid-layout","responsive-layout","blavatar","holiday","photoblogging","seasonal");
|
||||
$allowed_tags = array('grid-layout',"one-column","two-columns","three-columns","four-columns","left-sidebar","right-sidebar","wide-blocks","flexible-header",'footer-widgets',"accessibility-ready","block-styles","buddypress","custom-background","custom-colors","custom-header","custom-menu","custom-logo","editor-style","featured-image-header","featured-images","front-page-post-form","full-width-template","microformats","post-formats","rtl-language-support","sticky-post","theme-options","threaded-comments","translation-ready",'blog','e-commerce','education','entertainment','food-and-drink','holiday','news','photography','portfolio');
|
||||
$subject_tags = array('blog','e-commerce','education','entertainment','food-and-drink','holiday','news','photography','portfolio');
|
||||
$subject_tags_count = 0;
|
||||
$subject_tags_name = "";
|
||||
|
||||
foreach( $data[ 'Tags' ] as $tag ) {
|
||||
foreach( $data[ 'Tags' ] as $tag ) {
|
||||
|
||||
if ( strpos( strtolower( $tag ), "accessibility-ready") !== false ) {
|
||||
$this->error[] = '<span class="tc-lead tc-info">'. __('INFO','theme-check'). '</span>: ' . __( 'Themes that use the tag accessibility-ready will need to undergo an accessibility review.','theme-check' ) . ' ' . __('See <a href="https://make.wordpress.org/themes/handbook/review/accessibility/">https://make.wordpress.org/themes/handbook/review/accessibility/</a>', 'theme-check' );
|
||||
}
|
||||
if ( strpos( strtolower( $tag ), "accessibility-ready") !== false ) {
|
||||
$this->error[] = '<span class="tc-lead tc-info">'. __('INFO','theme-check'). '</span>: ' . __( 'Themes that use the tag accessibility-ready will need to undergo an accessibility review.','theme-check' ) . ' ' . __('See <a href="https://make.wordpress.org/themes/handbook/review/accessibility/">https://make.wordpress.org/themes/handbook/review/accessibility/</a>', 'theme-check' );
|
||||
}
|
||||
|
||||
if ( ! in_array( strtolower( $tag ), $allowed_tags ) ) {
|
||||
if ( in_array( strtolower( $tag ), $deprecated_tags ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-warning">'. __('WARNING','theme-check'). '</span>: ' . sprintf( __('The tag %s has been deprecated, please remove it from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
|
||||
} else {
|
||||
$this->error[] = '<span class="tc-lead tc-warning">'. __('WARNING','theme-check'). '</span>: ' . sprintf( __('Found wrong tag, remove %s from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
|
||||
$ret = false;
|
||||
if ( ! in_array( strtolower( $tag ), $allowed_tags ) ) {
|
||||
if ( in_array( strtolower( $tag ), $deprecated_tags ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('The tag %s has been deprecated, please remove it from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
|
||||
$ret = false;
|
||||
} else {
|
||||
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('Found wrong tag, remove %s from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( in_array( strtolower( $tag ), $subject_tags ) ) {
|
||||
$subject_tags_name .= strtolower( $tag ) . ', ';
|
||||
$subject_tags_count++;
|
||||
}
|
||||
|
||||
if ( in_array( strtolower( $tag ), $allowed_tags ) ) {
|
||||
if ( count( array_keys ($data[ 'Tags' ], $tag ) ) > 1) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('The tag %s is being used more than once, please remove it from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $subject_tags_count > 3 ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('A maximum of 3 subject tags are allowed. The theme has %1$u subjects tags ( %2$s ). Please remove the subject tags, which do not directly apply to the theme.', 'theme-check'), $subject_tags_count, '<strong>' . rtrim( $subject_tags_name, ', ' ) . '</strong>' ) . ' ' . '<a target="_blank" href="https://make.wordpress.org/themes/handbook/review/required/theme-tags/">' . __( 'See Theme Tags', 'theme-check' ) . '</a>';
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( in_array( strtolower( $tag ), $subject_tags ) ) {
|
||||
$subject_tags_name .= strtolower( $tag ) . ', ';
|
||||
$subject_tags_count++;
|
||||
}
|
||||
|
||||
if ( in_array( strtolower( $tag ), $allowed_tags ) ) {
|
||||
if ( count( array_keys ($data[ 'Tags' ], $tag ) ) > 1) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('The tag %s is being used more than once, please remove it from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( $subject_tags_count > 3 ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('A maximum of 3 subject tags are allowed. The theme has %1$u subjects tags ( %2$s ). Please remove the subject tags, which do not directly apply to the theme.', 'theme-check'), $subject_tags_count, '<strong>' . rtrim( $subject_tags_name, ', ' ) . '</strong>' ) . ' ' . '<a target="_blank" href="https://make.wordpress.org/themes/handbook/review/required/theme-tags/">' . __( 'See Theme Tags', 'theme-check' ) . '</a>';
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
@@ -140,7 +140,7 @@ class TextDomainCheck implements themecheck {
|
||||
}
|
||||
|
||||
if ( $domainscount > 1 ) {
|
||||
$this->error[] = '<span class="tc-lead tc-warning">' . __( 'Warning', 'theme-check' ) . '</span>: '
|
||||
$this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: '
|
||||
. __( 'More than one text-domain is being used in this theme. This means the theme will not be compatible with WordPress.org language packs.', 'theme-check' )
|
||||
. '<br>'
|
||||
. sprintf( __( 'The domains found are %s', 'theme-check'), '<strong>' . $domainlist . '</strong>' );
|
||||
|
||||
@@ -5,49 +5,59 @@
|
||||
* Is there a call to wp_title()?
|
||||
* There can't be any hardcoded text in the <title> tag.
|
||||
*
|
||||
* See: http://make.wordpress.org/themes/guidelines/guidelines-theme-check/
|
||||
* See: https://make.wordpress.org/themes/handbook/review/required/theme-check-plugin/
|
||||
*/
|
||||
class Title_Checks implements themecheck {
|
||||
protected $error = array();
|
||||
protected $error = array();
|
||||
|
||||
function check( $php_files, $css_files, $other_files ) {
|
||||
$ret = true;
|
||||
$php = implode( ' ', $php_files );
|
||||
|
||||
// Look for add_theme_support( 'title-tag' ) first
|
||||
// Look for add_theme_support( 'title-tag' ) first.
|
||||
$titletag = true;
|
||||
if ( ! preg_match( '#add_theme_support\s?\(\s?[\'|"]title-tag#', $php ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('No reference to <strong>add_theme_support( "title-tag" )</strong> was found in the theme.', 'theme-check' );
|
||||
$titletag = false;
|
||||
$ret = false;
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'No reference to <strong>add_theme_support( "title-tag" )</strong> was found in the theme.', 'theme-check' );
|
||||
$titletag = false;
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
// Look for <title> and </title> tags.
|
||||
checkcount();
|
||||
if ( ( 0 <= strpos( $php, '<title>' ) || 0 <= strpos( $php, '</title>' ) ) && !$titletag ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( 'The theme must not used the <strong><title></strong> tags.', 'theme-check' );
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
// Check whether there is a call to wp_title()
|
||||
checkcount();
|
||||
if ( 0 <= strpos( $php, 'wp_title(' ) && !$titletag ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( 'The theme must not call to <strong>wp_title()</strong>.', 'theme-check' );
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
//Check whether the the <title> tag contains something besides a call to wp_title()
|
||||
checkcount();
|
||||
|
||||
foreach ( $php_files as $file_path => $file_content ) {
|
||||
// Look for anything that looks like <svg>...</svg> and exclude it (inline svg's have titles too)
|
||||
$file_content = preg_replace('/<svg.*>.*<\/svg>/s', '', $file_content);
|
||||
|
||||
// First looks ahead to see of there's <title>...</title>
|
||||
// Then performs a negative look ahead for <title> wp_title(...); </title>
|
||||
$filename = tc_filename( $file_path );
|
||||
|
||||
// Look for <title> and </title> tags.
|
||||
checkcount();
|
||||
if ( ( 0 <= strpos( $php, '<title>' ) || 0 <= strpos( $php, '</title>' ) ) && ! $titletag ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme must not use the <strong><title></strong> tags. Found the tag in %1$s.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>'
|
||||
);
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
// Check whether there is a call to wp_title().
|
||||
checkcount();
|
||||
if ( 0 <= strpos( $php, 'wp_title(' ) && ! $titletag ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme must not call to <strong>wp_title()</strong>. Found wp_title() in %1$s.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>'
|
||||
);
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
// Check whether the the <title> tag contains something besides a call to wp_title().
|
||||
checkcount();
|
||||
// Look for anything that looks like <svg>...</svg> and exclude it (inline svg's have titles too).
|
||||
$file_content = preg_replace( '/<svg.*>.*<\/svg>/s', '', $file_content );
|
||||
// First looks ahead to see of there's <title>...</title>.
|
||||
// Then performs a negative look ahead for <title> wp_title(...); </title>.
|
||||
$error = '/<title>/';
|
||||
$grep = tc_preg( $error, $file_path );
|
||||
|
||||
if ( preg_match( '/(?=<title>(.*)<\/title>)(?!<title>\s*<\?php\s*wp_title\([^\)]*\);?\s*\?>\s*<\/title>)/s', $file_content ) ) {
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( 'The <strong><title></strong> tags can only contain a call to <strong>wp_title()</strong>. Use the <strong>wp_title filter</strong> to modify the output', 'theme-check' );
|
||||
$ret = false;
|
||||
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . sprintf( __( '%1$s: The <strong><title></strong> tags can only contain a call to <strong>wp_title()</strong>. Use the <strong>wp_title filter</strong> to modify the output.', 'theme-check' ),
|
||||
'<strong>' . $filename . '</strong>'
|
||||
) . $grep;
|
||||
$ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,4 +67,4 @@ class Title_Checks implements themecheck {
|
||||
function getError() { return $this->error; }
|
||||
}
|
||||
|
||||
$themechecks[] = new Title_Checks;
|
||||
$themechecks[] = new Title_Checks();
|
||||
|
||||
@@ -18,12 +18,12 @@ class WidgetsCheck implements themecheck {
|
||||
}
|
||||
|
||||
if ( strpos( $php, 'register_sidebar' ) !== false && strpos( $php, 'dynamic_sidebar' ) === false ) {
|
||||
$this->error[] = "<span class='tc-lead tc-required'>" . __( "REQUIRED", 'theme-check') . '</span>: '. __( "The theme appears to use <strong>register_sidebar()</strong> but no <strong>dynamic_sidebar()</strong> was found. See: <a href='https://codex.wordpress.org/Function_Reference/dynamic_sidebar'>dynamic_sidebar</a><pre> <?php dynamic_sidebar( \$index ); ?></pre>", "theme-check" );
|
||||
$this->error[] = "<span class='tc-lead tc-required'>" . __( "REQUIRED", 'theme-check') . '</span>: '. __( "The theme appears to use <strong>register_sidebar()</strong> but no <strong>dynamic_sidebar()</strong> was found. See: <a href='https://developer.wordpress.org/reference/functions/dynamic_sidebar/'>dynamic_sidebar</a><pre> <?php dynamic_sidebar( \$index ); ?></pre>", "theme-check" );
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
if ( strpos( $php, 'register_sidebar' ) === false && strpos( $php, 'dynamic_sidebar' ) !== false ) {
|
||||
$this->error[] = "<span class='tc-lead tc-required'>" . __( "REQUIRED", 'theme-check') . '</span>: '. __( "The theme appears to use <strong>dynamic_sidebars()</strong> but no <strong>register_sidebar()</strong> was found. See: <a href='https://codex.wordpress.org/Function_Reference/register_sidebar'>register_sidebar</a><pre> <?php register_sidebar( \$args ); ?></pre>", "theme-check" );
|
||||
$this->error[] = "<span class='tc-lead tc-required'>" . __( "REQUIRED", 'theme-check') . '</span>: '. __( "The theme appears to use <strong>dynamic_sidebars()</strong> but no <strong>register_sidebar()</strong> was found. See: <a href='https://developer.wordpress.org/reference/functions/register_sidebar/'>register_sidebar</a><pre> <?php register_sidebar( \$args ); ?></pre>", "theme-check" );
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class WidgetsCheck implements themecheck {
|
||||
* There are widgets registered, is the widgets_init action present?
|
||||
*/
|
||||
if ( strpos( $php, 'register_sidebar' ) !== false && preg_match( '/add_action\s*\(\s*("|\')widgets_init("|\')\s*,/', $php ) == false ) {
|
||||
$this->error[] = "<span class='tc-lead tc-required'>" . __( "REQUIRED", 'theme-check') . '</span>: '. sprintf( __( "Sidebars need to be registered in a custom function hooked to the <strong>widgets_init</strong> action. See: %s.", "theme-check" ), '<a href="https://codex.wordpress.org/Function_Reference/register_sidebar">register_sidebar()</a>' );
|
||||
$this->error[] = "<span class='tc-lead tc-required'>" . __( "REQUIRED", 'theme-check') . '</span>: '. sprintf( __( "Sidebars need to be registered in a custom function hooked to the <strong>widgets_init</strong> action. See: %s.", "theme-check" ), '<a href="https://developer.wordpress.org/reference/functions/register_sidebar/">register_sidebar()</a>' );
|
||||
$ret = false;
|
||||
}
|
||||
return $ret;
|
||||
|
||||
Algunos archivos no se mostraron porque demasiados archivos han cambiado en esta diferencia Ver más
Referencia en una nueva incidencia
Block a user