]*>(.*?)<\/code>/i', '`$1`', $markdown);
$markdown = preg_replace('/]*>]*>(.*?)<\/code><\/pre>/s', "```\n$1\n```", $markdown);
-
+
// Списки
$markdown = preg_replace('/]*>(.*?)<\/li>/i', '* $1', $markdown);
$markdown = preg_replace('/]*>(.*?)<\/ul>/s', '$1', $markdown);
$markdown = preg_replace('/]*>(.*?)<\/ol>/s', '$1', $markdown);
-
+
// Цитаты
$markdown = preg_replace('/]*>(.*?)<\/blockquote>/s', '> $1', $markdown);
-
+
// Параграфы
- $markdown = preg_replace('/]*>(.*?)<\/p>/i', '$1' . "\n\n", $markdown);
-
+ $markdown = preg_replace('/
]*>(.*?)<\/p>/i', '$1'."\n\n", $markdown);
+
// Убираем лишние HTML теги
$markdown = strip_tags($markdown);
-
+
return trim($markdown);
}
/**
* Подключает стили и скрипты для Markdown редактора
*/
- public function enqueueMarkdownAssets($hook): void {
- if (!$this->isMarkdownEnabled()) {
+ public function enqueueMarkdownAssets($hook): void
+ {
+ if (! $this->isMarkdownEnabled()) {
return;
}
- if (!in_array($hook, ['post.php', 'post-new.php'])) {
+ if (! in_array($hook, ['post.php', 'post-new.php'])) {
return;
}
@@ -419,7 +437,7 @@ public function enqueueMarkdownAssets($hook): void {
'2.18.0',
true
);
-
+
wp_enqueue_style(
'easymde',
'https://unpkg.com/easymde/dist/easymde.min.css',
@@ -432,7 +450,7 @@ public function enqueueMarkdownAssets($hook): void {
wp_enqueue_script(
'markdown-editor',
- RW_PLUGIN_URL . 'assets/js/markdown-editor.js',
+ RW_PLUGIN_URL.'assets/js/markdown-editor.js',
['jquery', 'easymde'],
'1.0.1',
true
@@ -442,7 +460,7 @@ public function enqueueMarkdownAssets($hook): void {
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('markdown_preview'),
'enable_shortcuts' => $this->getSetting('markdown_enable_shortcuts', true),
- 'enable_preview' => $this->getSetting('markdown_enable_preview', true)
+ 'enable_preview' => $this->getSetting('markdown_enable_preview', true),
]);
// Подключаем стили GitHub Markdown для предпросмотра
@@ -460,7 +478,7 @@ public function enqueueMarkdownAssets($hook): void {
[],
'11.9.0'
);
-
+
wp_enqueue_script(
'highlightjs',
'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js',
@@ -471,7 +489,7 @@ public function enqueueMarkdownAssets($hook): void {
wp_enqueue_style(
'markdown-editor',
- RW_PLUGIN_URL . 'assets/css/markdown-editor.css',
+ RW_PLUGIN_URL.'assets/css/markdown-editor.css',
['github-markdown-css', 'highlightjs-github'],
'1.0.0'
);
@@ -560,11 +578,12 @@ public function enqueueMarkdownAssets($hook): void {
/**
* Подключает стили и скрипты для фронтенда
- *
+ *
* Note: Highlight.js подключается темой, здесь только github-markdown-css
*/
- public function enqueueFrontendAssets(): void {
- if (!$this->isMarkdownEnabled()) {
+ public function enqueueFrontendAssets(): void
+ {
+ if (! $this->isMarkdownEnabled()) {
return;
}
@@ -576,4 +595,4 @@ public function enqueueFrontendAssets(): void {
'5.2.0'
);
}
-}
\ No newline at end of file
+}
diff --git a/functions/MediaCleanup.php b/functions/MediaCleanup.php
index 0737e67..a3aa24f 100644
--- a/functions/MediaCleanup.php
+++ b/functions/MediaCleanup.php
@@ -1,20 +1,23 @@
service = $service;
}
- public function init(): void {
- if (!$this->isEnabled()) {
+ public function init(): void
+ {
+ if (! $this->isEnabled()) {
return;
}
@@ -22,8 +25,9 @@ public function init(): void {
add_action('wp_ajax_wp_addon_cleanup_images_dry_run', [$this, 'dryRun']);
}
- public function dryRun(): void {
- if (!$this->isEnabled() || !current_user_can('manage_options')) {
+ public function dryRun(): void
+ {
+ if (! $this->isEnabled() || ! current_user_can('manage_options')) {
wp_die(__('Access denied.', 'wp-addon'));
}
check_ajax_referer('cleanup_images', 'nonce');
@@ -36,18 +40,19 @@ public function dryRun(): void {
$totalSize = $result['totalSize'];
$sizeMb = round($totalSize / 1024 / 1024, 2);
- $fileListHtml = !empty($files)
- ? '
' . implode('', array_map(fn($f) => '' . esc_html(basename($f)) . ' ', $files)) . ' '
- : '' . __('No files to delete.', 'wp-addon') . '
';
- $totalSizeHtml = '' . sprintf(__('Total size: %s MB', 'wp-addon'), $sizeMb) . '
';
+ $fileListHtml = ! empty($files)
+ ? ''.implode('', array_map(fn ($f) => ''.esc_html(basename($f)).' ', $files)).' '
+ : ''.__('No files to delete.', 'wp-addon').'
';
+ $totalSizeHtml = ''.sprintf(__('Total size: %s MB', 'wp-addon'), $sizeMb).'
';
- $output = '' . __('Files to delete:', 'wp-addon') . '
' . $fileListHtml . $totalSizeHtml . '
';
+ $output = ''.__('Files to delete:', 'wp-addon').'
'.$fileListHtml.$totalSizeHtml.'
';
wp_die($output);
}
- public function cleanup(): void {
- if (!$this->isEnabled() || !current_user_can('manage_options')) {
+ public function cleanup(): void
+ {
+ if (! $this->isEnabled() || ! current_user_can('manage_options')) {
wp_die(__('Access denied.', 'wp-addon'));
}
check_ajax_referer('cleanup_images', 'nonce');
@@ -65,12 +70,13 @@ public function cleanup(): void {
}
$class = $deleteResult['errors'] > 0 ? 'notice-warning' : 'notice-success';
- $output = '';
+ $output = '';
wp_die($output);
}
- private function isEnabled(): bool {
+ private function isEnabled(): bool
+ {
$options = get_option('wp-addon', []);
return isset($options['media_cleanup_enabled'])
@@ -79,4 +85,4 @@ private function isEnabled(): bool {
// Not used since we have separate methods
public function handleAjax(): void {}
-}
\ No newline at end of file
+}
diff --git a/functions/PageCache.php b/functions/PageCache.php
index bd4d4d6..68a2895 100644
--- a/functions/PageCache.php
+++ b/functions/PageCache.php
@@ -4,208 +4,269 @@
use WpAddon\Services\CacheService;
use WpAddon\Services\OptionService;
-class PageCache implements ModuleInterface {
- private CacheService $cache;
- private OptionService $optionService;
- private array $config;
-
- public function __construct( OptionService $optionService ) {
- $this->optionService = $optionService;
- $this->loadConfig();
- $this->cache = new CacheService( $this->config['cache_dir'], $this->config['ttl'] );
- }
-
- private function loadConfig(): void {
- $defaultConfig = require RW_PLUGIN_DIR . 'src/Config/cache.php';
-
- $preloadPagesSetting = $this->optionService->getSetting( 'cache_preload_pages', '' );
- $preloadPages = [];
- if ( ! empty( $preloadPagesSetting ) ) {
- $preloadPages = array_filter( explode( "\n", $preloadPagesSetting ) );
- }
- // Если preload пустой - будет заполнен автоматически в preloadPages()
-
- $this->config = [
- 'enabled' => $this->optionService->getSetting( 'cache_enabled', $defaultConfig['enabled'] ),
- 'ttl' => (int) $this->optionService->getSetting( 'cache_ttl', $defaultConfig['ttl'] ),
- 'exclude_logged_in' => $this->optionService->getSetting( 'cache_exclude_logged_in', $defaultConfig['exclude_logged_in'] ),
- 'exclude_urls' => array_filter( explode( "\n", $this->optionService->getSetting( 'cache_exclude_urls', implode( "\n", $defaultConfig['exclude_urls'] ) ) ) ),
- 'preload_pages' => $preloadPages,
- 'auto_preload' => empty( $preloadPagesSetting ),
- 'clear_on_post_save' => $this->optionService->getSetting( 'cache_clear_on_post_save', true ),
- 'cache_dir' => $defaultConfig['cache_dir'],
- 'max_files' => (int) $defaultConfig['max_files'],
- 'cleanup_batch_size' => (int) $defaultConfig['cleanup_batch_size'],
- ];
- }
-
- public function init(): void {
- if ( ! $this->config['enabled'] ) {
- return;
- }
-
- add_action( 'init', [ $this, 'startCache' ] );
- if ( $this->config['clear_on_post_save'] ) {
- add_action( 'save_post', [ $this, 'clearCache' ] );
- }
- add_action( 'wp_loaded', [ $this, 'preloadPages' ] );
-
- // Preload and cleanup hooks.
- add_action( 'page_cache_preload', [ $this, 'doPreload' ] );
- add_action( 'page_cache_cleanup', [ $this, 'cleanupExpiredEntries' ] );
- }
-
- public function doPreload(): void {
- $preloadPagesSetting = $this->optionService->getSetting( 'cache_preload_pages', '' );
- $pages = [];
-
- if ( ! empty( $preloadPagesSetting ) ) {
- $pages = array_filter( explode( "\n", $preloadPagesSetting ) );
- } else {
- // Auto preload mode
- $pages = $this->getAutoPreloadPages();
- }
-
- if ( ! empty( $pages ) ) {
- foreach ( $pages as $url ) {
- $response = wp_remote_get( home_url( trim( $url ) ) );
- if ( ! is_wp_error( $response ) ) {
- $key = $this->cache->generateCacheKey( $url );
- $this->cache->saveCachedContent( $key, wp_remote_retrieve_body( $response ) );
- }
- }
- }
- }
-
- private function getAutoPreloadPages(): array {
- $pages = [];
-
- // Получаем главную страницу
- $frontPageId = get_option( 'page_on_front' );
- if ( $frontPageId ) {
- $frontPageUrl = get_permalink( $frontPageId );
- if ( $frontPageUrl ) {
- $pages[] = parse_url( $frontPageUrl, PHP_URL_PATH ) ?: '/';
- }
- } else {
- $pages[] = '/';
- }
-
- // Получаем страницы из главного меню
- $locations = get_nav_menu_locations();
- if ( isset( $locations['primary'] ) || isset( $locations['main'] ) ) {
- $menuId = $locations['primary'] ?? $locations['main'];
- $menuItems = wp_get_nav_menu_items( $menuId );
-
- if ( $menuItems ) {
- foreach ( $menuItems as $item ) {
- if ( $item->type === 'post_type' && $item->object === 'page' ) {
- $pageUrl = parse_url( $item->url, PHP_URL_PATH );
- if ( $pageUrl && $pageUrl !== '/' && ! in_array( $pageUrl, $pages ) ) {
- $pages[] = $pageUrl;
- }
- }
- }
- }
- }
-
- // Добавляем страницу блога, если она есть
- $blogPageId = get_option( 'page_for_posts' );
- if ( $blogPageId && $blogPageId !== $frontPageId ) {
- $blogUrl = get_permalink( $blogPageId );
- if ( $blogUrl ) {
- $blogPath = parse_url( $blogUrl, PHP_URL_PATH );
- if ( $blogPath && ! in_array( $blogPath, $pages ) ) {
- $pages[] = $blogPath;
- }
- }
- }
-
- return array_slice( $pages, 0, 10 ); // Ограничиваем до 10 страниц
- }
-
- public function preloadPages(): void {
- if ( ! wp_next_scheduled( 'page_cache_preload' ) ) {
- wp_schedule_event( time(), 'hourly', 'page_cache_preload' );
- }
-
- if ( ! wp_next_scheduled( 'page_cache_cleanup' ) ) {
- wp_schedule_event( time(), 'hourly', 'page_cache_cleanup' );
- }
- }
-
- public function cleanupExpiredEntries(): void {
- $this->cache->cleanup( $this->config['max_files'], $this->config['ttl'], $this->config['cleanup_batch_size'] );
- }
-
- public function startCache(): void {
- if ( ! $this->shouldCache() ) {
- return;
- }
-
- $key = $this->cache->generateCacheKey( $this->getCachePath() );
- $cached = $this->cache->getCachedContent( $key );
-
- if ( $cached ) {
- echo $cached;
- exit;
- }
-
- ob_start( [ $this, 'cacheOutput' ] );
- }
-
- public function shouldCache(): bool {
- if ( is_admin() || defined( 'DOING_AJAX' ) && DOING_AJAX ) {
- return false;
- }
-
- if ( isset( $_SERVER['REQUEST_METHOD'] ) && strtoupper( $_SERVER['REQUEST_METHOD'] ) !== 'GET' ) {
- return false;
- }
-
- if ( $this->config['exclude_logged_in'] && is_user_logged_in() ) {
- return false;
- }
-
- $url = $_SERVER['REQUEST_URI'];
- if ( strpos( $url, '?' ) !== false || defined( 'REST_REQUEST' ) && REST_REQUEST || defined( 'DOING_CRON' ) && DOING_CRON || defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST || is_feed() || is_search() || is_preview() ) {
- return false;
- }
-
- $custom_login_slug = get_option( 'whl_page' );
- if ( ! empty( $custom_login_slug ) ) {
- $custom_login_path = '/' . ltrim( $custom_login_slug, '/' );
- if ( strpos( $url, $custom_login_path ) === 0 || isset( $_GET[ $custom_login_slug ] ) ) {
- return false;
- }
- }
- foreach ( $this->config['exclude_urls'] as $exclude ) {
- if ( strpos( $url, trim( $exclude ) ) === 0 ) {
- return false;
- }
- }
-
- return true;
- }
-
- private function getCachePath(): string {
- return wp_parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ) ?: '/';
- }
-
- public function cacheOutput( string $content ): string {
- if ( $this->shouldCache() ) {
- $key = $this->cache->generateCacheKey( $this->getCachePath() );
- $this->cache->saveCachedContent( $key, $content );
- }
-
- return $content;
- }
-
- public function clearCache(): void {
- $this->cache->clearCache();
- }
-
- public function getExcludeRules(): array {
- return $this->config['exclude_urls'];
- }
+class PageCache implements ModuleInterface
+{
+ private CacheService $cache;
+
+ private OptionService $optionService;
+
+ private array $config;
+
+ public function __construct(OptionService $optionService)
+ {
+ $this->optionService = $optionService;
+ $this->loadConfig();
+ $this->cache = new CacheService($this->config['cache_dir'], $this->config['ttl']);
+ }
+
+ private function loadConfig(): void
+ {
+ $defaultConfig = require RW_PLUGIN_DIR.'src/Config/cache.php';
+
+ $preloadPagesSetting = $this->optionService->getSetting('cache_preload_pages', '');
+ $preloadPages = $defaultConfig['preload_pages'];
+ if (! empty($preloadPagesSetting)) {
+ $preloadPages = array_filter(explode("\n", $preloadPagesSetting));
+ }
+
+ $this->config = [
+ 'enabled' => $this->toBool($this->optionService->getSetting('cache_enabled', $defaultConfig['enabled'])),
+ 'ttl' => max(1, (int) $this->optionService->getSetting('cache_ttl', $defaultConfig['ttl'])),
+ 'exclude_logged_in' => $this->toBool($this->optionService->getSetting('cache_exclude_logged_in', $defaultConfig['exclude_logged_in'])),
+ 'exclude_urls' => array_filter(explode("\n", $this->optionService->getSetting('cache_exclude_urls', implode("\n", $defaultConfig['exclude_urls'])))),
+ 'preload_pages' => $preloadPages,
+ 'auto_preload' => empty($preloadPagesSetting) && empty($defaultConfig['preload_pages']),
+ 'clear_on_post_save' => $this->toBool($this->optionService->getSetting('cache_clear_on_post_save', true)),
+ 'cache_dir' => $defaultConfig['cache_dir'],
+ 'max_files' => (int) $defaultConfig['max_files'],
+ 'cleanup_batch_size' => (int) $defaultConfig['cleanup_batch_size'],
+ ];
+ }
+
+ private function toBool($value): bool
+ {
+ return filter_var($value, FILTER_VALIDATE_BOOLEAN);
+ }
+
+ public function init(): void
+ {
+ if (! $this->config['enabled']) {
+ return;
+ }
+
+ add_action('wp', [$this, 'startCache']);
+ if ($this->config['clear_on_post_save']) {
+ add_action('save_post', [$this, 'clearCache']);
+ }
+ add_action('wp_loaded', [$this, 'preloadPages']);
+
+ // Preload and cleanup hooks.
+ add_action('page_cache_preload', [$this, 'doPreload']);
+ add_action('page_cache_cleanup', [$this, 'cleanupExpiredEntries']);
+ }
+
+ public function doPreload(): void
+ {
+ $preloadPagesSetting = $this->optionService->getSetting('cache_preload_pages', '');
+ $pages = [];
+
+ if (! empty($preloadPagesSetting)) {
+ $pages = array_filter(explode("\n", $preloadPagesSetting));
+ } else {
+ // Auto preload mode
+ $pages = $this->getAutoPreloadPages();
+ }
+
+ if (! empty($pages)) {
+ foreach ($pages as $url) {
+ $path = $this->normalizePath($url);
+ if ($path === null) {
+ continue;
+ }
+
+ $response = wp_remote_get(home_url($path), ['timeout' => 10]);
+ $body = ! is_wp_error($response) ? wp_remote_retrieve_body($response) : '';
+ if (! is_wp_error($response) && wp_remote_retrieve_response_code($response) >= 200 && wp_remote_retrieve_response_code($response) < 300 && $body !== '') {
+ $key = $this->cache->generateCacheKey($path);
+ $this->cache->saveCachedContent($key, $body);
+ }
+ }
+ }
+ }
+
+ private function getAutoPreloadPages(): array
+ {
+ $pages = [];
+
+ // Получаем главную страницу
+ $frontPageId = get_option('page_on_front');
+ if ($frontPageId) {
+ $frontPageUrl = get_permalink($frontPageId);
+ if ($frontPageUrl) {
+ $pages[] = parse_url($frontPageUrl, PHP_URL_PATH) ?: '/';
+ }
+ } else {
+ $pages[] = '/';
+ }
+
+ // Получаем страницы из главного меню
+ $locations = get_nav_menu_locations();
+ if (isset($locations['primary']) || isset($locations['main'])) {
+ $menuId = $locations['primary'] ?? $locations['main'];
+ $menuItems = wp_get_nav_menu_items($menuId);
+
+ if ($menuItems) {
+ foreach ($menuItems as $item) {
+ if ($item->type === 'post_type' && $item->object === 'page') {
+ $pageUrl = parse_url($item->url, PHP_URL_PATH);
+ if ($pageUrl && $pageUrl !== '/' && ! in_array($pageUrl, $pages)) {
+ $pages[] = $pageUrl;
+ }
+ }
+ }
+ }
+ }
+
+ // Добавляем страницу блога, если она есть
+ $blogPageId = get_option('page_for_posts');
+ if ($blogPageId && $blogPageId !== $frontPageId) {
+ $blogUrl = get_permalink($blogPageId);
+ if ($blogUrl) {
+ $blogPath = parse_url($blogUrl, PHP_URL_PATH);
+ if ($blogPath && ! in_array($blogPath, $pages)) {
+ $pages[] = $blogPath;
+ }
+ }
+ }
+
+ return array_slice($pages, 0, 10); // Ограничиваем до 10 страниц
+ }
+
+ public function preloadPages(): void
+ {
+ if (! wp_next_scheduled('page_cache_preload')) {
+ wp_schedule_event(time(), 'hourly', 'page_cache_preload');
+ }
+
+ if (! wp_next_scheduled('page_cache_cleanup')) {
+ wp_schedule_event(time(), 'hourly', 'page_cache_cleanup');
+ }
+ }
+
+ public function cleanupExpiredEntries(): void
+ {
+ $this->cache->cleanup($this->config['max_files'], $this->config['ttl'], $this->config['cleanup_batch_size']);
+ }
+
+ public function startCache(): void
+ {
+ if (! $this->shouldCache()) {
+ return;
+ }
+
+ $path = $this->getCachePath();
+ if ($path === null) {
+ return;
+ }
+
+ $key = $this->cache->generateCacheKey($path);
+ $cached = $this->cache->getCachedContent($key);
+
+ if ($cached) {
+ echo $cached;
+ exit;
+ }
+
+ ob_start([$this, 'cacheOutput']);
+ }
+
+ public function shouldCache(): bool
+ {
+ if (is_admin() || wp_doing_ajax()) {
+ return false;
+ }
+
+ if (isset($_SERVER['REQUEST_METHOD']) && strtoupper($_SERVER['REQUEST_METHOD']) !== 'GET') {
+ return false;
+ }
+
+ if ($this->config['exclude_logged_in'] && is_user_logged_in()) {
+ return false;
+ }
+
+ $requestUri = $_SERVER['REQUEST_URI'] ?? null;
+ if (! is_string($requestUri) || strpos($requestUri, '?') !== false) {
+ return false;
+ }
+
+ $url = $this->getCachePath();
+ if ($url === null) {
+ return false;
+ }
+ if (defined('REST_REQUEST') && REST_REQUEST || wp_doing_cron() || defined('XMLRPC_REQUEST') && XMLRPC_REQUEST || is_feed() || is_search() || is_preview()) {
+ return false;
+ }
+
+ $custom_login_slug = get_option('whl_page');
+ if (! empty($custom_login_slug)) {
+ $custom_login_path = '/'.ltrim($custom_login_slug, '/');
+ if (strpos($url, $custom_login_path) === 0 || isset($_GET[$custom_login_slug])) {
+ return false;
+ }
+ }
+ foreach ($this->config['exclude_urls'] as $exclude) {
+ if (strpos($url, trim($exclude)) === 0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private function getCachePath(): ?string
+ {
+ return isset($_SERVER['REQUEST_URI']) ? $this->normalizePath($_SERVER['REQUEST_URI']) : null;
+ }
+
+ private function normalizePath(string $url): ?string
+ {
+ $url = trim($url);
+ if ($url === '') {
+ return null;
+ }
+
+ $path = wp_parse_url($url, PHP_URL_PATH);
+ if (! is_string($path) || $path === '') {
+ $path = '/';
+ }
+
+ return '/'.ltrim($path, '/');
+ }
+
+ public function cacheOutput(string $content): string
+ {
+ if ($this->shouldCache()) {
+ $path = $this->getCachePath();
+ if ($path !== null) {
+ $key = $this->cache->generateCacheKey($path);
+ $this->cache->saveCachedContent($key, $content);
+ }
+ }
+
+ return $content;
+ }
+
+ public function clearCache($postId = 0): void
+ {
+ if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || (function_exists('wp_is_post_revision') && wp_is_post_revision($postId))) {
+ return;
+ }
+
+ $this->cache->clearCache();
+ }
+
+ public function getExcludeRules(): array
+ {
+ return $this->config['exclude_urls'];
+ }
}
diff --git a/functions/Redirects.php b/functions/Redirects.php
index 171002f..7e96caa 100644
--- a/functions/Redirects.php
+++ b/functions/Redirects.php
@@ -3,19 +3,22 @@
use WpAddon\Interfaces\ModuleInterface;
use WpAddon\Traits\HookTrait;
-class Redirects implements ModuleInterface {
+class Redirects implements ModuleInterface
+{
use HookTrait;
- public function init(): void {
- if (!$this->isEnabled()) {
+ public function init(): void
+ {
+ if (! $this->isEnabled()) {
return;
}
$this->addHook('init', [$this, 'processRedirects'], 1);
}
- public function processRedirects(): void {
- if (!$this->isEnabled()) {
+ public function processRedirects(): void
+ {
+ if (! $this->isEnabled()) {
return;
}
@@ -28,7 +31,7 @@ public function processRedirects(): void {
$redirects = [];
foreach ($options['redirects_rules'] as $rule) {
- if (!empty($rule['request']) && !empty($rule['destination'])) {
+ if (! empty($rule['request']) && ! empty($rule['destination'])) {
$redirects[trim($rule['request'])] = trim($rule['destination']);
}
}
@@ -41,7 +44,7 @@ public function processRedirects(): void {
$userrequest = str_ireplace(get_option('home'), '', $this->getAddress());
$userrequest = rtrim($userrequest, '/');
- $wildcard = !empty($options['redirects_wildcard']);
+ $wildcard = ! empty($options['redirects_wildcard']);
$do_redirect = '';
// Check each redirect rule
@@ -53,7 +56,7 @@ public function processRedirects(): void {
if (strpos($userrequest, '/wp-login') !== 0 && strpos($userrequest, '/wp-admin') !== 0) {
// Make sure it gets all the proper decoding and rtrim action
$storedrequest = str_replace('*', '(.*)', $storedrequest);
- $pattern = '/^' . str_replace('/', '\/', rtrim($storedrequest, '/')) . '/';
+ $pattern = '/^'.str_replace('/', '\/', rtrim($storedrequest, '/')).'/';
$destination = str_replace('*', '$1', $destination);
$output = preg_replace($pattern, $destination, $userrequest);
if ($output !== $userrequest) {
@@ -70,10 +73,10 @@ public function processRedirects(): void {
if ($do_redirect !== '' && trim($do_redirect, '/') !== trim($userrequest, '/')) {
// Check if destination needs the domain prepended
if (strpos($do_redirect, '/') === 0) {
- $do_redirect = home_url() . $do_redirect;
+ $do_redirect = home_url().$do_redirect;
}
header('HTTP/1.1 301 Moved Permanently');
- header('Location: ' . $do_redirect);
+ header('Location: '.$do_redirect);
exit();
} else {
unset($redirects[$storedrequest]);
@@ -81,13 +84,15 @@ public function processRedirects(): void {
}
}
- private function isEnabled(): bool {
+ private function isEnabled(): bool
+ {
$options = get_option('wp-addon', []);
- return !array_key_exists('redirect_enable', $options) || $this->isTruthy($options['redirect_enable']);
+ return ! array_key_exists('redirect_enable', $options) || $this->isTruthy($options['redirect_enable']);
}
- private function isTruthy($value): bool {
+ private function isTruthy($value): bool
+ {
return $value === true || $value === 1 || $value === '1' || $value === 'true';
}
@@ -95,17 +100,21 @@ private function isTruthy($value): bool {
* Get the full address of the current request
* Credit: http://www.phpro.org/examples/Get-Full-URL.html
*/
- private function getAddress(): string {
- // Return the full address
- return $this->getProtocol() . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
+ private function getAddress(): string
+ {
+ $host = $_SERVER['HTTP_HOST'] ?? '';
+ $requestUri = $_SERVER['REQUEST_URI'] ?? '/';
+
+ return $this->getProtocol().'://'.$host.$requestUri;
}
- private function getProtocol(): string {
+ private function getProtocol(): string
+ {
// Set the base protocol to http
$protocol = 'http';
// Check for https
- if (isset($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on") {
- $protocol .= "s";
+ if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') {
+ $protocol .= 's';
}
return $protocol;
diff --git a/functions/TinyMCE/bootstrap-shortcodes.php b/functions/TinyMCE/bootstrap-shortcodes.php
index e2a2060..943d051 100644
--- a/functions/TinyMCE/bootstrap-shortcodes.php
+++ b/functions/TinyMCE/bootstrap-shortcodes.php
@@ -1,62 +1,59 @@
name = 'bootstrap';
- add_action('admin_head', [$this, 'show']);
- add_filter('mce_css', [$this, 'add_mce_css']);
- add_action('admin_footer', [$this, 'get_shortcodes']);
+ add_action('admin_head', [$this, 'show']);
+ add_filter('mce_css', [$this, 'add_mce_css']);
+ add_action('admin_footer', [$this, 'get_shortcodes']);
}
-
public function show()
{
// check user permissions
- if ( ! current_user_can( 'edit_posts' ) ) {
+ if (! current_user_can('edit_posts')) {
return;
}
- if ('true' === get_user_option( 'rich_editing' )) { // check if WYSIWYG is enabled
- add_filter( 'mce_external_plugins', [$this, 'add_js_mce'], 20, 1 );
- add_filter( 'mce_buttons_3', [$this, 'register_mce_button'] );
+ if (get_user_option('rich_editing') === 'true') { // check if WYSIWYG is enabled
+ add_filter('mce_external_plugins', [$this, 'add_js_mce'], 20, 1);
+ add_filter('mce_buttons_3', [$this, 'register_mce_button']);
}
}
/**
* Add JS
- *
- * @param $plugin_array
- * @return array
*/
public function add_js_mce($plugin_array): array
{
- $arr['bootstrap'] = RW_PLUGIN_URL . 'assets/js/tinymce/bootstrap.js';
+ $arr['bootstrap'] = RW_PLUGIN_URL.'assets/js/tinymce/bootstrap.js';
+
return $plugin_array + $arr;
}
/**
* Register new button in the editor
*
- * @param $buttons array
- * @return array
+ * @param $buttons array
*/
public function register_mce_button(array $buttons): array
{
$buttons[] = $this->name;
+
return $buttons;
}
/**
* Show all shortcodes in JS
+ *
* @unused
*/
public function get_shortcodes()
@@ -65,49 +62,46 @@ public function get_shortcodes()
>>>>>>>>>>>>>>> */
/**
* Disable the new block editor (Gutenberg) completely.
@@ -26,7 +26,7 @@ function disable_guttenberg()
add_filter('use_widgets_block_editor', '__return_false');
// Удалить стили и скрипты Gutenberg из фронтенда
- add_action('wp_enqueue_scripts', function() {
+ add_action('wp_enqueue_scripts', function () {
wp_dequeue_style('wp-block-library');
wp_dequeue_style('wp-block-library-theme');
wp_dequeue_style('wc-blocks-style');
@@ -34,7 +34,7 @@ function disable_guttenberg()
}, 100);
// Удалить стили Gutenberg из админки
- add_action('admin_enqueue_scripts', function() {
+ add_action('admin_enqueue_scripts', function () {
wp_dequeue_style('wp-block-library');
wp_dequeue_style('wp-block-library-theme');
});
@@ -49,4 +49,4 @@ function disable_guttenberg()
add_action('edit_form_after_title', ['WP_Privacy_Policy_Content', 'notice']);
});
}
-endif;
\ No newline at end of file
+}
diff --git a/functions/TinyMCE/plugins.php b/functions/TinyMCE/plugins.php
index 1813c7f..5b037a0 100644
--- a/functions/TinyMCE/plugins.php
+++ b/functions/TinyMCE/plugins.php
@@ -3,7 +3,6 @@
* Adv
*/
-
/*newdocument
bold
italic
@@ -96,26 +95,26 @@
function tiny_advanced()
{
- add_filter('tiny_mce_before_init', function( $in ) {
+ add_filter('tiny_mce_before_init', function ($in) {
$in['font_formats'] = 'Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Courier New=courier new,courier;';
$in['toolbar1'] = 'insertfile undo redo | blockquote styleselect | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify alignnone | bullist numlist outdent indent | link image | print preview media fullpage | forecolor backcolor emoticons | wp_more';
- /* if(class_exists('\JsonFileManager\Model\JsonFile')) {
- $file = new \JsonFileManager\Model\JsonFile(null,null,'buttons.json',
- ['basedir' => RW_PLUGIN_DIR . 'functions/TinyMCE/',
- 'baseurl' => RW_PLUGIN_URL . 'functions/TinyMCE/',
- ]);
- $buttons = $file->read();
- if(!empty($buttons)){
- $in['toolbar2'] = '';
- foreach ($buttons as $button){
- if( false == strpos($in['toolbar1'], $button['control']) ){
- $in['toolbar2'] .= $button['control'] . ' ';
- }
- }
- }
- }*/
+ /* if(class_exists('\JsonFileManager\Model\JsonFile')) {
+ $file = new \JsonFileManager\Model\JsonFile(null,null,'buttons.json',
+ ['basedir' => RW_PLUGIN_DIR . 'functions/TinyMCE/',
+ 'baseurl' => RW_PLUGIN_URL . 'functions/TinyMCE/',
+ ]);
+ $buttons = $file->read();
+ if(!empty($buttons)){
+ $in['toolbar2'] = '';
+ foreach ($buttons as $button){
+ if( false == strpos($in['toolbar1'], $button['control']) ){
+ $in['toolbar2'] .= $button['control'] . ' ';
+ }
+ }
+ }
+ }*/
$in['toolbar2'] = 'formatselect fontselect fontsizeselect | table | subscript superscript removeformat | insert unlink openlink charmap code | cut copy paste pastetext';
$in['fontsize_formats'] = '10px 12px 14px 15px 18px 20px 24px 28px 30px 32px 36px 48px';
@@ -126,10 +125,10 @@ function tiny_advanced()
}, 9, 1);
// Add Google Scripts for use with the editor
- add_action('init', function(){
+ add_action('init', function () {
$fonts_url = [
'https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800',
- 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'
+ 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css',
];
foreach ($fonts_url as $font_url) {
add_editor_style(str_replace(',', '%2C', $font_url));
@@ -137,24 +136,25 @@ function tiny_advanced()
});
}
-
function tiny_table_plugin()
{
- add_filter('mce_buttons_2', function($buttons){
- array_push($buttons, 'separator', '| table |' );
+ add_filter('mce_buttons_2', function ($buttons) {
+ array_push($buttons, 'separator', '| table |');
+
return $buttons;
}, 10, 1);
- add_filter('mce_external_plugins', function($plugins){
+ add_filter('mce_external_plugins', function ($plugins) {
global $tinymce_version;
- $plugins['icofonts'] = RW_PLUGIN_URL . 'functions/TinyMCE/plugins/icofonts/plugin.min.js';
- $plugins['table'] = RW_PLUGIN_URL . 'functions/TinyMCE/plugins/table/plugin.min.js';
+ $plugins['icofonts'] = RW_PLUGIN_URL.'functions/TinyMCE/plugins/icofonts/plugin.min.js';
+ $plugins['table'] = RW_PLUGIN_URL.'functions/TinyMCE/plugins/table/plugin.min.js';
+
return $plugins;
}, 10, 1);
- add_filter('tiny_mce_before_init', function ( $settings, $editor_id){
+ add_filter('tiny_mce_before_init', function ($settings, $editor_id) {
- //$tinymce_settings['menubar'] = true;
+ // $tinymce_settings['menubar'] = true;
/*$tinymce_settings = [
'table_tab_navigation' => false,
'table_resize_bars' => false,
@@ -217,8 +217,7 @@ function tiny_table_plugin()
return array_merge($settings, $tinymce_settings);
}, 10, 2);
-
- add_action('admin_footer', function (){
+ add_action('admin_footer', function () {
?>
+ ?>
true], 'names');
- if ( ! $post_types) {
+ if (! $post_types) {
return null;
}
unset($post_types['attachment']);
- $post_types = "'" . implode("','", $post_types) . "'";
- $SQL = "SELECT ID, post_date, post_title, guid
+ $post_types = "'".implode("','", $post_types)."'";
+ $SQL = "SELECT ID, post_date, post_title, guid
FROM $wpdb->posts p
WHERE p.post_type IN ($post_types)
AND p.post_status = 'publish'";
- $results = $wpdb->get_results($SQL);
+ $results = $wpdb->get_results($SQL);
- if ( ! $results) {
- return print ("Запрос вернул пустой результат");
+ if (! $results) {
+ return print 'Запрос вернул пустой результат';
}
- //Обновить все поля Guid в БД таблице posts.
+ // Обновить все поля Guid в БД таблице posts.
if ($action == 'update') {
echo "
№ / ID / guid
@@ -146,9 +145,9 @@ function krg_guid($action)
echo "
Не обнволено: id: $reslt->ID: $permalink ";
}
}
- echo "
";
+ echo ' ';
- } //Посмотреть все поля Guid в БД таблице posts.
+ } // Посмотреть все поля Guid в БД таблице posts.
elseif ($action == 'look') {
echo "
@@ -161,16 +160,15 @@ function krg_guid($action)
(strpos($guid, '?p=')
|| strpos($guid,
- '?page_id=')) !== false ? $style = " style='color:#f00;'" : $style = " style='color:green;'";
+ '?page_id=')) !== false ? $style = " style='color:#f00;'" : $style = " style='color:green;'";
echo "
id: $ID $guid ";
}
- echo "
";
+ echo '';
}
}
-
/* ========= РЕВИЗИИ ========= */
/* Удалить все ревизии и соответствующие им поля в таблицах term_relationships и postmeta
------------------------------------------------------- */
@@ -189,23 +187,21 @@ function delete_all_revision()
echo "Все ревизии были удалены из БД posts и соответствующие им поля в таблицах term_relationships, postmeta и wp_comments ";
}
-
/* Посмотреть все ревизии
-------------------------------------------------------- */
function look_all_revision()
{
global $wpdb;
- if ( ! $results = $wpdb->get_results("SELECT ID, post_date, post_title, post_status, guid, post_type FROM $wpdb->posts WHERE post_type = 'revision'")) {
- return print("Ревизий не найдено. Запрос вернул пустой результат ");
+ if (! $results = $wpdb->get_results("SELECT ID, post_date, post_title, post_status, guid, post_type FROM $wpdb->posts WHERE post_type = 'revision'")) {
+ return print "Ревизий не найдено. Запрос вернул пустой результат ";
}
- $d = 0; $rrr = '';
+ $d = 0;
+ $rrr = '';
foreach ($results as $reslt) {
- $rrr .= "" . ++$d . ". id: {$reslt->ID} | guid: {$reslt->guid} ";
+ $rrr .= "".++$d.". id: {$reslt->ID} | guid: {$reslt->guid} ";
}
echo "";
}
}
-
-
diff --git a/functions/posts/post-excerpt.php b/functions/posts/post-excerpt.php
index a3d55c8..10c9a02 100644
--- a/functions/posts/post-excerpt.php
+++ b/functions/posts/post-excerpt.php
@@ -1,30 +1,28 @@
181) {
+ $excerpt = preg_replace('( [.*?])', '', $excerpt);
+ $excerpt = mb_substr($excerpt, 0, 180, 'UTF-8');
+ $excerpt = mb_substr($excerpt, 0, strripos($excerpt, ' '), 'UTF-8');
+ $excerpt = trim(preg_replace('/\s+/', ' ', $excerpt));
+ $excerpt .= '...';
+ }
- if( 181 < mb_strlen($excerpt, 'UTF-8') ){
- $excerpt = preg_replace( '( [.*?])','',$excerpt);
- $excerpt = mb_substr($excerpt, 0, 180, 'UTF-8');
- $excerpt = mb_substr($excerpt, 0, strripos($excerpt, ' ' ), 'UTF-8');
- $excerpt = trim(preg_replace( '/\s+/', ' ', $excerpt));
- $excerpt .= '...';
+ return $excerpt;
}
- return $excerpt;
+ add_filter('get_the_excerpt', 'change_excerpt_length', 10, 2);
}
- add_filter('get_the_excerpt', 'change_excerpt_length', 10, 2);
}
-endif;
\ No newline at end of file
diff --git a/functions/posts/show-id.php b/functions/posts/show-id.php
index a62a41d..53f35c5 100644
--- a/functions/posts/show-id.php
+++ b/functions/posts/show-id.php
@@ -1,13 +1,14 @@
';
}
-}
\ No newline at end of file
+}
diff --git a/functions/posts/show_symbols.php b/functions/posts/show_symbols.php
index d86127b..173663e 100644
--- a/functions/posts/show_symbols.php
+++ b/functions/posts/show_symbols.php
@@ -1,9 +1,10 @@
id ){
+ if (! isset($screen) || $screen->id !== 'post') {
return;
}
?>
@@ -28,4 +29,4 @@ function show_symbols(){
parent) {
+ if ($taxonomy !== 'post_tag' || ! $term->parent) {
return $termlink;
}
@@ -44,12 +44,12 @@ public function hierarchical_tag_link($termlink, $term, $taxonomy)
$slug = $term->slug;
if ($term->parent) {
$parents = $this->get_tag_parents($term->parent, false, '/', true);
- if (!is_wp_error($parents)) {
- $slug = $parents . $slug;
+ if (! is_wp_error($parents)) {
+ $slug = $parents.$slug;
}
}
- return home_url(user_trailingslashit($tag_base . '/' . $slug, 'category'));
+ return home_url(user_trailingslashit($tag_base.'/'.$slug, 'category'));
}
/**
@@ -70,6 +70,7 @@ public function flush()
if (get_option('flush_rewrite_tags')) {
add_action('shutdown', 'flush_rewrite_rules');
delete_option('flush_rewrite_tags');
+
return true;
}
@@ -79,7 +80,7 @@ public function flush()
/**
* Generate rewrite rules for hierarchical tags.
*
- * @param array $tag_rewrite Existing tag rewrite rules.
+ * @param array $tag_rewrite Existing tag rewrite rules.
* @return array Modified tag rewrite rules.
*/
public function tag_rewrite_rules($tag_rewrite)
@@ -87,9 +88,9 @@ public function tag_rewrite_rules($tag_rewrite)
global $wp_rewrite;
$new_tag_rewrite = [];
-
+
$taxonomy = get_taxonomy('post_tag');
- if (!$taxonomy || !isset($taxonomy->rewrite['hierarchical']) || !$taxonomy->rewrite['hierarchical']) {
+ if (! $taxonomy || ! isset($taxonomy->rewrite['hierarchical']) || ! $taxonomy->rewrite['hierarchical']) {
return $tag_rewrite;
}
@@ -97,24 +98,24 @@ public function tag_rewrite_rules($tag_rewrite)
if (empty($tag_base)) {
$tag_base = 'tag';
}
-
+
$tag_base = trim($tag_base, '/');
$tags = get_terms([
- 'taxonomy' => 'post_tag',
+ 'taxonomy' => 'post_tag',
'hide_empty' => false,
]);
- if (is_array($tags) && !empty($tags)) {
+ if (is_array($tags) && ! empty($tags)) {
foreach ($tags as $tag) {
$tag_nicename = $tag->slug;
-
+
if ($tag->parent === $tag->term_id) {
$tag->parent = 0;
} elseif ($tag->parent !== 0) {
$parents = $this->get_tag_parents($tag->parent, false, '/', true);
- if (!is_wp_error($parents)) {
- $tag_nicename = $parents . $tag_nicename;
+ if (! is_wp_error($parents)) {
+ $tag_nicename = $parents.$tag_nicename;
}
unset($parents);
}
@@ -146,15 +147,15 @@ public function tag_rewrite_rules($tag_rewrite)
/**
* Get tag parents path.
*
- * @param int $id Tag ID.
- * @param bool $link Whether to format with link.
- * @param string $separator Path separator.
- * @param bool $nicename Whether to use nice name for display.
+ * @param int $id Tag ID.
+ * @param bool $link Whether to format with link.
+ * @param string $separator Path separator.
+ * @param bool $nicename Whether to use nice name for display.
* @return string|WP_Error Tag parents path or WP_Error on failure.
*/
protected function get_tag_parents($id, $link = false, $separator = '/', $nicename = false)
{
- $chain = '';
+ $chain = '';
$parent = get_term($id, 'post_tag');
if (is_wp_error($parent)) {
@@ -172,9 +173,9 @@ protected function get_tag_parents($id, $link = false, $separator = '/', $nicena
}
if ($link) {
- $chain .= '' . $name . ' ' . $separator;
+ $chain .= ''.$name.' '.$separator;
} else {
- $chain .= $name . $separator;
+ $chain .= $name.$separator;
}
return $chain;
@@ -183,23 +184,23 @@ protected function get_tag_parents($id, $link = false, $separator = '/', $nicena
/**
* Adds required tag rewrite rules.
*
- * @param array $rewrites The current set of rules.
- * @param string $tag_name Tag nicename (hierarchical path).
- * @param string $tag_base Tag base.
- * @param string $pagination_base WP_Query pagination base.
+ * @param array $rewrites The current set of rules.
+ * @param string $tag_name Tag nicename (hierarchical path).
+ * @param string $tag_base Tag base.
+ * @param string $pagination_base WP_Query pagination base.
* @return array The added set of rules.
*/
protected function add_tag_rewrites($rewrites, $tag_name, $tag_base, $pagination_base)
{
- $rewrite_name = $tag_base . '/(' . $tag_name . ')';
-
+ $rewrite_name = $tag_base.'/('.$tag_name.')';
+
// Extract the actual slug from the hierarchical path (e.g. 'git/submodules' -> 'submodules')
$parts = explode('/', $tag_name);
$actual_slug = end($parts);
- $rewrites[$rewrite_name . '/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?tag=' . $actual_slug . '&feed=$matches[2]';
- $rewrites[$rewrite_name . '/' . $pagination_base . '/?([0-9]{1,})/?$'] = 'index.php?tag=' . $actual_slug . '&paged=$matches[2]';
- $rewrites[$rewrite_name . '/?$'] = 'index.php?tag=' . $actual_slug;
+ $rewrites[$rewrite_name.'/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?tag='.$actual_slug.'&feed=$matches[2]';
+ $rewrites[$rewrite_name.'/'.$pagination_base.'/?([0-9]{1,})/?$'] = 'index.php?tag='.$actual_slug.'&paged=$matches[2]';
+ $rewrites[$rewrite_name.'/?$'] = 'index.php?tag='.$actual_slug;
return $rewrites;
}
@@ -207,7 +208,7 @@ protected function add_tag_rewrites($rewrites, $tag_name, $tag_base, $pagination
/**
* Walks through tag nicename and convert encoded parts into uppercase.
*
- * @param string $name The encoded tag URI string.
+ * @param string $name The encoded tag URI string.
* @return string The converted URI string.
*/
protected function convert_encoded_to_upper($name)
@@ -225,7 +226,7 @@ protected function convert_encoded_to_upper($name)
/**
* Converts the encoded URI string to uppercase.
*
- * @param string $encoded The encoded string.
+ * @param string $encoded The encoded string.
* @return string The uppercased string.
*/
public function encode_to_upper($encoded)
@@ -242,7 +243,8 @@ function hierarchical_tags_rewrite()
{
static $instance = null;
if ($instance === null) {
- $instance = new HierarchicalTagsRewrite();
+ $instance = new HierarchicalTagsRewrite;
}
+
return $instance;
}
diff --git a/functions/seo/RemoveCategoryURL.php b/functions/seo/RemoveCategoryURL.php
index 4b596c2..b8c76c1 100644
--- a/functions/seo/RemoveCategoryURL.php
+++ b/functions/seo/RemoveCategoryURL.php
@@ -1,4 +1,5 @@
redirect( $query_vars['category_redirect'] );
+ $this->redirect($query_vars['category_redirect']);
}
/**
@@ -114,52 +119,52 @@ public function request( $query_vars ) {
*
* @return array
*/
- public function category_rewrite_rules() {
+ public function category_rewrite_rules()
+ {
global $wp_rewrite;
$category_rewrite = [];
- $taxonomy = get_taxonomy( 'category' );
- $permalink_structure = get_option( 'permalink_structure' );
+ $taxonomy = get_taxonomy('category');
+ $permalink_structure = get_option('permalink_structure');
$blog_prefix = '';
- if ( is_multisite() && ! is_subdomain_install() && is_main_site() && strpos( $permalink_structure, '/blog/' ) === 0 ) {
+ if (is_multisite() && ! is_subdomain_install() && is_main_site() && strpos($permalink_structure, '/blog/') === 0) {
$blog_prefix = 'blog/';
}
- $categories = get_categories( [ 'hide_empty' => false ] );
- if ( is_array( $categories ) && $categories !== [] ) {
- foreach ( $categories as $category ) {
+ $categories = get_categories(['hide_empty' => false]);
+ if (is_array($categories) && $categories !== []) {
+ foreach ($categories as $category) {
$category_nicename = $category->slug;
- if ( $category->parent === $category->cat_ID ) {
+ if ($category->parent === $category->cat_ID) {
// Recursive recursion.
$category->parent = 0;
- }
- elseif ( $taxonomy->rewrite['hierarchical'] !== false && $category->parent !== 0 ) {
- $parents = get_category_parents( $category->parent, false, '/', true );
- if ( ! is_wp_error( $parents ) ) {
- $category_nicename = $parents . $category_nicename;
+ } elseif ($taxonomy->rewrite['hierarchical'] !== false && $category->parent !== 0) {
+ $parents = get_category_parents($category->parent, false, '/', true);
+ if (! is_wp_error($parents)) {
+ $category_nicename = $parents.$category_nicename;
}
- unset( $parents );
+ unset($parents);
}
- $category_rewrite = $this->add_category_rewrites( $category_rewrite, $category_nicename, $blog_prefix, $wp_rewrite->pagination_base );
+ $category_rewrite = $this->add_category_rewrites($category_rewrite, $category_nicename, $blog_prefix, $wp_rewrite->pagination_base);
// Adds rules for the uppercase encoded URIs.
- $category_nicename_filtered = $this->convert_encoded_to_upper( $category_nicename );
+ $category_nicename_filtered = $this->convert_encoded_to_upper($category_nicename);
- if ( $category_nicename_filtered !== $category_nicename ) {
- $category_rewrite = $this->add_category_rewrites( $category_rewrite, $category_nicename_filtered, $blog_prefix, $wp_rewrite->pagination_base );
+ if ($category_nicename_filtered !== $category_nicename) {
+ $category_rewrite = $this->add_category_rewrites($category_rewrite, $category_nicename_filtered, $blog_prefix, $wp_rewrite->pagination_base);
}
}
- unset( $categories, $category, $category_nicename, $category_nicename_filtered );
+ unset($categories, $category, $category_nicename, $category_nicename_filtered);
}
// Redirect support from Old Category Base.
- $old_base = $wp_rewrite->get_category_permastruct();
- $old_base = str_replace( '%category%', '(.+)', $old_base );
- $old_base = trim( $old_base, '/' );
- $category_rewrite[ $old_base . '$' ] = 'index.php?category_redirect=$matches[1]';
+ $old_base = $wp_rewrite->get_category_permastruct();
+ $old_base = str_replace('%category%', '(.+)', $old_base);
+ $old_base = trim($old_base, '/');
+ $category_rewrite[$old_base.'$'] = 'index.php?category_redirect=$matches[1]';
return $category_rewrite;
}
@@ -167,19 +172,19 @@ public function category_rewrite_rules() {
/**
* Adds required category rewrites rules.
*
- * @param array $rewrites The current set of rules.
- * @param string $category_name Category nicename.
- * @param string $blog_prefix Multisite blog prefix.
- * @param string $pagination_base WP_Query pagination base.
- *
+ * @param array $rewrites The current set of rules.
+ * @param string $category_name Category nicename.
+ * @param string $blog_prefix Multisite blog prefix.
+ * @param string $pagination_base WP_Query pagination base.
* @return array The added set of rules.
*/
- protected function add_category_rewrites( $rewrites, $category_name, $blog_prefix, $pagination_base ) {
- $rewrite_name = $blog_prefix . '(' . $category_name . ')';
+ protected function add_category_rewrites($rewrites, $category_name, $blog_prefix, $pagination_base)
+ {
+ $rewrite_name = $blog_prefix.'('.$category_name.')';
- $rewrites[ $rewrite_name . '/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?category_name=$matches[1]&feed=$matches[2]';
- $rewrites[ $rewrite_name . '/' . $pagination_base . '/?([0-9]{1,})/?$' ] = 'index.php?category_name=$matches[1]&paged=$matches[2]';
- $rewrites[ $rewrite_name . '/?$' ] = 'index.php?category_name=$matches[1]';
+ $rewrites[$rewrite_name.'/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?category_name=$matches[1]&feed=$matches[2]';
+ $rewrites[$rewrite_name.'/'.$pagination_base.'/?([0-9]{1,})/?$'] = 'index.php?category_name=$matches[1]&paged=$matches[2]';
+ $rewrites[$rewrite_name.'/?$'] = 'index.php?category_name=$matches[1]';
return $rewrites;
}
@@ -188,35 +193,35 @@ protected function add_category_rewrites( $rewrites, $category_name, $blog_prefi
* Walks through category nicename and convert encoded parts
* into uppercase using $this->encode_to_upper().
*
- * @param string $name The encoded category URI string.
- *
+ * @param string $name The encoded category URI string.
* @return string The convered URI string.
*/
- protected function convert_encoded_to_upper( $name ) {
+ protected function convert_encoded_to_upper($name)
+ {
// Checks if name has any encoding in it.
- if ( strpos( $name, '%' ) === false ) {
+ if (strpos($name, '%') === false) {
return $name;
}
- $names = explode( '/', $name );
- $names = array_map( [ $this, 'encode_to_upper' ], $names );
+ $names = explode('/', $name);
+ $names = array_map([$this, 'encode_to_upper'], $names);
- return implode( '/', $names );
+ return implode('/', $names);
}
/**
* Converts the encoded URI string to uppercase.
*
- * @param string $encoded The encoded string.
- *
+ * @param string $encoded The encoded string.
* @return string The uppercased string.
*/
- public function encode_to_upper( $encoded ) {
- if ( strpos( $encoded, '%' ) === false ) {
+ public function encode_to_upper($encoded)
+ {
+ if (strpos($encoded, '%') === false) {
return $encoded;
}
- return strtoupper( $encoded );
+ return strtoupper($encoded);
}
/**
@@ -224,16 +229,18 @@ public function encode_to_upper( $encoded ) {
*
* @codeCoverageIgnore
*
- * @param string $category_redirect The category page to redirect to.
+ * @param string $category_redirect The category page to redirect to.
* @return void
*/
- protected function redirect( $category_redirect ) {
- $catlink = trailingslashit( get_option( 'home' ) ) . user_trailingslashit( $category_redirect, 'category' );
- wp_safe_redirect( $catlink, 301, 'RW-ADDON' );
+ protected function redirect($category_redirect)
+ {
+ $catlink = trailingslashit(get_option('home')).user_trailingslashit($category_redirect, 'category');
+ wp_safe_redirect($catlink, 301, 'RW-ADDON');
exit;
}
}
-function remove_category_url(){
- return new RemoveCategoryURL();
-}
\ No newline at end of file
+function remove_category_url()
+{
+ return new RemoveCategoryURL;
+}
diff --git a/functions/seo/seo.php b/functions/seo/seo.php
index 60987fa..185c6d8 100644
--- a/functions/seo/seo.php
+++ b/functions/seo/seo.php
@@ -1,4 +1,5 @@
'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't',
'у' => 'u', 'ў' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'ts',
'ч' => 'ch', 'џ' => 'dh', 'ш' => 'sh', 'щ' => 'shh', 'ъ' => '',
- 'ы' => 'y', 'ь' => '', 'э' => 'e', 'ю' => 'yu', 'я' => 'ya'
+ 'ы' => 'y', 'ь' => '', 'э' => 'e', 'ю' => 'yu', 'я' => 'ya',
];
$geo2lat = [
'ა' => 'a', 'ბ' => 'b', 'გ' => 'g', 'დ' => 'd', 'ე' => 'e', 'ვ' => 'v',
'ზ' => 'z', 'თ' => 'th', 'ი' => 'i', 'კ' => 'k', 'ლ' => 'l', 'მ' => 'm',
- 'ნ' => 'n', 'ო' => 'o', 'პ' => 'p','ჟ' => 'zh','რ' => 'r','ს' => 's',
- 'ტ' => 't','უ' => 'u','ფ' => 'ph','ქ' => 'q','ღ' => 'gh','ყ' => 'qh',
- 'შ' => 'sh','ჩ' => 'ch','ც' => 'ts','ძ' => 'dz','წ' => 'ts','ჭ' => 'tch',
- 'ხ' => 'kh','ჯ' => 'j','ჰ' => 'h'
+ 'ნ' => 'n', 'ო' => 'o', 'პ' => 'p', 'ჟ' => 'zh', 'რ' => 'r', 'ს' => 's',
+ 'ტ' => 't', 'უ' => 'u', 'ფ' => 'ph', 'ქ' => 'q', 'ღ' => 'gh', 'ყ' => 'qh',
+ 'შ' => 'sh', 'ჩ' => 'ch', 'ც' => 'ts', 'ძ' => 'dz', 'წ' => 'ts', 'ჭ' => 'tch',
+ 'ხ' => 'kh', 'ჯ' => 'j', 'ჰ' => 'h',
];
$iso9_table = array_merge($iso9_table, $geo2lat);
$locale = get_locale();
- switch ( $locale ) {
+ switch ($locale) {
case 'bg_BG':
$iso9_table['Щ'] = 'SHT';
$iso9_table['щ'] = 'sht';
@@ -72,8 +76,8 @@ function cyr_to_lat($title) {
$is_term = false;
$backtrace = debug_backtrace();
- foreach ( $backtrace as $backtrace_entry ) {
- if ( $backtrace_entry['function'] === 'wp_insert_term' ) {
+ foreach ($backtrace as $backtrace_entry) {
+ if ($backtrace_entry['function'] === 'wp_insert_term') {
$is_term = true;
break;
}
@@ -81,57 +85,59 @@ function cyr_to_lat($title) {
$term = $is_term ? $wpdb->get_var("SELECT slug FROM {$wpdb->terms} WHERE name = '$title'") : '';
- if ( !empty($term) ) {
+ if (! empty($term)) {
$title = $term;
} else {
- $title = strtr($title, apply_filters('ctl_table', $iso9_table));
- if (function_exists('iconv')){
- $title = iconv('UTF-8', 'UTF-8//TRANSLIT//IGNORE', $title);
- }
- $title = preg_replace("/[^A-Za-z0-9'_\-\.]/", '-', $title);
- $title = preg_replace('/\-+/', '-', $title);
- $title = preg_replace('/^-+/', '', $title);
- $title = preg_replace('/-+$/', '', $title);
- $title = strtolower($title);
- }
+ $title = strtr($title, apply_filters('ctl_table', $iso9_table));
+ if (function_exists('iconv')) {
+ $title = iconv('UTF-8', 'UTF-8//TRANSLIT//IGNORE', $title);
+ }
+ $title = preg_replace("/[^A-Za-z0-9'_\-\.]/", '-', $title);
+ $title = preg_replace('/\-+/', '-', $title);
+ $title = preg_replace('/^-+/', '', $title);
+ $title = preg_replace('/-+$/', '', $title);
+ $title = strtolower($title);
+ }
return $title;
}
add_filter('sanitize_title', 'cyr_to_lat', 9);
add_filter('sanitize_file_name', 'cyr_to_lat', 9);
- function ctl_convert_existing_slugs() {
+ function ctl_convert_existing_slugs()
+ {
global $wpdb;
$posts = $wpdb->get_results("SELECT ID, post_name FROM {$wpdb->posts} WHERE post_name REGEXP('[^A-Za-z0-9\-]+') AND post_status IN ('publish', 'future', 'private')");
- foreach ( (array) $posts as $post ) {
+ foreach ((array) $posts as $post) {
$sanitized_name = sanitize_title(urldecode($post->post_name));
- if ( $post->post_name != $sanitized_name ) {
+ if ($post->post_name != $sanitized_name) {
add_post_meta($post->ID, '_wp_old_slug', $post->post_name);
- $wpdb->update($wpdb->posts, array( 'post_name' => $sanitized_name ), array( 'ID' => $post->ID ));
+ $wpdb->update($wpdb->posts, ['post_name' => $sanitized_name], ['ID' => $post->ID]);
}
}
$terms = $wpdb->get_results("SELECT term_id, slug FROM {$wpdb->terms} WHERE slug REGEXP('[^A-Za-z0-9\-]+') ");
- foreach ( (array) $terms as $term ) {
+ foreach ((array) $terms as $term) {
$sanitized_slug = sanitize_title(urldecode($term->slug));
- if ( $term->slug != $sanitized_slug ) {
- $wpdb->update($wpdb->terms, array( 'slug' => $sanitized_slug ), array( 'term_id' => $term->term_id ));
+ if ($term->slug != $sanitized_slug) {
+ $wpdb->update($wpdb->terms, ['slug' => $sanitized_slug], ['term_id' => $term->term_id]);
}
}
}
- function ctl_schedule_conversion() {
+ function ctl_schedule_conversion()
+ {
add_action('shutdown', 'ctl_convert_existing_slugs');
}
}
-
/**
* Выключить индексацию. Убирает страницы из поисковой выдачи.
*/
-function index_disable(){
- add_action('wp_head', static function (){
+function index_disable()
+{
+ add_action('wp_head', static function () {
echo ' ';
});
}
diff --git a/functions/shortcodes/FAQ.php b/functions/shortcodes/FAQ.php
index e0af443..53e8abd 100644
--- a/functions/shortcodes/FAQ.php
+++ b/functions/shortcodes/FAQ.php
@@ -10,44 +10,49 @@
class FAQ implements ShortcodeInterface
{
public $tag;
+
public $title;
+
public $description;
+
public $icon;
public $parent_tag;
+
public $single_tag;
public static $instance = 0;
+
public static $params = [];
- public function __construct( $tag = '', $title = null, $description = null, $icon = null )
+ public function __construct($tag = '', $title = null, $description = null, $icon = null)
{
$this->tag = $tag ?: 'faq';
$this->parent_tag = $this->tag;
$this->single_tag = 'question';
- $this->title = __( 'FAQ', 'wp-addon' );
- $this->description = __( 'FAQ', 'wp-addon' );
+ $this->title = __('FAQ', 'wp-addon');
+ $this->description = __('FAQ', 'wp-addon');
- $this->icon = file_exists( get_stylesheet_directory() . '/img/black_color.svg' ) ?
- get_stylesheet_directory_uri() . '/img/black_color.svg' :
+ $this->icon = file_exists(get_stylesheet_directory().'/img/black_color.svg') ?
+ get_stylesheet_directory_uri().'/img/black_color.svg' :
'https://cdn1.iconfinder.com/data/icons/sugar-glyph/64/174_sugar-white-cubes-512.png';
- add_shortcode( $this->tag, [$this, 'html']);
- add_action( 'init', [$this, 'vc_support'] );
+ add_shortcode($this->tag, [$this, 'html']);
+ add_action('init', [$this, 'vc_support']);
- add_action( 'wp_enqueue_scripts', [$this, 'assets'] );
- add_action( 'admin_head', [$this, 'tiny_mce_support']);
+ add_action('wp_enqueue_scripts', [$this, 'assets']);
+ add_action('admin_head', [$this, 'tiny_mce_support']);
- add_action( 'init', [$this, 'pll_support']);
+ add_action('init', [$this, 'pll_support']);
}
- public function html( $atts, $content = null )
+ public function html($atts, $content = null)
{
- $atts = (object) shortcode_atts( [
+ $atts = (object) shortcode_atts([
'type' => 'default',
- ], $atts, $this->tag );
+ ], $atts, $this->tag);
/** @var string - default = show all, show_first = show first, hidden - hidden all content */
$atts->type;
@@ -57,7 +62,7 @@ public function html( $atts, $content = null )
ob_start();
?>
-
+
__('FAQ Accordion', 'gillion'),
- 'base' => $this->parent_tag,
- 'description' => __('Accordion Collapse.js', 'gillion'),
- 'category' => __('Elements', 'wp-addon' ),
- 'icon' => get_stylesheet_directory_uri() . '/img/elements/tabs.svg', // https://www.flaticon.com/packs/website-7
- 'as_parent' => array('only' => $this->single_tag),
- 'js_view' => 'VcColumnView',
- 'content_element' => true,
+ if (! function_exists('vc_map')) {
+ return;
+ }
+
+ vc_map([
+ 'name' => __('FAQ Accordion', 'gillion'),
+ 'base' => $this->parent_tag,
+ 'description' => __('Accordion Collapse.js', 'gillion'),
+ 'category' => __('Elements', 'wp-addon'),
+ 'icon' => get_stylesheet_directory_uri().'/img/elements/tabs.svg', // https://www.flaticon.com/packs/website-7
+ 'as_parent' => ['only' => $this->single_tag],
+ 'js_view' => 'VcColumnView',
+ 'content_element' => true,
'show_settings_on_create' => true,
- 'is_container' => true,
- 'params' => [
+ 'is_container' => true,
+ 'params' => [
[
- 'type' => 'textfield',
- 'holder' => 'div',
+ 'type' => 'textfield',
+ 'holder' => 'div',
'admin_label' => true,
- 'heading' => esc_html__( 'Section Title', 'rw-addon' ),
- 'param_name' => 'section_title',
- 'description' => esc_html__( 'Section Title', 'rw-addon' ),
- 'value' => '',
+ 'heading' => esc_html__('Section Title', 'rw-addon'),
+ 'param_name' => 'section_title',
+ 'description' => esc_html__('Section Title', 'rw-addon'),
+ 'value' => '',
],
[
- 'type' => 'dropdown',
- 'admin_label' => true,
- 'heading' => esc_html__('Tabs Style', 'wdo-tabs'),
- 'param_name' => 'style',
+ 'type' => 'dropdown',
+ 'admin_label' => true,
+ 'heading' => esc_html__('Tabs Style', 'wdo-tabs'),
+ 'param_name' => 'style',
'value' => [
- 'Select Style' => 'style',
- 'Style1' => 'style1',
- 'Style2' => 'style2',
- ]
+ 'Select Style' => 'style',
+ 'Style1' => 'style1',
+ 'Style2' => 'style2',
+ ],
],
[
- 'type' => 'dropdown',
- 'admin_label' => true,
- 'heading' => esc_html__('Color Scheme', 'wdo-tabs'),
- 'param_name' => 'wdo_color_scheme',
- 'group' => esc_html__('Color Scheme','wdo-tabs'),
+ 'type' => 'dropdown',
+ 'admin_label' => true,
+ 'heading' => esc_html__('Color Scheme', 'wdo-tabs'),
+ 'param_name' => 'wdo_color_scheme',
+ 'group' => esc_html__('Color Scheme', 'wdo-tabs'),
'value' => [
- 'Select Color Scheme' => '',
- 'Blue' => 'blue',
- 'Green' => 'green',
- 'MidNight Blue' => 'midnightblue',
- 'Orange' => 'orange',
- ]
- ]
- ]
- ));
+ 'Select Color Scheme' => '',
+ 'Blue' => 'blue',
+ 'Green' => 'green',
+ 'MidNight Blue' => 'midnightblue',
+ 'Orange' => 'orange',
+ ],
+ ],
+ ],
+ ]);
}
public function assets()
@@ -136,19 +143,16 @@ public function admin_script($screen)
// TODO: Implement admin_script() method.
}
- public function pll_support()
- {
- }
+ public function pll_support() {}
}
-
function faq_shortcode()
{
new FAQ('faq');
new FAQ_Question('question');
- if ( class_exists('WPBakeryShortCodesContainer') ) {
+ if (class_exists('WPBakeryShortCodesContainer')) {
class WPBakeryShortCode_faq extends WPBakeryShortCodesContainer {}
class WPBakeryShortCode_question extends WPBakeryShortCodesContainer {}
}
-}
\ No newline at end of file
+}
diff --git a/functions/shortcodes/FAQ_Question.php b/functions/shortcodes/FAQ_Question.php
index 7ca488c..f1acfeb 100644
--- a/functions/shortcodes/FAQ_Question.php
+++ b/functions/shortcodes/FAQ_Question.php
@@ -10,71 +10,76 @@
class FAQ_Question implements ShortcodeInterface
{
-
public $id;
+
public $tag;
+
public $title;
+
public $description;
+
public $icon;
public $parent_tag;
+
public $single_tag;
public static $instance = 0;
+
public $last_group;
/** @var object */
public $parent_params;
- public function __construct($tag = '', $title = null, $description = null, $icon = null )
+ public function __construct($tag = '', $title = null, $description = null, $icon = null)
{
$this->tag = $tag ?: 'question';
$this->parent_tag = 'faq';
$this->single_tag = $this->tag;
- $this->title = __( 'Question', 'wp-addon' );
- $this->description = __( 'Question', 'wp-addon' );
+ $this->title = __('Question', 'wp-addon');
+ $this->description = __('Question', 'wp-addon');
- $this->icon = file_exists( get_stylesheet_directory() . '/img/black_color.svg' ) ?
- get_stylesheet_directory_uri() . '/img/black_color.svg' :
+ $this->icon = file_exists(get_stylesheet_directory().'/img/black_color.svg') ?
+ get_stylesheet_directory_uri().'/img/black_color.svg' :
'https://cdn1.iconfinder.com/data/icons/sugar-glyph/64/174_sugar-white-cubes-512.png';
- add_shortcode( $this->tag, [$this, 'html']);
- add_action( 'init', [$this, 'vc_support'] );
- add_action( 'wp_enqueue_scripts', [$this, 'assets'] );
- add_action( 'admin_head', [$this, 'tiny_mce_support']);
+ add_shortcode($this->tag, [$this, 'html']);
+ add_action('init', [$this, 'vc_support']);
+ add_action('wp_enqueue_scripts', [$this, 'assets']);
+ add_action('admin_head', [$this, 'tiny_mce_support']);
- add_action( 'init', [$this, 'pll_support']);
+ add_action('init', [$this, 'pll_support']);
}
public function html($atts, $content = null)
{
- $atts = (object) shortcode_atts( [
+ $atts = (object) shortcode_atts([
'title' => '',
- ], $atts, $this->tag );
+ ], $atts, $this->tag);
- if($this->last_group < FAQ::$instance){
+ if ($this->last_group < FAQ::$instance) {
static::$instance = 0;
}
static::$instance++;
$this->parent_params = FAQ::$params;
$this->last_group = FAQ::$instance;
- $this->id = $this->last_group . 'acc' . static::$instance;
+ $this->id = $this->last_group.'acc'.static::$instance;
- if( isset($this->parent_params->type) && $this->parent_params->type === 'show_first') {
+ if (isset($this->parent_params->type) && $this->parent_params->type === 'show_first') {
- $aria_expanded = (static::$instance === 1) ? 'true' : 'false';
+ $aria_expanded = (static::$instance === 1) ? 'true' : 'false';
$panel_collapse = (static::$instance === 1) ? 'collapse in' : 'collapse';
- } elseif( isset($this->parent_params->type) && $this->parent_params->type === 'hidden'){
+ } elseif (isset($this->parent_params->type) && $this->parent_params->type === 'hidden') {
- $aria_expanded = 'false';
+ $aria_expanded = 'false';
$panel_collapse = 'collapse';
- } else { //default
+ } else { // default
- $aria_expanded = 'true';
+ $aria_expanded = 'true';
$panel_collapse = 'collapse in';
}
@@ -82,13 +87,13 @@ public function html($atts, $content = null)
?>
-
@@ -103,31 +108,31 @@ public function html($atts, $content = null)
*/
public function vc_support()
{
- if (!function_exists('vc_map')) {
+ if (! function_exists('vc_map')) {
return;
}
vc_map([
- 'category' => __('Elements', 'wp-addon' ),
- 'name' => __( 'Question', 'gillion' ),
- 'base' => $this->single_tag,
- 'as_child' => ['only' => $this->parent_tag],
- 'as_parent' => [''],
+ 'category' => __('Elements', 'wp-addon'),
+ 'name' => __('Question', 'gillion'),
+ 'base' => $this->single_tag,
+ 'as_child' => ['only' => $this->parent_tag],
+ 'as_parent' => [''],
'allowed_container_element' => 'vc_row',
- 'js_view' => 'VcColumnView',
- 'icon' => get_stylesheet_directory_uri() . '/img/elements/tab.svg',
- 'params' => array_merge(
+ 'js_view' => 'VcColumnView',
+ 'icon' => get_stylesheet_directory_uri().'/img/elements/tab.svg',
+ 'params' => array_merge(
[
[
- 'type' => 'textfield',
- 'holder' => 'div',
+ 'type' => 'textfield',
+ 'holder' => 'div',
'admin_label' => true,
- 'heading' => esc_html__( 'Question', 'wp-addon' ),
- 'param_name' => 'tab_title',
+ 'heading' => esc_html__('Question', 'wp-addon'),
+ 'param_name' => 'tab_title',
'description' => __('Question for answer', 'wp-addon'),
],
]
- )
+ ),
]);
}
@@ -146,7 +151,5 @@ public function admin_script($screen)
// TODO: Implement admin_script() method.
}
- public function pll_support()
- {
- }
-}
\ No newline at end of file
+ public function pll_support() {}
+}
diff --git a/functions/shortcodes/email.php b/functions/shortcodes/email.php
index 4b27b63..dab0b0e 100644
--- a/functions/shortcodes/email.php
+++ b/functions/shortcodes/email.php
@@ -1,15 +1,15 @@
tag = $tag;
- $this->title = $title;
- $this->description = $description;
+ $this->tag = $tag;
+ $this->title = $title;
+ $this->description = $description;
- $icon_def = file_exists( get_stylesheet_directory() . '/img/black_color.svg' ) ?
- get_stylesheet_directory_uri() . '/img/black_color.svg' :
+ $icon_def = file_exists(get_stylesheet_directory().'/img/black_color.svg') ?
+ get_stylesheet_directory_uri().'/img/black_color.svg' :
'https://cdn1.iconfinder.com/data/icons/sugar-glyph/64/174_sugar-white-cubes-512.png';
$this->icon = $icon ?? $icon_def;
- add_shortcode( $this->tag, [$this, 'html']);
- add_action( 'init', [$this, 'vc_support'] );
- add_action( 'wp_enqueue_scripts', [$this, 'assets'] );
- add_action( 'admin_head', [$this, 'tiny_mce_support']);
- add_action( 'init', [$this, 'pll_support']);
+ add_shortcode($this->tag, [$this, 'html']);
+ add_action('init', [$this, 'vc_support']);
+ add_action('wp_enqueue_scripts', [$this, 'assets']);
+ add_action('admin_head', [$this, 'tiny_mce_support']);
+ add_action('init', [$this, 'pll_support']);
}
-
-
-}
\ No newline at end of file
+}
diff --git a/functions/shortcodes/vc-support.php b/functions/shortcodes/vc-support.php
index 6b8de26..dacc576 100644
--- a/functions/shortcodes/vc-support.php
+++ b/functions/shortcodes/vc-support.php
@@ -1,43 +1,44 @@
__( 'Any widgets', 'wp-addon' ),
+add_action('vc_before_init', 'widgets_support_vc');
+function widgets_support_vc()
+{
+ vc_map([
+ 'name' => __('Any widgets', 'wp-addon'),
'base' => 'widget',
'class' => '',
- 'category' => __('Elements', 'wp-addon' ),
+ 'category' => __('Elements', 'wp-addon'),
'params' => [
[
'type' => 'textfield',
'holder' => 'div',
'class' => '',
- 'heading' => __( 'Widget Name', 'wp-addon' ),
+ 'heading' => __('Widget Name', 'wp-addon'),
'param_name' => 'widget_name',
- 'value' => __( '', 'wp-addon' ),
- 'description' => __( 'Paste Original Widget Class Name. See: https://codex.wordpress.org/Template_Tags/the_widget', 'wp-addon' )
+ 'value' => __('', 'wp-addon'),
+ 'description' => __('Paste Original Widget Class Name. See: https://codex.wordpress.org/Template_Tags/the_widget', 'wp-addon'),
],
[
'type' => 'textarea',
- //'holder' => 'div',
+ // 'holder' => 'div',
'class' => '',
- 'heading' => __( 'Instance', 'wp-addon' ),
+ 'heading' => __('Instance', 'wp-addon'),
'param_name' => 'instance',
- 'value' => __( '', 'wp-addon' ),
- 'description' => __( 'Instance Params', 'wp-addon' )
+ 'value' => __('', 'wp-addon'),
+ 'description' => __('Instance Params', 'wp-addon'),
],
[
'type' => 'textarea',
'class' => '',
- 'heading' => __( 'Args', 'wp-addon' ),
+ 'heading' => __('Args', 'wp-addon'),
'param_name' => 'args',
- 'value' => __( '', 'wp-addon' ),
- 'description' => __( 'Enter description.', 'wp-addon' )
- ]
+ 'value' => __('', 'wp-addon'),
+ 'description' => __('Enter description.', 'wp-addon'),
+ ],
- ]
- ) );
-}
\ No newline at end of file
+ ],
+ ]);
+}
diff --git a/functions/shortcodes/widget_shortcode.php b/functions/shortcodes/widget_shortcode.php
index 2c7c381..f71d24e 100644
--- a/functions/shortcodes/widget_shortcode.php
+++ b/functions/shortcodes/widget_shortcode.php
@@ -1,24 +1,23 @@
false,
- 'instance' => [],
- 'args' => [],
- ], $atts)
+ 'widget_name' => false,
+ 'instance' => [],
+ 'args' => [],
+ ], $atts)
);
$widget_name = esc_html($widget_name);
@@ -27,6 +26,7 @@ function widget_shortcode($atts)
register_widget($widget_name);
ob_start();
the_widget($widget_name, $instance, $args);
+
return ob_get_clean();
}
@@ -38,4 +38,4 @@ function widget_short_code_init()
add_shortcode('widget', 'widget_shortcode');
}
-add_action('widgets_init', 'widget_short_code_init');
\ No newline at end of file
+add_action('widgets_init', 'widget_short_code_init');
diff --git a/functions/terms/categories.php b/functions/terms/categories.php
index cd35bbb..c03de28 100644
--- a/functions/terms/categories.php
+++ b/functions/terms/categories.php
@@ -1,5 +1,5 @@
url = ! empty( $url ) ? $url : RW_PLUGIN_URL . 'assets/images/user_gray.svg';
- }
-
- /**
- * Свой вариант аватарки по-умолчанию.
- *
- * @param $avatar_defaults
- *
- * @return mixed
- */
- public function new_default_avatar( $avatar_defaults ) {
- $avatar_defaults[ $this->url ] = __( 'Custom Default Avatar', 'wp-addon' );
-
- return $avatar_defaults;
- }
-
- /**
- * Свой вариант аватарки по-умолчанию. Заменяем картинку при отображении списка аватаров.
- *
- * @param $avatar
- * @param $id_or_email
- * @param $size
- * @param $default
- * @param $alt
- * @param $args
- *
- * @return string - html код аватарки
- */
- public function media_get_avatar( $avatar, $id_or_email, $size, $default, $alt, $args ): string {
- if ( $default === $this->url ) { // путь к файлу
- $avatar = '
';
- // $args['default']
- }
-
- return $avatar;
- }
- }
-
- return new UserAvatar();
-}
\ No newline at end of file
+if (! class_exists('functions\users\UserAvatar')) {
+ class UserAvatar
+ {
+ public string $url;
+
+ public function __construct(string $url = '')
+ {
+ add_filter('avatar_defaults', [$this, 'new_default_avatar'], 10);
+ add_filter('get_avatar', [$this, 'media_get_avatar'], 10, 6);
+
+ $this->url = ! empty($url) ? $url : RW_PLUGIN_URL.'assets/images/user_gray.svg';
+ }
+
+ /**
+ * Свой вариант аватарки по-умолчанию.
+ *
+ *
+ * @return mixed
+ */
+ public function new_default_avatar($avatar_defaults)
+ {
+ $avatar_defaults[$this->url] = __('Custom Default Avatar', 'wp-addon');
+
+ return $avatar_defaults;
+ }
+
+ /**
+ * Свой вариант аватарки по-умолчанию. Заменяем картинку при отображении списка аватаров.
+ *
+ *
+ * @return string - html код аватарки
+ */
+ public function media_get_avatar($avatar, $id_or_email, $size, $default, $alt, $args): string
+ {
+ if ($default === $this->url) { // путь к файлу
+ $avatar = '
';
+ // $args['default']
+ }
+
+ return $avatar;
+ }
+ }
+
+ return new UserAvatar;
+}
diff --git a/functions/users/UserFilter.php b/functions/users/UserFilter.php
index 7733401..5d1594a 100644
--- a/functions/users/UserFilter.php
+++ b/functions/users/UserFilter.php
@@ -18,42 +18,41 @@
* Requires at least: 4.6
* Tested up to: 5.6.0
* Requires PHP: 7.2+
- *
- * @package WordPress Addon
*/
-class UserFilter {
-
- public $screen;
-
- public function __construct() {
- $this->screen = 'users';
-
- add_action( 'restrict_manage_users', [ $this, 'filter_by_role' ], 10, 1 );
- add_filter( 'pre_get_users', [ $this, 'filter_users_by_role_section' ] );
- add_filter( "manage_{$this->screen}_sortable_columns", [ $this, 'columns_sortable' ] );
- add_filter( 'user_row_actions', [ $this, 'quick_edit' ], 10, 2 );
-
- if ( ! shortcode_exists( 'role_list' ) ) {
- add_shortcode( 'role_list', [ $this, 'add_shortcode' ] );
- }
- }
-
- /**
- ** Sort and Filter Users **
- * render html form filter
- *
- * @param $which
- *
- * @return null
- */
- public function filter_by_role( $which ) {
- if ( shortcode_exists( 'role_list' ) ) {
- echo do_shortcode( '[role_list style="filter" args="' . $which . '""]' );
- echo '
';
- }
-
- add_action( 'admin_footer', function () {
- ?>
+class UserFilter
+{
+ public $screen;
+
+ public function __construct()
+ {
+ $this->screen = 'users';
+
+ add_action('restrict_manage_users', [$this, 'filter_by_role'], 10, 1);
+ add_filter('pre_get_users', [$this, 'filter_users_by_role_section']);
+ add_filter("manage_{$this->screen}_sortable_columns", [$this, 'columns_sortable']);
+ add_filter('user_row_actions', [$this, 'quick_edit'], 10, 2);
+
+ if (! shortcode_exists('role_list')) {
+ add_shortcode('role_list', [$this, 'add_shortcode']);
+ }
+ }
+
+ /**
+ ** Sort and Filter Users **
+ * render html form filter
+ *
+ *
+ * @return null
+ */
+ public function filter_by_role($which)
+ {
+ if (shortcode_exists('role_list')) {
+ echo do_shortcode('[role_list style="filter" args="'.$which.'""]');
+ echo '
';
+ }
+
+ add_action('admin_footer', function () {
+ ?>
set( 'role', $_GET['role_filter'] );
- $query->set( 'role__in', [ $_GET['role_filter'] ] );
- }
- }
-
- return $query;
- }
-
-
- /**
- * Add sortable to columns
- *
- * @param $sortable_columns
- *
- * @return mixed
- */
- public function columns_sortable( $sortable_columns ) {
- $sortable_columns['role'] = 'role';
- $sortable_columns['name'] = 'name';
- $sortable_columns['posts'] = 'posts';
-
- return $sortable_columns;
- }
-
-
- public function quick_edit( $actions, $user_object ) {
- // TODO : quick edit here ...
- return $actions;
- }
-
- public function add_shortcode( $atts = [] ) {
- if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
- return false;
- }
-
- $role_names = wp_roles()->get_names();
- // filter by user role
- if ( isset( $atts['style'] ) && $atts['style'] === 'filter' ) {
- // template for filtering
- $select = '
';
- $select .= '' . __( 'Filter by role' ) . ' ';
- foreach ( $role_names as $role => $name ) {
- if ( isset( $_GET['role'] ) && ! empty( $_GET['role'] ) && $role === $_GET['role'] ) {
- $select .= '' . $name . ' ';
- } else {
- $select .= '' . $name . ' ';
- }
- }
- $select .= ' ';
-
- return $select;
- }
-
- $html = '
';
- foreach ( $role_names as $role => $name ) {
- $html .= '' . $role . ' - ' . $name . ' ';
- }
- $html .= '';
-
- return $html;
- }
+ });
+ }
+
+ /**
+ * @return WP_User_Query $query
+ */
+ public function filter_users_by_role_section(WP_User_Query $query): WP_User_Query
+ {
+ global $pagenow;
+
+ if (is_admin() && isset($_GET['role_filter']) && $pagenow === 'users.php') {
+ if (! empty($_GET['role_filter'])) {
+ $query->set('role', $_GET['role_filter']);
+ $query->set('role__in', [$_GET['role_filter']]);
+ }
+ }
+
+ return $query;
+ }
+
+ /**
+ * Add sortable to columns
+ *
+ *
+ * @return mixed
+ */
+ public function columns_sortable($sortable_columns)
+ {
+ $sortable_columns['role'] = 'role';
+ $sortable_columns['name'] = 'name';
+ $sortable_columns['posts'] = 'posts';
+
+ return $sortable_columns;
+ }
+
+ public function quick_edit($actions, $user_object)
+ {
+ // TODO : quick edit here ...
+ return $actions;
+ }
+
+ public function add_shortcode($atts = [])
+ {
+ if (! is_admin() || ! current_user_can('manage_options')) {
+ return false;
+ }
+
+ $role_names = wp_roles()->get_names();
+ // filter by user role
+ if (isset($atts['style']) && $atts['style'] === 'filter') {
+ // template for filtering
+ $select = '';
+ $select .= ''.__('Filter by role').' ';
+ foreach ($role_names as $role => $name) {
+ if (isset($_GET['role']) && ! empty($_GET['role']) && $role === $_GET['role']) {
+ $select .= ''.$name.' ';
+ } else {
+ $select .= ''.$name.' ';
+ }
+ }
+ $select .= ' ';
+
+ return $select;
+ }
+
+ $html = '';
+ foreach ($role_names as $role => $name) {
+ $html .= ''.$role.' - '.$name.' ';
+ }
+ $html .= '';
+
+ return $html;
+ }
}
-return new UserFilter();
\ No newline at end of file
+return new UserFilter;
diff --git a/functions/vc/wpbackery-page-builder.php b/functions/vc/wpbackery-page-builder.php
deleted file mode 100644
index 87e533d..0000000
--- a/functions/vc/wpbackery-page-builder.php
+++ /dev/null
@@ -1,44 +0,0 @@
-isDevEnvironment('local');
- vc_license()->isDevEnvironment('loc');
- }
-
-
- /* $prefix = 'wpb_js_';
- $name = 'js_composer_purchase_code';
- if(false === get_option($prefix . $name, false)) {
- update_option($prefix . $name, '$value');
- }*/
-
-}
-add_action('plugins_loaded', 'remove_admin_notice');
\ No newline at end of file
diff --git a/functions/widgets/WP_Widget_External_RSS.php b/functions/widgets/WP_Widget_External_RSS.php
index 6eb39ff..b05e6d2 100644
--- a/functions/widgets/WP_Widget_External_RSS.php
+++ b/functions/widgets/WP_Widget_External_RSS.php
@@ -2,10 +2,8 @@
/**
* WP_External_Widget_RSS
*/
-
class WP_Widget_External_RSS extends WP_Widget
{
-
/**
* Sets up a new RSS widget instance.
*
@@ -13,16 +11,16 @@ class WP_Widget_External_RSS extends WP_Widget
*/
public function __construct()
{
- $widget_ops = array(
- 'description' => __('External RSS feed.'),
+ $widget_ops = [
+ 'description' => __('External RSS feed.'),
'customize_selective_refresh' => true,
- 'show_instance_in_rest' => true,
+ 'show_instance_in_rest' => true,
- );
- $control_ops = array(
- 'width' => 400,
+ ];
+ $control_ops = [
+ 'width' => 400,
'height' => 200,
- );
+ ];
parent::__construct('external_rss', __('External RSS'), $widget_ops, $control_ops);
}
@@ -31,35 +29,37 @@ public function __construct()
* Outputs the content for the current RSS widget instance.
*
* @param array $args Display arguments including 'before_title', 'after_title',
- * 'before_widget', and 'after_widget'.
+ * 'before_widget', and 'after_widget'.
* @param array $instance Settings for the current RSS widget instance.
*
* @since 2.8.0
- *
*/
public function widget($args, $instance)
{
if (isset($instance['error']) && $instance['error']) {
console_log($instance['error']);
+
return;
}
- $url = !empty($instance['url']) ? $instance['url'] : '';
- while (!empty($url) && stristr($url, 'http') !== $url) {
+ $url = ! empty($instance['url']) ? $instance['url'] : '';
+ while (! empty($url) && stristr($url, 'http') !== $url) {
$url = substr($url, 1);
}
if (empty($url)) {
console_log('Empty URL');
+
return;
}
// Self-URL destruction sequence.
- if (in_array(untrailingslashit($url), array(site_url(), home_url()),
+ if (in_array(untrailingslashit($url), [site_url(), home_url()],
true)
) {
console_log('Self hosted!');
+
return;
}
@@ -68,23 +68,23 @@ public function widget($args, $instance)
$desc = '';
$link = '';
- if (!is_wp_error($rss)) {
+ if (! is_wp_error($rss)) {
$desc
= esc_attr(strip_tags(html_entity_decode($rss->get_description(),
- ENT_QUOTES, get_option('blog_charset'))));
+ ENT_QUOTES, get_option('blog_charset'))));
if (empty($title)) {
$title = strip_tags($rss->get_title());
}
$link = strip_tags($rss->get_permalink());
- while (!empty($link) && stristr($link, 'http') !== $link) {
+ while (! empty($link) && stristr($link, 'http') !== $link) {
$link = substr($link, 1);
}
- } else {
+ } else {
console_log($rss->get_error_message());
}
if (empty($title)) {
- $title = !empty($desc) ? $desc : __('Unknown Feed');
+ $title = ! empty($desc) ? $desc : __('Unknown Feed');
}
/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
@@ -113,7 +113,6 @@ public function widget($args, $instance)
* @param array $instance Array of settings for the current widget.
*
* @since 5.9.0
- *
*/
$feed_link = apply_filters('rss_widget_feed_link', $feed_link,
$instance);
@@ -134,7 +133,7 @@ public function widget($args, $instance)
/** This filter is documented in wp-includes/widgets/class-wp-nav-menu-widget.php */
$format = apply_filters('navigation_widgets_format', $format);
- if ('html5' === $format) {
+ if ($format === 'html5') {
// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
$title = trim(strip_tags($title));
$aria_label = $title ?: __('RSS Feed');
@@ -143,13 +142,13 @@ public function widget($args, $instance)
wp_widget_rss_output($rss, $instance);
- if ('html5' === $format) {
+ if ($format === 'html5') {
echo '';
}
echo $args['after_widget'];
- if (!is_wp_error($rss)) {
+ if (! is_wp_error($rss)) {
$rss->__destruct();
}
unset($rss);
@@ -159,20 +158,19 @@ public function widget($args, $instance)
* Handles updating settings for the current RSS widget instance.
*
* @param array $new_instance New settings for this instance as input by the user via
- * WP_Widget::form().
+ * WP_Widget::form().
* @param array $old_instance Old settings for this instance.
- *
* @return array Updated settings to save.
- * @since 2.8.0
*
+ * @since 2.8.0
*/
public function update($new_instance, $old_instance)
{
$testurl = (isset($new_instance['url'])
- && (!isset($old_instance['url'])
+ && (! isset($old_instance['url'])
|| ($new_instance['url'] !== $old_instance['url'])));
- //var_dump($new_instance, $old_instance); die();
+ // var_dump($new_instance, $old_instance); die();
return wp_widget_rss_process($new_instance, $testurl);
}
@@ -182,94 +180,92 @@ public function update($new_instance, $old_instance)
* @param array $instance Current settings.
*
* @since 2.8.0
- *
*/
public function form($instance)
{
if (empty($instance)) {
- $instance = array(
- 'title' => '',
- 'url' => '',
- 'items' => 10,
- 'error' => false,
+ $instance = [
+ 'title' => '',
+ 'url' => '',
+ 'items' => 10,
+ 'error' => false,
'show_summary' => 0,
- 'show_author' => 0,
- 'show_date' => 0,
- );
+ 'show_author' => 0,
+ 'show_date' => 0,
+ ];
}
$instance['number'] = $this->id;
$args = $instance;
$inputs = null;
- $default_inputs = array(
- 'url' => true,
- 'title' => true,
- 'items' => true,
+ $default_inputs = [
+ 'url' => true,
+ 'title' => true,
+ 'items' => true,
'show_summary' => true,
- 'show_author' => true,
- 'show_date' => true,
- );
- $inputs = wp_parse_args( $inputs, $default_inputs );
+ 'show_author' => true,
+ 'show_date' => true,
+ ];
+ $inputs = wp_parse_args($inputs, $default_inputs);
- $args['title'] = isset( $args['title'] ) ? $args['title'] : '';
- $args['url'] = isset( $args['url'] ) ? $args['url'] : '';
- $args['items'] = isset( $args['items'] ) ? (int) $args['items'] : 0;
+ $args['title'] = isset($args['title']) ? $args['title'] : '';
+ $args['url'] = isset($args['url']) ? $args['url'] : '';
+ $args['items'] = isset($args['items']) ? (int) $args['items'] : 0;
- if ( $args['items'] < 1 || 20 < $args['items'] ) {
+ if ($args['items'] < 1 || $args['items'] > 20) {
$args['items'] = 10;
}
- $args['show_summary'] = isset( $args['show_summary'] ) ? (int) $args['show_summary'] : (int) $inputs['show_summary'];
- $args['show_author'] = isset( $args['show_author'] ) ? (int) $args['show_author'] : (int) $inputs['show_author'];
- $args['show_date'] = isset( $args['show_date'] ) ? (int) $args['show_date'] : (int) $inputs['show_date'];
+ $args['show_summary'] = isset($args['show_summary']) ? (int) $args['show_summary'] : (int) $inputs['show_summary'];
+ $args['show_author'] = isset($args['show_author']) ? (int) $args['show_author'] : (int) $inputs['show_author'];
+ $args['show_date'] = isset($args['show_date']) ? (int) $args['show_date'] : (int) $inputs['show_date'];
- if ( ! empty( $args['error'] ) ) {
- echo '' . __( 'RSS Error:' ) . ' ' . esc_html( $args['error'] ) . '
';
+ if (! empty($args['error'])) {
+ echo ''.__('RSS Error:').' '.esc_html($args['error']).'
';
}
- $esc_number = esc_attr( $args['number'] );
- if ( $inputs['url'] ) :
+ $esc_number = esc_attr($args['number']);
+ if ($inputs['url']) {
?>
-
-
+
+
+ id="get_field_id('url'); ?>"
+ name="get_field_name('url'); ?>" type="text"
+ value="" />
-
-
-
+
+
+
+ id="get_field_id('title'); ?>"
+ name="get_field_name('title'); ?>" type="text"
+ value="" />
-
-
-
+
+
+
-
$i";
- }
- ?>
+ for ($i = 1; $i <= 20; $i++) {
+ echo "$i ";
+ }
+ ?>
- __('Additional sidebar 1', 'wp-addon'),
- 'id' => 'additional_sidebar_1',
- 'description' => __('Additional sidebar 1', 'wp-addon'),
+ 'name' => __('Additional sidebar 1', 'wp-addon'),
+ 'id' => 'additional_sidebar_1',
+ 'description' => __('Additional sidebar 1', 'wp-addon'),
'before_widget' => '',
- 'after_widget' => '
',
- 'before_title' => '',
+ 'after_widget' => '
',
+ 'before_title' => '
',
]
);
});
@@ -25,13 +25,13 @@ function add_sidebar_2()
add_action('widgets_init', function () {
register_sidebar(
[
- 'name' => __('Additional sidebar 2', 'wp-addon'),
- 'id' => 'additional_sidebar_2',
- 'description' => __('Additional sidebar 2', 'wp-addon'),
+ 'name' => __('Additional sidebar 2', 'wp-addon'),
+ 'id' => 'additional_sidebar_2',
+ 'description' => __('Additional sidebar 2', 'wp-addon'),
'before_widget' => '
',
- 'after_widget' => '
',
- 'before_title' => '
',
+ 'after_widget' => '
',
+ 'before_title' => '',
]
);
});
@@ -42,13 +42,13 @@ function add_sidebar_3()
add_action('widgets_init', function () {
register_sidebar(
[
- 'name' => __('Additional sidebar 3', 'wp-addon'),
- 'id' => 'additional_sidebar_3',
- 'description' => __('Additional sidebar 3', 'wp-addon'),
+ 'name' => __('Additional sidebar 3', 'wp-addon'),
+ 'id' => 'additional_sidebar_3',
+ 'description' => __('Additional sidebar 3', 'wp-addon'),
'before_widget' => '',
- 'after_widget' => '
',
- 'before_title' => '',
+ 'after_widget' => '',
+ 'before_title' => '',
]
);
});
diff --git a/functions/widgets/duplicate-widgets.php b/functions/widgets/duplicate-widgets.php
index 60b95c2..515636c 100644
--- a/functions/widgets/duplicate-widgets.php
+++ b/functions/widgets/duplicate-widgets.php
@@ -1,11 +1,10 @@
__('Clone', 'wp-addon'),
- 'title' => __('Clone this Widget', 'wp-addon')
+ 'text' => __('Clone', 'wp-addon'),
+ 'title' => __('Clone this Widget', 'wp-addon'),
]);
}
- endif;
+ }
}
diff --git a/functions/wp-functions.php b/functions/wp-functions.php
index 1efae32..f0e8710 100644
--- a/functions/wp-functions.php
+++ b/functions/wp-functions.php
@@ -45,36 +45,39 @@ function wptweaker_setting_1()
{
remove_action('wp_head', 'wp_generator'); // из заголовка
add_filter('the_generator', '__return_empty_string'); // из фидов и URL
- if ( file_exists( ABSPATH . '/readme.txt' ) ) {
- unlink( ABSPATH . '/readme.txt' );
+ if (file_exists(ABSPATH.'/readme.txt')) {
+ unlink(ABSPATH.'/readme.txt');
}
}
/** Disable Emo */
function wptweaker_setting_2()
{
- remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
- remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
- remove_action( 'wp_print_styles', 'print_emoji_styles' );
- remove_action( 'admin_print_styles', 'print_emoji_styles' );
- remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
- remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
- remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
-
- add_filter( 'tiny_mce_plugins', 'disable_emojis_tinymce' );
- add_filter( 'wp_resource_hints', 'disable_emojis_remove_dns_prefetch', 10, 2 );
- function disable_emojis_tinymce( $plugins ) {
- if ( is_array( $plugins ) ) {
- return array_diff( $plugins, array( 'wpemoji' ) );
+ remove_action('wp_head', 'print_emoji_detection_script', 7);
+ remove_action('admin_print_scripts', 'print_emoji_detection_script');
+ remove_action('wp_print_styles', 'print_emoji_styles');
+ remove_action('admin_print_styles', 'print_emoji_styles');
+ remove_filter('the_content_feed', 'wp_staticize_emoji');
+ remove_filter('comment_text_rss', 'wp_staticize_emoji');
+ remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
+
+ add_filter('tiny_mce_plugins', 'disable_emojis_tinymce');
+ add_filter('wp_resource_hints', 'disable_emojis_remove_dns_prefetch', 10, 2);
+ function disable_emojis_tinymce($plugins)
+ {
+ if (is_array($plugins)) {
+ return array_diff($plugins, ['wpemoji']);
}
}
- function disable_emojis_remove_dns_prefetch( $urls, $relation_type ) {
- if ( 'dns-prefetch' === $relation_type ) {
+ function disable_emojis_remove_dns_prefetch($urls, $relation_type)
+ {
+ if ($relation_type === 'dns-prefetch') {
// This filter is documented in wp-includes/formatting.php
- $emoji_svg_url = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/2/svg/' );
- $urls = array_diff( $urls, array( $emoji_svg_url ) );
+ $emoji_svg_url = apply_filters('emoji_svg_url', 'https://s.w.org/images/core/emoji/2/svg/');
+ $urls = array_diff($urls, [$emoji_svg_url]);
}
+
return $urls;
}
}
@@ -108,14 +111,14 @@ function wptweaker_setting_7()
function wptweaker_setting_8()
{
- if (!defined('WP_POST_REVISIONS')) {
+ if (! defined('WP_POST_REVISIONS')) {
define('WP_POST_REVISIONS', 5);
}
}
function wptweaker_setting_9()
{
- add_filter( 'pre_http_request', '__return_true', 100 );
+ add_filter('pre_http_request', '__return_true', 100);
}
function wptweaker_setting_10()
@@ -133,34 +136,35 @@ function wptweaker_setting_11()
*
* @since 1.0
*
- * @param WP_Scripts $scripts WP_Scripts object.
+ * @param WP_Scripts $scripts WP_Scripts object.
*/
- function rw_remove_jquery_migrate( $scripts ) {
- if ( ! is_admin() && isset( $scripts->registered['jquery'] ) ) {
+ function rw_remove_jquery_migrate($scripts)
+ {
+ if (! is_admin() && isset($scripts->registered['jquery'])) {
$script = $scripts->registered['jquery'];
- if ( $script->deps ) { // Check whether the script has any dependencies
- $script->deps = array_diff( $script->deps, array( 'jquery-migrate' ) );
+ if ($script->deps) { // Check whether the script has any dependencies
+ $script->deps = array_diff($script->deps, ['jquery-migrate']);
}
}
}
- add_action( 'wp_default_scripts', 'rw_remove_jquery_migrate' );
+ add_action('wp_default_scripts', 'rw_remove_jquery_migrate');
}
function wptweaker_setting_12()
{
- define( 'CORE_UPGRADE_SKIP_NEW_BUNDLED', true );
+ define('CORE_UPGRADE_SKIP_NEW_BUNDLED', true);
}
function wptweaker_setting_13()
{
- add_filter('xmlrpc_enabled', '__return_false' );
+ add_filter('xmlrpc_enabled', '__return_false');
}
function wptweaker_setting_14()
{
- add_filter( 'enable_post_by_email_configuration', '__return_false' );
+ add_filter('enable_post_by_email_configuration', '__return_false');
}
function wptweaker_setting_15()
@@ -192,27 +196,30 @@ function wpt_login_shake()
function wptweaker_setting_18()
{
- if (!defined('EMPTY_TRASH_DAYS')) {
- define('EMPTY_TRASH_DAYS', 14 );
+ if (! defined('EMPTY_TRASH_DAYS')) {
+ define('EMPTY_TRASH_DAYS', 14);
}
}
-function wptweaker_setting_19(){
- function upload_allow_types( $mimes ) {
+function wptweaker_setting_19()
+{
+ function upload_allow_types($mimes)
+ {
// разрешаем новые типы
- $mimes['svg'] = 'image/svg+xml';
+ $mimes['svg'] = 'image/svg+xml';
$mimes['svgz'] = 'image/svg+xml';
- $mimes['doc'] = 'application/msword';
+ $mimes['doc'] = 'application/msword';
$mimes['woff'] = 'font/woff';
- $mimes['psd'] = 'image/vnd.adobe.photoshop';
- $mimes['djv'] = 'image/vnd.djvu';
+ $mimes['psd'] = 'image/vnd.adobe.photoshop';
+ $mimes['djv'] = 'image/vnd.djvu';
$mimes['djvu'] = 'image/vnd.djvu';
$mimes['webp'] = 'image/webp';
// отключаем имеющиеся
- unset( $mimes['mp4a'] );
+ unset($mimes['mp4a']);
+
return $mimes;
}
- add_filter( 'upload_mimes', 'upload_allow_types' );
+ add_filter('upload_mimes', 'upload_allow_types');
}
function wptweaker_setting_20()
@@ -220,7 +227,7 @@ function wptweaker_setting_20()
// Отключаем пинги на свои же посты
add_action('pre_ping', function (&$links) {
foreach ($links as $k => $val) {
- if (false !== strpos($val, str_replace('www.', '', $_SERVER['HTTP_HOST']))) {
+ if (strpos($val, str_replace('www.', '', $_SERVER['HTTP_HOST'])) !== false) {
unset($links[$k]);
}
}
@@ -232,7 +239,7 @@ function wptweaker_setting_21()
/* Отключение админ-бара для всех, кроме админа */
function disable_admin_bar()
{
- if ( ! current_user_can('edit_posts')) {
+ if (! current_user_can('edit_posts')) {
add_filter('show_admin_bar', '__return_false');
add_action('admin_print_scripts-profile.php', 'hide_admin_bar_settings');
}
@@ -249,6 +256,7 @@ function new_contactmethod($methods, $user)
unset($methods['aim'], $methods['jabber'], $methods['yim']);
$methods['vk'] = __('VK', 'wp-addon');
$methods['ok'] = __('OK', 'wp-addon');
+
return $methods;
}
}
@@ -282,22 +290,22 @@ function unregister_basic_widgets()
function wptweaker_setting_25()
{
- ## Удаление файлов license.txt и readme.html для защиты
+ // # Удаление файлов license.txt и readme.html для защиты
if (is_admin() && ! defined('DOING_AJAX')) {
- $license_file = ABSPATH . '/license.txt';
- $readme_file = ABSPATH . '/readme.html';
+ $license_file = ABSPATH.'/license.txt';
+ $readme_file = ABSPATH.'/readme.html';
if (file_exists($license_file) && current_user_can('manage_options')) {
$deleted = unlink($license_file) && unlink($readme_file);
- if ( ! $deleted) {
+ if (! $deleted) {
$GLOBALS['readmedel'] = sprintf(__('Failed to delete files license.txt and readme.html from folder %s. Please delete them manually!', 'wp-addon'), ABSPATH);
} else {
$GLOBALS['readmedel'] = sprintf(__('Files license.txt and readme.html have been deleted from folder %s.', 'wp-addon'), ABSPATH);
}
add_action('admin_notices', function () {
- echo '' . $GLOBALS['readmedel'] . '
';
+ echo ''.$GLOBALS['readmedel'].'
';
});
}
}
@@ -305,21 +313,21 @@ function wptweaker_setting_25()
function wptweaker_setting_26()
{
- ## Фильтр элементо втаксономии для метабокса таксономий в админке.
- ## Позволяет удобно фильтровать (искать) элементы таксономии по назанию, когда их очень много
+ // # Фильтр элементо втаксономии для метабокса таксономий в админке.
+ // # Позволяет удобно фильтровать (искать) элементы таксономии по назанию, когда их очень много
add_action('admin_print_scripts', 'my_admin_term_filter', 99);
function my_admin_term_filter()
{
$screen = get_current_screen();
- if ($screen === null || 'post' !== $screen->base) {
+ if ($screen === null || $screen->base !== 'post') {
return;
} // только для страницы редактирвоания любой записи
?>
';
+
return $html;
}
- public function refresh_plugins_list_ajax() {
+ public function refresh_plugins_list_ajax()
+ {
check_ajax_referer('refresh_plugins', 'nonce');
- if (!current_user_can('manage_options')) {
+ if (! current_user_can('manage_options')) {
wp_send_json_error('Нет прав.');
}
delete_transient('wp_addon_github_plugins');
wp_send_json_success();
}
- public function uninstall_plugin_ajax() {
+ public function uninstall_plugin_ajax()
+ {
check_ajax_referer('uninstall_plugin', 'nonce');
- if (!current_user_can('delete_plugins')) {
+ if (! current_user_can('delete_plugins')) {
wp_send_json_error('Нет прав для удаления плагинов.');
}
$repo = sanitize_text_field($_POST['repo']);
if (empty($repo)) {
wp_send_json_error('Неверные параметры.');
}
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
- require_once ABSPATH . 'wp-admin/includes/file.php';
- if (!WP_Filesystem()) {
- wp_send_json_error('Ошибка файловой системы.');
+ require_once ABSPATH.'wp-admin/includes/plugin.php';
+ require_once ABSPATH.'wp-admin/includes/file.php';
+ if (! WP_Filesystem()) {
+ wp_send_json_error('Ошибка файловой системы.');
+
return;
}
global $wp_filesystem;
@@ -307,46 +317,49 @@ public function uninstall_plugin_ajax() {
break;
}
}
- if (!$plugin_file) {
+ if (! $plugin_file) {
wp_send_json_error('Плагин не найден.');
+
return;
}
- $plugin_dir = WP_PLUGIN_DIR . '/' . $repo;
+ $plugin_dir = WP_PLUGIN_DIR.'/'.$repo;
if ($wp_filesystem->exists($plugin_dir)) {
$wp_filesystem->delete($plugin_dir, true);
}
wp_send_json_success();
}
- public function toggle_plugin_ajax() {
+ public function toggle_plugin_ajax()
+ {
check_ajax_referer('toggle_plugin', 'nonce');
- if (!current_user_can('activate_plugins')) {
+ if (! current_user_can('activate_plugins')) {
wp_send_json_error('Нет прав для активации/деактивации плагинов.');
}
$plugin_file = sanitize_text_field($_POST['plugin_file']);
if (empty($plugin_file)) {
wp_send_json_error('Неверные параметры.');
}
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
+ require_once ABSPATH.'wp-admin/includes/plugin.php';
$active_plugins = get_option('active_plugins', []);
if (in_array($plugin_file, $active_plugins)) {
// Деактивировать
deactivate_plugins($plugin_file);
- wp_send_json_success(['action' => 'deactivated']);
+ wp_send_json_success(['action' => 'deactivated']);
} else {
// Активировать
$activate_result = activate_plugin($plugin_file);
if ($activate_result === true || is_null($activate_result)) {
- wp_send_json_success(['action' => 'activated']);
+ wp_send_json_success(['action' => 'activated']);
} else {
- wp_send_json_error('Не удалось активировать плагин: ' . (is_wp_error($activate_result) ? $activate_result->get_error_message() : 'Неизвестная ошибка'));
+ wp_send_json_error('Не удалось активировать плагин: '.(is_wp_error($activate_result) ? $activate_result->get_error_message() : 'Неизвестная ошибка'));
}
}
}
- public function install_plugin_ajax() {
+ public function install_plugin_ajax()
+ {
check_ajax_referer('install_plugin', 'nonce');
- if (!current_user_can('install_plugins')) {
+ if (! current_user_can('install_plugins')) {
wp_send_json_error('Нет прав для установки плагинов.');
}
$zip_url = esc_url_raw($_POST['zip']);
@@ -354,36 +367,39 @@ public function install_plugin_ajax() {
if (empty($zip_url) || empty($repo)) {
wp_send_json_error('Неверные параметры.');
}
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
- require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
- require_once ABSPATH . 'wp-admin/includes/file.php';
- if (!WP_Filesystem()) {
- wp_send_json_error('Ошибка файловой системы.');
+ require_once ABSPATH.'wp-admin/includes/plugin.php';
+ require_once ABSPATH.'wp-admin/includes/class-wp-upgrader.php';
+ require_once ABSPATH.'wp-admin/includes/plugin-install.php';
+ require_once ABSPATH.'wp-admin/includes/file.php';
+ if (! WP_Filesystem()) {
+ wp_send_json_error('Ошибка файловой системы.');
+
return;
}
- $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() );
+ $upgrader = new Plugin_Upgrader(new Automatic_Upgrader_Skin);
$result = $upgrader->install($zip_url);
if ($result) {
// Найти установленную папку (GitHub ZIP создает папку с -main)
- $possible_dirs = glob(WP_PLUGIN_DIR . '/' . $repo . '-*');
+ $possible_dirs = glob(WP_PLUGIN_DIR.'/'.$repo.'-*');
if (empty($possible_dirs)) {
wp_send_json_error('Не найдена установленная папка.');
+
return;
}
$installed_dir = $possible_dirs[0]; // берем первую
- $expected_dir = WP_PLUGIN_DIR . '/' . $repo;
+ $expected_dir = WP_PLUGIN_DIR.'/'.$repo;
if (is_dir($expected_dir)) {
wp_send_json_error('Папка плагина уже существует.');
+
return;
}
if (rename($installed_dir, $expected_dir)) {
// Найти основной файл плагина
- $plugin_files = glob($expected_dir . '/*.php');
+ $plugin_files = glob($expected_dir.'/*.php');
$plugin_file = null;
foreach ($plugin_files as $file) {
$data = get_plugin_data($file);
- if (!empty($data['Name'])) {
+ if (! empty($data['Name'])) {
$plugin_file = $file;
break;
}
@@ -393,7 +409,7 @@ public function install_plugin_ajax() {
if ($activate_result === true || is_null($activate_result)) {
wp_send_json_success();
} else {
- wp_send_json_error('Плагин установлен, но не удалось активировать: ' . (is_wp_error($activate_result) ? $activate_result->get_error_message() : 'Неизвестная ошибка'));
+ wp_send_json_error('Плагин установлен, но не удалось активировать: '.(is_wp_error($activate_result) ? $activate_result->get_error_message() : 'Неизвестная ошибка'));
}
} else {
wp_send_json_error('Не найден файл плагина для активации.');
@@ -406,38 +422,38 @@ public function install_plugin_ajax() {
public function add_actions()
{
- add_action( 'after_setup_theme', [ $this, 'after_setup_theme'] );
- add_action( 'admin_enqueue_scripts', [ $this, 'admin_assets' ], 20 );
- add_action( 'wp_ajax_install_my_plugin', [ $this, 'install_plugin_ajax' ] );
- add_action( 'wp_ajax_refresh_plugins_list', [ $this, 'refresh_plugins_list_ajax' ] );
- add_action( 'wp_ajax_uninstall_my_plugin', [ $this, 'uninstall_plugin_ajax' ] );
- add_action( 'wp_ajax_toggle_my_plugin', [ $this, 'toggle_plugin_ajax' ] );
+ add_action('after_setup_theme', [$this, 'after_setup_theme']);
+ add_action('admin_enqueue_scripts', [$this, 'admin_assets'], 20);
+ add_action('wp_ajax_install_my_plugin', [$this, 'install_plugin_ajax']);
+ add_action('wp_ajax_refresh_plugins_list', [$this, 'refresh_plugins_list_ajax']);
+ add_action('wp_ajax_uninstall_my_plugin', [$this, 'uninstall_plugin_ajax']);
+ add_action('wp_ajax_toggle_my_plugin', [$this, 'toggle_plugin_ajax']);
+ }
+
+ /**
+ * style and scripts in wp-admin
+ */
+ public function admin_assets($page)
+ {
+ if (strpos($page, $this->wp_plugin_slug) === false) {
+ return;
+ }
+
+ wp_enqueue_style($this->wp_plugin_slug,
+ RW_PLUGIN_URL.'assets/css/min/admin.min.css',
+ false,
+ $this->ver,
+ 'all');
}
- /**
- * style and scripts in wp-admin
- *
- * @param $page
- */
- public function admin_assets( $page ) {
- if ( false === strpos( $page, $this->wp_plugin_slug ) ) {
- return;
- }
-
- wp_enqueue_style( $this->wp_plugin_slug,
- RW_PLUGIN_URL . 'assets/css/min/admin.min.css',
- false,
- $this->ver,
- 'all' );
- }
-
- /**
- * @see http://codestarframework.com/documentation/#/fields?id=checkbox
- */
- public function after_setup_theme() {
-
- // Check core class for avoid errors
- if ( !class_exists( 'CSF' ) ){
+ /**
+ * @see http://codestarframework.com/documentation/#/fields?id=checkbox
+ */
+ public function after_setup_theme()
+ {
+
+ // Check core class for avoid errors
+ if (! class_exists('CSF')) {
return;
}
@@ -448,70 +464,70 @@ public function after_setup_theme() {
$prefix = $this->wp_plugin_slug;
// Create options
- \CSF::createOptions($prefix, require_once __DIR__ . '/_options.php');
+ \CSF::createOptions($prefix, require_once __DIR__.'/_options.php');
// General Settings
\CSF::createSection($prefix, [
- 'title' => __('General Settings', 'wp-addon'),
- 'icon' => 'fa fa-rocket',
- 'fields' => require_once __DIR__ . '/main.php',
+ 'title' => __('General Settings', 'wp-addon'),
+ 'icon' => 'fa fa-rocket',
+ 'fields' => require_once __DIR__.'/main.php',
]);
// Tweaks
\CSF::createSection($prefix, [
- 'title' => __('Tweaks', 'wp-addon'),
- 'icon' => 'fa fa-wordpress',
- 'fields' => require_once __DIR__ . '/tweaks.php',
+ 'title' => __('Tweaks', 'wp-addon'),
+ 'icon' => 'fa fa-wordpress',
+ 'fields' => require_once __DIR__.'/tweaks.php',
]);
// Cache
\CSF::createSection($prefix, [
- 'title' => __('Cache', 'wp-addon'),
- 'icon' => 'fa fa-database',
+ 'title' => __('Cache', 'wp-addon'),
+ 'icon' => 'fa fa-database',
'description' => __('Page caching saves ready HTML pages to a file. When a user visits the site, instead of executing PHP code and database queries, they are shown the saved page immediately. This speeds up site loading by 5-10 times.When to use: On a finished site with high traffic. When to disable: During development or if content changes frequently.Important: Cached pages are stored in the wp-content/cache/pages/ folder as .gz files.', 'wp-addon'),
'fields' => [
[
- 'id' => 'cache_enabled',
- 'type' => 'switcher',
+ 'id' => 'cache_enabled',
+ 'type' => 'switcher',
'title' => __('Enable page caching', 'wp-addon'),
- 'desc' => __('Main switch for enabling/disabling cache. When ON: all site pages are saved to cache. When OFF: cache is not used, pages are generated each time anew.', 'wp-addon'),
+ 'desc' => __('Main switch for enabling/disabling cache. When ON: all site pages are saved to cache. When OFF: cache is not used, pages are generated each time anew.', 'wp-addon'),
'default' => true,
],
[
- 'id' => 'cache_ttl',
- 'type' => 'number',
+ 'id' => 'cache_ttl',
+ 'type' => 'number',
'title' => __('Cache lifetime (seconds)', 'wp-addon'),
- 'desc' => __('How many seconds to store the cached page. After this time, the page will be recreated. For a news site - 1800 sec (30 min). For static - 3600 sec (1 hour).', 'wp-addon'),
+ 'desc' => __('How many seconds to store the cached page. After this time, the page will be recreated. For a news site - 1800 sec (30 min). For static - 3600 sec (1 hour).', 'wp-addon'),
'default' => 3600,
- 'min' => 300,
- 'max' => 86400,
+ 'min' => 300,
+ 'max' => 86400,
],
[
- 'id' => 'cache_exclude_logged_in',
- 'type' => 'switcher',
+ 'id' => 'cache_exclude_logged_in',
+ 'type' => 'switcher',
'title' => __('Do not cache for logged-in users', 'wp-addon'),
- 'desc' => __('If a user is logged into admin or personal account - show them fresh pages without cache. Otherwise, they may not see their changes or notifications.', 'wp-addon'),
+ 'desc' => __('If a user is logged into admin or personal account - show them fresh pages without cache. Otherwise, they may not see their changes or notifications.', 'wp-addon'),
'default' => true,
],
[
- 'id' => 'cache_exclude_urls',
- 'type' => 'textarea',
+ 'id' => 'cache_exclude_urls',
+ 'type' => 'textarea',
'title' => __('Do not cache these pages', 'wp-addon'),
- 'desc' => __('Pages that change frequently and should not be cached. One line - one URL. Examples: /wp-admin/ (admin), /checkout/ (checkout), /cart/ (cart), /my-account/ (personal account).', 'wp-addon'),
+ 'desc' => __('Pages that change frequently and should not be cached. One line - one URL. Examples: /wp-admin/ (admin), /checkout/ (checkout), /cart/ (cart), /my-account/ (personal account).', 'wp-addon'),
'default' => "/wp-admin/\n/wp-login.php\n/checkout/\n/cart/",
],
[
- 'id' => 'cache_preload_pages',
- 'type' => 'textarea',
+ 'id' => 'cache_preload_pages',
+ 'type' => 'textarea',
'title' => __('Preload these pages', 'wp-addon'),
- 'desc' => __('Pages for auto-caching every hour. Leave empty for automatic mode: the home page + all pages from the main site menu (up to 10 pcs) will be loaded. Or specify manually: one URL per line, for example /about/, /services/', 'wp-addon'),
- 'default' => "",
+ 'desc' => __('Pages for auto-caching every hour. Leave empty for automatic mode: the home page + all pages from the main site menu (up to 10 pcs) will be loaded. Or specify manually: one URL per line, for example /about/, /services/', 'wp-addon'),
+ 'default' => '',
],
[
- 'id' => 'cache_clear_on_post_save',
- 'type' => 'switcher',
+ 'id' => 'cache_clear_on_post_save',
+ 'type' => 'switcher',
'title' => __('Clear cache on post publish', 'wp-addon'),
- 'desc' => __('When you publish a new article or edit an old one - automatically delete all cache. So readers will immediately see fresh content. Disable if you publish often - this will slow down the site.', 'wp-addon'),
+ 'desc' => __('When you publish a new article or edit an old one - automatically delete all cache. So readers will immediately see fresh content. Disable if you publish often - this will slow down the site.', 'wp-addon'),
'default' => true,
],
],
@@ -519,78 +535,78 @@ public function after_setup_theme() {
// Asset Minification
\CSF::createSection($prefix, [
- 'title' => __('Asset Minification', 'wp-addon'),
- 'icon' => 'fa fa-compress',
+ 'title' => __('Asset Minification', 'wp-addon'),
+ 'icon' => 'fa fa-compress',
'description' => __('Asset optimization is a comprehensive system for improving site performance by minifying and combining CSS/JavaScript files. The module automatically analyzes all connected resources and applies optimal optimization strategies.Benefits: • Reduce file size by 20-40% • Decrease number of HTTP requests • Speed up page loading • Better PageSpeed Insights scoresAutomatic logic: • Excludes WordPress system resources • Does not process files smaller than 1KB • Skips already minified files • Analyzes resource loading priorities', 'wp-addon'),
'fields' => [
[
- 'id' => 'asset_minification_enabled',
- 'type' => 'switcher',
+ 'id' => 'asset_minification_enabled',
+ 'type' => 'switcher',
'title' => __('Enable asset optimization', 'wp-addon'),
- 'desc' => __('Main switch of the optimization module. When enabled, intelligent processing of all CSS and JavaScript resources on the site is activated. Recommended to enable on production sites for maximum performance.', 'wp-addon'),
+ 'desc' => __('Main switch of the optimization module. When enabled, intelligent processing of all CSS and JavaScript resources on the site is activated. Recommended to enable on production sites for maximum performance.', 'wp-addon'),
'default' => true,
],
[
- 'id' => 'asset_minify_css',
- 'type' => 'switcher',
+ 'id' => 'asset_minify_css',
+ 'type' => 'switcher',
'title' => __('Minify CSS files', 'wp-addon'),
- 'desc' => __('Removes from CSS files: comments, extra spaces, line breaks and tabs. Does not process files that are already minified or smaller than 1KB. Traffic savings: 15-30% per file.', 'wp-addon'),
+ 'desc' => __('Removes from CSS files: comments, extra spaces, line breaks and tabs. Does not process files that are already minified or smaller than 1KB. Traffic savings: 15-30% per file.', 'wp-addon'),
'default' => true,
'dependency' => ['asset_minification_enabled', '==', 'true'],
],
[
- 'id' => 'asset_minify_js',
- 'type' => 'switcher',
+ 'id' => 'asset_minify_js',
+ 'type' => 'switcher',
'title' => __('Minify JavaScript files', 'wp-addon'),
- 'desc' => __('Compresses JS code by removing comments, extra spaces and formatting. Skips minified files and files smaller than 1KB. Important: check functionality after enabling, as some plugins may have minification-sensitive code.', 'wp-addon'),
+ 'desc' => __('Compresses JS code by removing comments, extra spaces and formatting. Skips minified files and files smaller than 1KB. Important: check functionality after enabling, as some plugins may have minification-sensitive code.', 'wp-addon'),
'default' => false,
'dependency' => ['asset_minification_enabled', '==', 'true'],
],
[
- 'id' => 'asset_combine_css',
- 'type' => 'switcher',
+ 'id' => 'asset_combine_css',
+ 'type' => 'switcher',
'title' => __('Combine CSS files', 'wp-addon'),
- 'desc' => __('Collects all suitable CSS files into one combined file, reducing the number of HTTP requests to the server. Automatically excludes WordPress system styles. Effective for sites with 3+ CSS files.', 'wp-addon'),
+ 'desc' => __('Collects all suitable CSS files into one combined file, reducing the number of HTTP requests to the server. Automatically excludes WordPress system styles. Effective for sites with 3+ CSS files.', 'wp-addon'),
'default' => true,
'dependency' => ['asset_minification_enabled', '==', 'true'],
],
[
- 'id' => 'asset_combine_js',
- 'type' => 'switcher',
+ 'id' => 'asset_combine_js',
+ 'type' => 'switcher',
'title' => __('Combine JavaScript files', 'wp-addon'),
- 'desc' => __('Combines JS files into one loaded in the footer. Reduces the number of requests, but may break loading order. Recommended to test for JavaScript errors after enabling.', 'wp-addon'),
+ 'desc' => __('Combines JS files into one loaded in the footer. Reduces the number of requests, but may break loading order. Recommended to test for JavaScript errors after enabling.', 'wp-addon'),
'default' => false,
'dependency' => ['asset_minification_enabled', '==', 'true'],
],
[
- 'id' => 'asset_critical_css_enabled',
- 'type' => 'switcher',
+ 'id' => 'asset_critical_css_enabled',
+ 'type' => 'switcher',
'title' => __('Implement critical CSS', 'wp-addon'),
- 'desc' => __('Automatically extracts and embeds inline critical CSS styles (header, menu, main content) for instant display of above-the-fold content. Improves First Contentful Paint score in Lighthouse.', 'wp-addon'),
+ 'desc' => __('Automatically extracts and embeds inline critical CSS styles (header, menu, main content) for instant display of above-the-fold content. Improves First Contentful Paint score in Lighthouse.', 'wp-addon'),
'default' => true,
'dependency' => ['asset_minification_enabled', '==', 'true'],
],
[
- 'id' => 'asset_defer_non_critical_css',
- 'type' => 'switcher',
+ 'id' => 'asset_defer_non_critical_css',
+ 'type' => 'switcher',
'title' => __('Defer non-critical CSS', 'wp-addon'),
- 'desc' => __('Loads non-critical CSS files asynchronously after page rendering. Prevents render blocking, but may cause brief "flash of unstyled content" (FOUC).', 'wp-addon'),
+ 'desc' => __('Loads non-critical CSS files asynchronously after page rendering. Prevents render blocking, but may cause brief "flash of unstyled content" (FOUC).', 'wp-addon'),
'default' => true,
'dependency' => ['asset_minification_enabled', '==', 'true'],
],
[
- 'id' => 'asset_exclude_css',
- 'type' => 'textarea',
+ 'id' => 'asset_exclude_css',
+ 'type' => 'textarea',
'title' => __('Exclude CSS files', 'wp-addon'),
- 'desc' => __('List of CSS file handles separated by comma that should not be optimized. Examples: critical-styles, admin-css, custom-admin-styles. WordPress system files are excluded automatically.', 'wp-addon'),
+ 'desc' => __('List of CSS file handles separated by comma that should not be optimized. Examples: critical-styles, admin-css, custom-admin-styles. WordPress system files are excluded automatically.', 'wp-addon'),
'default' => 'admin-bar,dashicons',
'dependency' => ['asset_minification_enabled', '==', 'true'],
],
[
- 'id' => 'asset_exclude_js',
- 'type' => 'textarea',
+ 'id' => 'asset_exclude_js',
+ 'type' => 'textarea',
'title' => __('Exclude JavaScript files', 'wp-addon'),
- 'desc' => __('JS file handles separated by comma for exclusion from optimization. Examples: google-analytics, facebook-pixel, custom-scripts. WordPress system scripts (jQuery, etc.) are excluded automatically.', 'wp-addon'),
+ 'desc' => __('JS file handles separated by comma for exclusion from optimization. Examples: google-analytics, facebook-pixel, custom-scripts. WordPress system scripts (jQuery, etc.) are excluded automatically.', 'wp-addon'),
'default' => 'jquery,jquery-core',
'dependency' => ['asset_minification_enabled', '==', 'true'],
],
@@ -599,22 +615,22 @@ public function after_setup_theme() {
// Lazy Loading
\CSF::createSection($prefix, [
- 'title' => __('Lazy Loading', 'wp-addon'),
- 'icon' => 'fa fa-eye',
+ 'title' => __('Lazy Loading', 'wp-addon'),
+ 'icon' => 'fa fa-eye',
'description' => __('Lazy loading of images and media files is a performance optimization technique where resources are loaded only when they come into the user\'s view. The module uses the modern Intersection Observer API with fallback for older browsers.Benefits: • Reduced page load time • Traffic savings (especially on mobile devices) • Improved Core Web Vitals (LCP, CLS) • Automatic image compression with blur placeholderSupport: • Images (img) • Iframe (YouTube, Vimeo videos) • Video elements • Blur placeholder for smooth loading • Fallback for IE11+', 'wp-addon'),
'fields' => [
[
- 'id' => 'enable_lazy_loading',
- 'type' => 'switcher',
+ 'id' => 'enable_lazy_loading',
+ 'type' => 'switcher',
'title' => __('Enable lazy loading', 'wp-addon'),
- 'desc' => __('Main switch of the module. When enabled, lazy loading is activated for selected media types. Recommended to enable on all sites for improved performance.', 'wp-addon'),
+ 'desc' => __('Main switch of the module. When enabled, lazy loading is activated for selected media types. Recommended to enable on all sites for improved performance.', 'wp-addon'),
'default' => false,
],
[
- 'id' => 'lazy_types',
- 'type' => 'checkbox',
+ 'id' => 'lazy_types',
+ 'type' => 'checkbox',
'title' => __('Media types for lazy loading', 'wp-addon'),
- 'desc' => __('Select element types for which lazy loading will be applied. Images are most effective for optimization.', 'wp-addon'),
+ 'desc' => __('Select element types for which lazy loading will be applied. Images are most effective for optimization.', 'wp-addon'),
'options' => [
'img' => __('Images (img)', 'wp-addon'),
'iframe' => __('Iframe (YouTube, Vimeo)', 'wp-addon'),
@@ -624,20 +640,20 @@ public function after_setup_theme() {
'dependency' => ['enable_lazy_loading', '==', 'true'],
],
[
- 'id' => 'blur_intensity',
- 'type' => 'number',
+ 'id' => 'blur_intensity',
+ 'type' => 'number',
'title' => __('Blur effect intensity', 'wp-addon'),
- 'desc' => __('Degree of blur placeholder blur. Value 1 - weak blur, 10 - strong. Recommended 3-7 for optimal quality and performance balance.', 'wp-addon'),
+ 'desc' => __('Degree of blur placeholder blur. Value 1 - weak blur, 10 - strong. Recommended 3-7 for optimal quality and performance balance.', 'wp-addon'),
'default' => 5,
- 'min' => 1,
- 'max' => 10,
+ 'min' => 1,
+ 'max' => 10,
'dependency' => ['enable_lazy_loading', '==', 'true'],
],
[
- 'id' => 'root_margin',
- 'type' => 'text',
+ 'id' => 'root_margin',
+ 'type' => 'text',
'title' => __('Viewport margin (rootMargin)', 'wp-addon'),
- 'desc' => __('Distance from viewport edge at which to start loading. Example: 50px - loading 50px before element appears. 10% - 10% of viewport height.', 'wp-addon'),
+ 'desc' => __('Distance from viewport edge at which to start loading. Example: 50px - loading 50px before element appears. 10% - 10% of viewport height.', 'wp-addon'),
'default' => '50px',
'attributes' => [
'placeholder' => '50px',
@@ -645,21 +661,21 @@ public function after_setup_theme() {
'dependency' => ['enable_lazy_loading', '==', 'true'],
],
[
- 'id' => 'threshold',
- 'type' => 'number',
+ 'id' => 'threshold',
+ 'type' => 'number',
'title' => __('Visibility threshold', 'wp-addon'),
- 'desc' => __('The portion of the element that must enter the viewport to start loading. 0.1 = 10% of element visible. 1.0 = entire element visible.', 'wp-addon'),
+ 'desc' => __('The portion of the element that must enter the viewport to start loading. 0.1 = 10% of element visible. 1.0 = entire element visible.', 'wp-addon'),
'default' => 0.1,
- 'min' => 0,
- 'max' => 1,
- 'step' => 0.1,
+ 'min' => 0,
+ 'max' => 1,
+ 'step' => 0.1,
'dependency' => ['enable_lazy_loading', '==', 'true'],
],
[
- 'id' => 'enable_fallback',
- 'type' => 'switcher',
+ 'id' => 'enable_fallback',
+ 'type' => 'switcher',
'title' => __('Enable fallback for older browsers', 'wp-addon'),
- 'desc' => __('Use scroll event listeners instead of Intersection Observer in browsers without IO API support. Slows performance but ensures compatibility.', 'wp-addon'),
+ 'desc' => __('Use scroll event listeners instead of Intersection Observer in browsers without IO API support. Slows performance but ensures compatibility.', 'wp-addon'),
'default' => true,
'dependency' => ['enable_lazy_loading', '==', 'true'],
],
@@ -668,67 +684,67 @@ public function after_setup_theme() {
// Media Cleanup
\CSF::createSection($prefix, [
- 'title' => __('Media Cleanup', 'wp-addon'),
- 'icon' => 'fa fa-image',
+ 'title' => __('Media Cleanup', 'wp-addon'),
+ 'icon' => 'fa fa-image',
'description' => __('This section allows you to clean up unused image sizes to free up disk space. WordPress generates multiple sizes for each uploaded image, but if your theme or plugins don\'t use all of them, they take up unnecessary space. Use this tool to identify and remove such files.When to use: After changing themes, disabling plugins that generate custom sizes, or optimizing site performance.Precautions: Always create a backup before cleanup. Use "Preview Cleanup" first to see what will be deleted. The tool preserves original images and "scaled" versions (up to 2000px). Deleted files cannot be recovered!', 'wp-addon'),
'fields' => [
[
- 'id' => 'media_cleanup_enabled',
- 'type' => 'switcher',
- 'title' => __('Enable Media Cleanup', 'wp-addon'),
- 'desc' => __('Registers the cleanup AJAX actions. Keep disabled until you are ready to review and remove generated image sizes.', 'wp-addon'),
+ 'id' => 'media_cleanup_enabled',
+ 'type' => 'switcher',
+ 'title' => __('Enable Media Cleanup', 'wp-addon'),
+ 'desc' => __('Registers the cleanup AJAX actions. Keep disabled until you are ready to review and remove generated image sizes.', 'wp-addon'),
'default' => false,
],
[
- 'id' => 'cleanup_images',
- 'type' => 'content',
- 'title' => __('Clean up unused image sizes', 'wp-addon'),
+ 'id' => 'cleanup_images',
+ 'type' => 'content',
+ 'title' => __('Clean up unused image sizes', 'wp-addon'),
'dependency' => ['media_cleanup_enabled', '==', 'true'],
- 'content' => '' . sprintf(__('This will delete all image sizes except: %s. Files will be deleted permanently!', 'wp-addon'), implode(', ', MediaCleanupService::getRegisteredSizesStatic())) . '
' . __('Preview Cleanup', 'wp-addon') . ' ' . __('Start Cleanup', 'wp-addon') . '
',
+ 'content' => ''.sprintf(__('This will delete all image sizes except: %s. Files will be deleted permanently!', 'wp-addon'), implode(', ', MediaCleanupService::getRegisteredSizesStatic())).'
'.__('Preview Cleanup', 'wp-addon').' '.__('Start Cleanup', 'wp-addon').'
',
],
],
]);
// Redirects
\CSF::createSection($prefix, [
- 'title' => __('Redirects', 'wp-addon'),
- 'icon' => 'fa fa-share',
+ 'title' => __('Redirects', 'wp-addon'),
+ 'icon' => 'fa fa-share',
'description' => __('301 redirect management. Create redirect rules from one URL to another. Supports both simple redirection and wildcard (*) usage for folder redirection.Simple redirects: /old-page/ → /new-page/Wildcard redirects: /old-folder/* → /new-folder/*Important: Redirects apply to all requests except wp-admin and wp-login to prevent admin access blocking.', 'wp-addon'),
'fields' => [
[
- 'id' => 'redirect_enable',
- 'type' => 'switcher',
- 'title' => __('Enable redirects', 'wp-addon'),
- 'desc' => __('When disabled, redirect rules are not registered or processed.', 'wp-addon'),
+ 'id' => 'redirect_enable',
+ 'type' => 'switcher',
+ 'title' => __('Enable redirects', 'wp-addon'),
+ 'desc' => __('When disabled, redirect rules are not registered or processed.', 'wp-addon'),
'default' => true,
],
[
- 'id' => 'redirects_wildcard',
- 'type' => 'switcher',
+ 'id' => 'redirects_wildcard',
+ 'type' => 'switcher',
'title' => __('Use wildcard redirects', 'wp-addon'),
- 'desc' => __('Enable for * symbol support in URLs. Example: /old-folder/* will redirect all pages from old-folder to corresponding pages in new-folder.', 'wp-addon'),
+ 'desc' => __('Enable for * symbol support in URLs. Example: /old-folder/* will redirect all pages from old-folder to corresponding pages in new-folder.', 'wp-addon'),
'default' => false,
],
[
- 'id' => 'redirects_rules',
- 'type' => 'repeater',
+ 'id' => 'redirects_rules',
+ 'type' => 'repeater',
'title' => __('Redirect rules', 'wp-addon'),
- 'desc' => __('Add redirection rules. Request - source URL (relative to site root), Destination - target URL.', 'wp-addon'),
+ 'desc' => __('Add redirection rules. Request - source URL (relative to site root), Destination - target URL.', 'wp-addon'),
'fields' => [
[
- 'id' => 'request',
- 'type' => 'text',
+ 'id' => 'request',
+ 'type' => 'text',
'title' => __('Request URL', 'wp-addon'),
- 'desc' => __('Source URL for redirection. Example: /old-page/ or /old-folder/*', 'wp-addon'),
+ 'desc' => __('Source URL for redirection. Example: /old-page/ or /old-folder/*', 'wp-addon'),
'attributes' => [
'placeholder' => '/old-page/',
],
],
[
- 'id' => 'destination',
- 'type' => 'text',
+ 'id' => 'destination',
+ 'type' => 'text',
'title' => __('Destination URL', 'wp-addon'),
- 'desc' => __('Target URL. Can be relative (/new-page/) or absolute (https://example.com/new-page/)', 'wp-addon'),
+ 'desc' => __('Target URL. Can be relative (/new-page/) or absolute (https://example.com/new-page/)', 'wp-addon'),
'attributes' => [
'placeholder' => '/new-page/',
],
@@ -741,74 +757,72 @@ public function after_setup_theme() {
// Shortcodes and Widgets
\CSF::createSection($prefix, [
- 'title' => __('Shortcodes and Widgets', 'wp-addon'),
- 'icon' => 'fa fa-bolt',
- 'fields' => require __DIR__ . '/wp-widgets.php',
+ 'title' => __('Shortcodes and Widgets', 'wp-addon'),
+ 'icon' => 'fa fa-bolt',
+ 'fields' => require __DIR__.'/wp-widgets.php',
]);
-
-
do_action('wp_addon_settings_section', $prefix);
// Custom Code
\CSF::createSection($prefix, [
- 'title' => __('Custom code', 'wp-addon'),
- 'icon' => 'fa fa-code',
+ 'title' => __('Custom code', 'wp-addon'),
+ 'icon' => 'fa fa-code',
'fields' => [
[
- 'id' => 'rw_header_css',
- 'type' => 'code_editor',
- 'title' => __('CSS Code in Header', 'wp-addon'),
+ 'id' => 'rw_header_css',
+ 'type' => 'code_editor',
+ 'title' => __('CSS Code in Header', 'wp-addon'),
'settings' => [
'theme' => 'mbo',
- 'mode' => 'css',
+ 'mode' => 'css',
],
'sanitize' => false,
],
[
- 'id' => 'rw_header_html',
- 'type' => 'code_editor',
- 'title' => __('Any HTML code or Analytics code in header.',
+ 'id' => 'rw_header_html',
+ 'type' => 'code_editor',
+ 'title' => __('Any HTML code or Analytics code in header.',
'wp-addon'),
'settings' => [
'theme' => 'monokai',
- 'mode' => 'htmlmixed',
+ 'mode' => 'htmlmixed',
],
- 'default' => '',
+ 'default' => '',
'sanitize' => false,
],
[
- 'id' => 'rw_footer_html',
- 'type' => 'code_editor',
- 'title' => __('Any HTML code in footer.', 'wp-addon'),
+ 'id' => 'rw_footer_html',
+ 'type' => 'code_editor',
+ 'title' => __('Any HTML code in footer.', 'wp-addon'),
'settings' => [
'theme' => 'monokai',
- //'mode' => 'php',
+ // 'mode' => 'php',
],
- 'default' => '',
+ 'default' => '',
'sanitize' => false,
],
- ],// #fields
+ ], // #fields
]);
// Markdown Editor
\CSF::createSection($prefix, [
- 'title' => __('Markdown Editor', 'wp-addon'),
- 'icon' => 'fa fa-edit',
+ 'title' => __('Markdown Editor', 'wp-addon'),
+ 'icon' => 'fa fa-edit',
'description' => __('Markdown Editor позволяет писать статьи в удобном формате Markdown и автоматически конвертировать их в HTML. Поддерживает синтаксис заголовков, списков, ссылок, изображений, кода и других элементов.Преимущества: • Простой и читаемый синтаксис • Быстрое форматирование текста • Предпросмотр в реальном времени • Горячие клавиши для ускорения работы • Автоматическое преобразование в HTMLПоддерживаемые элементы: • Заголовки (# ## ###) • Жирный (**текст**) и курсив (*текст*) • Ссылки [текст](url) • Изображения  • Списки маркированные и нумерованные • Код `inline` и блоки кода • Цитаты и горизонтальные линии', 'wp-addon'),
'fields' => [
[
- 'id' => 'wp_addon_markdown_enabled',
- 'type' => 'switcher',
+ 'id' => 'wp_addon_markdown_enabled',
+ 'type' => 'switcher',
'title' => __('Enable Markdown Editor', 'wp-addon'),
- 'desc' => __('Включает Markdown редактор для постов и страниц. При включении в админ-панели появится дополнительный блок для редактирования контента в формате Markdown с предпросмотром.', 'wp-addon'),
+ 'desc' => __('Включает Markdown редактор для постов и страниц. При включении в админ-панели появится дополнительный блок для редактирования контента в формате Markdown с предпросмотром.', 'wp-addon'),
'default' => false,
],
[
- 'id' => 'markdown_post_types',
- 'type' => 'checkbox',
+ 'id' => 'markdown_post_types',
+ 'type' => 'checkbox',
'title' => __('Post types for Markdown', 'wp-addon'),
- 'desc' => __('Выберите типы постов, для которых будет доступен Markdown редактор.', 'wp-addon'),
+ 'desc' => __('Выберите типы постов, для которых будет доступен Markdown редактор.', 'wp-addon'),
'options' => [
'post' => __('Posts', 'wp-addon'),
'page' => __('Pages', 'wp-addon'),
@@ -817,39 +831,39 @@ public function after_setup_theme() {
'dependency' => ['wp_addon_markdown_enabled', '==', 'true'],
],
[
- 'id' => 'markdown_replace_tinymce',
- 'type' => 'switcher',
+ 'id' => 'markdown_replace_tinymce',
+ 'type' => 'switcher',
'title' => __('Replace TinyMCE editor', 'wp-addon'),
- 'desc' => __('Заменить стандартный редактор TinyMCE на Markdown редактор по умолчанию. При отключении оба редактора будут доступны.', 'wp-addon'),
+ 'desc' => __('Заменить стандартный редактор TinyMCE на Markdown редактор по умолчанию. При отключении оба редактора будут доступны.', 'wp-addon'),
'default' => false,
'dependency' => ['wp_addon_markdown_enabled', '==', 'true'],
],
[
- 'id' => 'markdown_enable_preview',
- 'type' => 'switcher',
+ 'id' => 'markdown_enable_preview',
+ 'type' => 'switcher',
'title' => __('Enable live preview', 'wp-addon'),
- 'desc' => __('Включает предпросмотр Markdown в реальном времени. Показывает как будет выглядеть контент после публикации.', 'wp-addon'),
+ 'desc' => __('Включает предпросмотр Markdown в реальном времени. Показывает как будет выглядеть контент после публикации.', 'wp-addon'),
'default' => true,
'dependency' => ['wp_addon_markdown_enabled', '==', 'true'],
],
[
- 'id' => 'markdown_enable_shortcuts',
- 'type' => 'switcher',
+ 'id' => 'markdown_enable_shortcuts',
+ 'type' => 'switcher',
'title' => __('Enable keyboard shortcuts', 'wp-addon'),
- 'desc' => __('Активирует горячие клавиши для быстрого форматирования: Ctrl+B (жирный), Ctrl+I (курсив), Ctrl+K (ссылка), Tab (отступ).', 'wp-addon'),
+ 'desc' => __('Активирует горячие клавиши для быстрого форматирования: Ctrl+B (жирный), Ctrl+I (курсив), Ctrl+K (ссылка), Tab (отступ).', 'wp-addon'),
'default' => true,
'dependency' => ['wp_addon_markdown_enabled', '==', 'true'],
],
[
- 'id' => 'markdown_migrate_existing',
- 'type' => 'switcher',
+ 'id' => 'markdown_migrate_existing',
+ 'type' => 'switcher',
'title' => __('Convert existing HTML to Markdown', 'wp-addon'),
- 'desc' => __('Автоматически конвертирует существующий HTML контент в Markdown при первом редактировании поста. Необратимая операция.', 'wp-addon'),
+ 'desc' => __('Автоматически конвертирует существующий HTML контент в Markdown при первом редактировании поста. Необратимая операция.', 'wp-addon'),
'default' => false,
'dependency' => ['wp_addon_markdown_enabled', '==', 'true'],
],
[
- 'type' => 'content',
+ 'type' => 'content',
'content' => '
📝 Справка по Markdown синтаксису:
@@ -883,27 +897,27 @@ public function after_setup_theme() {
// BackUp
\CSF::createSection($prefix, [
- 'title' => __('Backup Settings', 'wp-addon'),
- 'icon' => 'fa fa-server',
+ 'title' => __('Backup Settings', 'wp-addon'),
+ 'icon' => 'fa fa-server',
'fields' => [
[
'title' => __('Download settings now', 'wp-addon'),
- 'desc' => __('You can get or set settings from backup'),
- 'type' => 'backup',
+ 'desc' => __('You can get or set settings from backup'),
+ 'type' => 'backup',
],
],
]);
- // My Plugins
- \CSF::createSection($prefix, [
- 'title' => __('Мои плагины', 'wp-addon'),
- 'icon' => 'fa fa-plug',
- 'fields' => [
- [
- 'type' => 'content',
- 'content' => $this->get_plugins_html(),
- ],
- ],
- ]);
- }
+ // My Plugins
+ \CSF::createSection($prefix, [
+ 'title' => __('Мои плагины', 'wp-addon'),
+ 'icon' => 'fa fa-plug',
+ 'fields' => [
+ [
+ 'type' => 'content',
+ 'content' => $this->get_plugins_html(),
+ ],
+ ],
+ ]);
+ }
}
diff --git a/src/Config/wp-widgets.php b/src/Config/wp-widgets.php
index 2925e8f..cf68c3a 100644
--- a/src/Config/wp-widgets.php
+++ b/src/Config/wp-widgets.php
@@ -1,69 +1,68 @@
'content',
+ 'type' => 'content',
'content' => '',
],
[
- 'id' => 'disable_guttenberg_widget',
- 'type' => 'switcher',
- 'title' => __( 'Disable guttenberg for widgets', 'wp-addon' ),
+ 'id' => 'disable_guttenberg_widget',
+ 'type' => 'switcher',
+ 'title' => __('Disable guttenberg for widgets', 'wp-addon'),
'default' => true,
],
[
- 'id' => 'add_clone_widget',
- 'type' => 'switcher',
- 'title' => __( 'Enable Duplicate widgets', 'wp-addon' ),
+ 'id' => 'add_clone_widget',
+ 'type' => 'switcher',
+ 'title' => __('Enable Duplicate widgets', 'wp-addon'),
'default' => true,
],
- /*[
- 'id' => 'custom_sidebars',
- 'type' => 'switcher',
- 'title' => __( 'Enable custom Dynamic sidebars', 'wp-addon' ),
- 'default' => true,
- ],*/
+ /*[
+ 'id' => 'custom_sidebars',
+ 'type' => 'switcher',
+ 'title' => __( 'Enable custom Dynamic sidebars', 'wp-addon' ),
+ 'default' => true,
+ ],*/
[ // Shortcodes
- 'id' => 'components',
- 'type' => 'tabbed',
- 'title' => __('Components', 'wp-addon'),
+ 'id' => 'components',
+ 'type' => 'tabbed',
+ 'title' => __('Components', 'wp-addon'),
'subtitle' => '',
- 'tabs' => [
+ 'tabs' => [
+ [
+ 'title' => __('Shortcodes', 'rw-addon'),
+ 'icon' => '',
+ 'fields' => [
+ [
+ 'id' => 'faq_shortcode',
+ 'type' => 'switcher',
+ 'title' => __('Enable FAQ shortcode', 'wp-addon'),
+ 'desc' => __('WPBakery Page Builder support ', 'wp-addon'),
+ 'default' => true,
+ ],
+ [
+ 'id' => 'table_of_contents',
+ 'type' => 'switcher',
+ 'title' => __('Enable Table of Content shortcode', 'wp-addon'),
+ 'desc' => __('WPBakery Page Builder support ', 'wp-addon'),
+ 'default' => true,
+ ],
+ ],
+ ],
[
- 'title' => __('Shortcodes', 'rw-addon'),
- 'icon' => '',
+ 'title' => __('Widgets', 'rw-addon'),
+ 'icon' => 'fa fa-connectdevelop',
'fields' => [
- [
- 'id' => 'faq_shortcode',
- 'type' => 'switcher',
- 'title' => __('Enable FAQ shortcode', 'wp-addon'),
- 'desc' => __('WPBakery Page Builder support ', 'wp-addon'),
- 'default' => true,
- ],
- [
- 'id' => 'table_of_contents',
- 'type' => 'switcher',
- 'title' => __('Enable Table of Content shortcode', 'wp-addon'),
- 'desc' => __('WPBakery Page Builder support ', 'wp-addon'),
- 'default' => true,
- ],
+ [
+ 'id' => 'archive_widget',
+ 'type' => 'switcher',
+ 'title' => __('Yearly archive widget', 'wp-addon'),
+ 'default' => true,
+ ],
],
],
- [
- 'title' => __('Widgets', 'rw-addon'),
- 'icon' => 'fa fa-connectdevelop',
- 'fields' => [
- [
- 'id' => 'archive_widget',
- 'type' => 'switcher',
- 'title' => __('Yearly archive widget', 'wp-addon'),
- 'default' => true,
- ],
- ],
- ],
],
],
-];
\ No newline at end of file
+];
diff --git a/src/ControllerWP.php b/src/ControllerWP.php
index 83901ba..efe7dad 100644
--- a/src/ControllerWP.php
+++ b/src/ControllerWP.php
@@ -7,12 +7,11 @@
final class ControllerWP
{
private OptionService $optionService;
+
private array $options;
/**
* Constructor
- *
- * @param OptionService $optionService
*/
public function __construct(OptionService $optionService)
{
@@ -25,15 +24,15 @@ public function __construct(OptionService $optionService)
*/
public function options_loader()
{
- if (!is_array($this->options)) {
+ if (! is_array($this->options)) {
return;
}
- /**
- * @var string $key Option name
- * @var int|array|false $value Option value
- */
- foreach ($this->options as $key => $value) {
+ /**
+ * @var string $key Option name
+ * @var int|array|false $value Option value
+ */
+ foreach ($this->options as $key => $value) {
if ($value == 1) {
$this->run($key); // 'plugins_loaded'
} elseif (is_array($value)) { // block options
@@ -49,8 +48,7 @@ public function options_loader()
/**
* Запускаем если есть такая функция
*
- * @param $function
- * @param $settings
+ * @param $settings
*/
protected function run($function)
{
@@ -59,6 +57,4 @@ protected function run($function)
add_action('init', $function, 1);
}
}
-
-
-}
\ No newline at end of file
+}
diff --git a/src/Core/Plugin.php b/src/Core/Plugin.php
index ed1267d..3a2d9d2 100644
--- a/src/Core/Plugin.php
+++ b/src/Core/Plugin.php
@@ -2,11 +2,21 @@
namespace WpAddon\Core;
+use WpAddon\ControllerWP;
+use WpAddon\FrontWP;
+use WpAddon\Services\AssetService;
+use WpAddon\Services\ImageOptimizationService;
+use WpAddon\Services\MediaCleanupService;
+use WpAddon\Services\OptionService;
+use WpAddon\WP_Addon_Settings;
+
/**
* Main Plugin class for initialization and constants
*/
class Plugin
{
+ private bool $initialized = false;
+
/**
* Plugin file path
*/
@@ -25,7 +35,7 @@ class Plugin
/**
* Plugin version
*/
- private string $version = '1.3.6';
+ private string $version = '1.4.0';
/**
* Text domain
@@ -35,27 +45,27 @@ class Plugin
/**
* Option service
*/
- private \WpAddon\Services\OptionService $optionService;
+ private OptionService $optionService;
/**
* Asset service
*/
- private \WpAddon\Services\AssetService $assetService;
+ private AssetService $assetService;
/**
* Media cleanup service
*/
- private \WpAddon\Services\MediaCleanupService $mediaCleanupService;
+ private MediaCleanupService $mediaCleanupService;
/**
* Image optimization service
*/
- private \WpAddon\Services\ImageOptimizationService $imageOptimizationService;
+ private ImageOptimizationService $imageOptimizationService;
/**
* Constructor
*
- * @param string $file Plugin file path
+ * @param string $file Plugin file path
*/
public function __construct(string $file)
{
@@ -69,10 +79,15 @@ public function __construct(string $file)
*/
public function init(): void
{
+ if ($this->initialized) {
+ return;
+ }
+
+ $this->initialized = true;
register_activation_hook($this->file, [$this, 'activate']);
$this->defineConstants();
- $this->loadLocales();
+ $this->loadLocales();
$this->loadDependencies();
$this->addHooks();
}
@@ -82,91 +97,53 @@ public function init(): void
*/
public function activate(): void
{
- // Check if CodeStar Framework is installed
- if (!class_exists('CSF')) {
- $this->installCodestarFramework();
+ if (! class_exists('CSF')) {
+ add_action('admin_notices', [$this, 'renderMissingCodeStarNotice']);
}
}
- /**
- * Install CodeStar Framework
- */
- private function installCodestarFramework(): void
+ public function renderMissingCodeStarNotice(): void
{
- $csf_dir = $this->dir . 'lib/codestar-framework/';
-
- // Check if already downloaded
- if (file_exists($csf_dir . 'codestar-framework.php')) {
- require_once $csf_dir . 'codestar-framework.php';
+ if (! current_user_can('activate_plugins')) {
return;
}
- // Download CodeStar Framework
- $zip_url = 'https://github.com/Codestar/codestar-framework/archive/refs/heads/master.zip';
- $temp_zip = download_url($zip_url);
-
- if (is_wp_error($temp_zip)) {
- wp_die(__('Error downloading CodeStar Framework. Please install it manually from https://github.com/Codestar/codestar-framework', 'wp-addon'));
- }
-
- // Unzip
- WP_Filesystem();
- global $wp_filesystem;
-
- $unzip_result = unzip_file($temp_zip, $this->dir . 'lib/');
-
- // Clean up temp file
- @unlink($temp_zip);
-
- if (is_wp_error($unzip_result)) {
- wp_die(__('Error unpacking CodeStar Framework. Please install it manually.', 'wp-addon'));
- }
-
- // Rename directory
- $extracted_dir = $this->dir . 'lib/codestar-framework-master/';
- if (file_exists($extracted_dir)) {
- $wp_filesystem->move($extracted_dir, $csf_dir);
- }
-
- // Include CSF
- if (file_exists($csf_dir . 'codestar-framework.php')) {
- require_once $csf_dir . 'codestar-framework.php';
- } else {
- wp_die(__('CodeStar Framework not found after installation. Please install it manually.', 'wp-addon'));
- }
+ echo '
'
+ .esc_html__('WP Addon requires the bundled CodeStar Framework. Reinstall the plugin from a complete release package.', 'wp-addon')
+ .'
';
}
-
- private function loadLocales(): void {
- add_action( 'plugins_loaded', function () {
- $domain = 'wp-addon';
- $path = dirname( plugin_basename( RW_FILE ) ) . '/languages';
- load_plugin_textdomain( $domain, false, $path );
- }, 9 );
- }
+ private function loadLocales(): void
+ {
+ add_action('plugins_loaded', function () {
+ $domain = 'wp-addon';
+ $path = dirname(plugin_basename(RW_FILE)).'/languages';
+ load_plugin_textdomain($domain, false, $path);
+ }, 9);
+ }
/**
* Define plugin constants
*/
private function defineConstants(): void
{
- if (!defined('RW_LANG')) {
+ if (! defined('RW_LANG')) {
define('RW_LANG', $this->textDomain);
}
- if (!defined('RW_PLUGIN_DIR')) {
+ if (! defined('RW_PLUGIN_DIR')) {
define('RW_PLUGIN_DIR', $this->dir);
}
- if (!defined('RW_PLUGIN_URL')) {
+ if (! defined('RW_PLUGIN_URL')) {
define('RW_PLUGIN_URL', $this->url);
}
- if (!defined('RW_FILE')) {
+ if (! defined('RW_FILE')) {
define('RW_FILE', $this->file);
}
- if (!defined('WP_ADDON_VERSION')) {
+ if (! defined('WP_ADDON_VERSION')) {
define('WP_ADDON_VERSION', $this->version);
}
}
@@ -177,19 +154,19 @@ private function defineConstants(): void
private function loadDependencies(): void
{
// Load CodeStar Framework if available
- $csf_file = $this->dir . 'lib/codestar-framework/codestar-framework.php';
+ $csf_file = $this->dir.'lib/codestar-framework/codestar-framework.php';
if (file_exists($csf_file)) {
require_once $csf_file;
}
// Load settings
- require_once $this->dir . 'src/Config/wp-addon-settings.php';
+ require_once $this->dir.'src/Config/wp-addon-settings.php';
// Initialize services
- $this->optionService = new \WpAddon\Services\OptionService(RW_LANG);
- $this->assetService = new \WpAddon\Services\AssetService(RW_FILE, RW_PLUGIN_URL, RW_LANG, $this->version);
- $this->mediaCleanupService = new \WpAddon\Services\MediaCleanupService();
- $this->imageOptimizationService = new \WpAddon\Services\ImageOptimizationService();
+ $this->optionService = new OptionService(RW_LANG);
+ $this->assetService = new AssetService(RW_FILE, RW_PLUGIN_URL, RW_LANG, $this->version);
+ $this->mediaCleanupService = new MediaCleanupService;
+ $this->imageOptimizationService = new ImageOptimizationService;
// Load functions and modules
$this->loadModules();
@@ -198,31 +175,37 @@ private function loadDependencies(): void
/**
* Load and initialize modules from functions directory
*/
- private function loadModules(): void {
- foreach (glob($this->dir . 'functions/*.php') as $file) {
+ private function loadModules(): void
+ {
+ $initializedModules = [];
+ $moduleDependencies = [
+ 'MediaCleanup' => [$this->mediaCleanupService],
+ 'PageCache' => [$this->optionService],
+ 'AssetMinification' => [$this->optionService],
+ 'LazyLoading' => [$this->optionService, $this->imageOptimizationService],
+ ];
+
+ $files = glob($this->dir.'functions/*.php') ?: [];
+ sort($files, SORT_STRING);
+ foreach ($files as $file) {
require_once $file;
$className = basename($file, '.php');
- if (class_exists($className) && is_subclass_of($className, 'WpAddon\Interfaces\ModuleInterface')) {
- // For complex modules inject dependencies
- if ($className === 'MediaCleanup') {
- $module = new $className($this->mediaCleanupService);
- } elseif ($className === 'PageCache' || $className === 'AssetMinification') {
- $module = new $className($this->optionService);
- } elseif ($className === 'LazyLoading') {
- $module = new $className($this->optionService, $this->imageOptimizationService);
- } else {
- $module = new $className();
- }
+ if (class_exists($className) && is_subclass_of($className, 'WpAddon\Interfaces\ModuleInterface') && ! isset($initializedModules[$className])) {
+ $module = new $className(...($moduleDependencies[$className] ?? []));
$module->init();
+ $initializedModules[$className] = true;
}
}
- foreach (glob($this->dir . 'functions/*/*.php') as $file) {
+ $files = glob($this->dir.'functions/*/*.php') ?: [];
+ sort($files, SORT_STRING);
+ foreach ($files as $file) {
require_once $file;
$className = basename($file, '.php');
- if (class_exists($className) && is_subclass_of($className, 'WpAddon\Interfaces\ModuleInterface')) {
- $module = new $className();
+ if (class_exists($className) && is_subclass_of($className, 'WpAddon\Interfaces\ModuleInterface') && ! isset($initializedModules[$className])) {
+ $module = new $className(...($moduleDependencies[$className] ?? []));
$module->init();
+ $initializedModules[$className] = true;
}
}
}
@@ -241,19 +224,19 @@ private function addHooks(): void
*/
public function loadSeoFunctions(): void
{
- $seo_dir = $this->dir . 'functions/seo/';
+ $seo_dir = $this->dir.'functions/seo/';
if (is_dir($seo_dir)) {
- foreach (glob($seo_dir . '*.php') as $file) {
+ foreach (glob($seo_dir.'*.php') as $file) {
require_once $file;
}
}
-
+
// Also load from functions/posts, functions/terms, etc
$function_subdirs = ['posts', 'terms', 'comments', 'users', 'shortcodes', 'widgets', 'dashboard-widget', 'cf7', 'vc', 'TinyMCE'];
foreach ($function_subdirs as $subdir) {
- $dir = $this->dir . 'functions/' . $subdir . '/';
+ $dir = $this->dir.'functions/'.$subdir.'/';
if (is_dir($dir)) {
- foreach (glob($dir . '*.php') as $file) {
+ foreach (glob($dir.'*.php') as $file) {
require_once $file;
}
}
@@ -267,15 +250,15 @@ public function onPluginsLoaded(): void
{
// Initialize settings
if (class_exists('\WpAddon\WP_Addon_Settings')) {
- \WpAddon\WP_Addon_Settings::getInstance()->add_actions();
+ WP_Addon_Settings::getInstance()->add_actions();
}
// Initialize front-end logic
- $frontWP = new \WpAddon\FrontWP($this->optionService, $this->assetService);
+ $frontWP = new FrontWP($this->optionService, $this->assetService);
$frontWP->add_actions();
// Initialize controller
- $controllerWP = new \WpAddon\ControllerWP($this->optionService);
+ $controllerWP = new ControllerWP($this->optionService);
$controllerWP->options_loader();
}
}
diff --git a/src/FrontWP.php b/src/FrontWP.php
index 2a3cc85..ec1248f 100644
--- a/src/FrontWP.php
+++ b/src/FrontWP.php
@@ -2,25 +2,29 @@
namespace WpAddon;
-use WpAddon\Services\OptionService;
use WpAddon\Services\AssetService;
+use WpAddon\Services\OptionService;
final class FrontWP
{
private OptionService $optionService;
+
private AssetService $assetService;
+
private array $options;
+
private string $file;
+
private string $path;
+
private string $url;
+
private string $name;
+
private string $ver;
/**
* Constructor
- *
- * @param OptionService $optionService
- * @param AssetService $assetService
*/
public function __construct(OptionService $optionService, AssetService $assetService)
{
@@ -47,7 +51,6 @@ public function add_actions()
add_action('wp_footer', [__CLASS__, 'add_wp_footer'], 10, 0);
}
-
public function action_add_meta()
{
if (empty($this->options)) {
@@ -55,15 +58,15 @@ public function action_add_meta()
}
foreach ($this->options as $option => $value) {
if (is_string($option) && $option === 'meta_tags') {
- if (!is_array($value)) {
+ if (! is_array($value)) {
continue;
}
foreach ($value as $val) {
- if (!is_array($val)) {
+ if (! is_array($val)) {
continue;
}
foreach ($val as $item) {
- if (!is_array($item)) {
+ if (! is_array($item)) {
continue;
}
echo $item;
@@ -75,31 +78,30 @@ public function action_add_meta()
public function add_header_js()
{
- if (!empty($this->options['rw_header_js'])) {
+ if (! empty($this->options['rw_header_js'])) {
echo '';
}
}
public function add_header_css()
{
- if (!empty($this->options['rw_header_css'])) {
+ if (! empty($this->options['rw_header_css'])) {
echo '';
}
}
-
public function rw_header_html()
{
- if (!empty($this->options['rw_header_html'])) {
+ if (! empty($this->options['rw_header_html'])) {
echo $this->options['rw_header_html'];
}
}
public function rw_footer_html()
{
- if (!empty($this->options['rw_footer_html'])) {
+ if (! empty($this->options['rw_footer_html'])) {
echo $this->options['rw_footer_html'];
}
}
@@ -109,10 +111,8 @@ public function rw_enqueue_scripts()
$this->assetService->enqueueScripts();
}
-
public static function add_wp_footer()
{
do_action('add_front');
}
-
-}
\ No newline at end of file
+}
diff --git a/src/Interfaces/CacheInterface.php b/src/Interfaces/CacheInterface.php
index 8e20969..c3bb63b 100644
--- a/src/Interfaces/CacheInterface.php
+++ b/src/Interfaces/CacheInterface.php
@@ -5,7 +5,10 @@
interface CacheInterface
{
public function generateCacheKey(string $url): string;
+
public function getCachedContent(string $key): ?string;
+
public function saveCachedContent(string $key, string $content): void;
+
public function clearCache(): void;
}
diff --git a/src/Interfaces/ModuleInterface.php b/src/Interfaces/ModuleInterface.php
index 1974598..d774435 100644
--- a/src/Interfaces/ModuleInterface.php
+++ b/src/Interfaces/ModuleInterface.php
@@ -1,6 +1,8 @@
config = $config;
- $this->cacheDir = rtrim($config['cache_dir'], '/') . '/';
+ $this->cacheDir = rtrim($config['cache_dir'], '/').'/';
$this->ensureCacheDir();
}
private function ensureCacheDir(): void
{
- if (!is_dir($this->cacheDir)) {
+ if (! is_dir($this->cacheDir)) {
mkdir($this->cacheDir, 0755, true);
}
}
@@ -29,7 +30,7 @@ private function ensureCacheDir(): void
*/
public function minifyCss(string $css): string
{
- if (!$this->config['minify_css']) {
+ if (! $this->config['minify_css']) {
return $css;
}
@@ -49,7 +50,7 @@ public function minifyCss(string $css): string
*/
public function minifyJs(string $js): string
{
- if (!$this->config['minify_js']) {
+ if (! $this->config['minify_js']) {
return $js;
}
@@ -67,14 +68,14 @@ public function minifyJs(string $js): string
*/
public function combineCss(array $files): string
{
- if (!$this->config['combine_css']) {
+ if (! $this->config['combine_css']) {
return '';
}
$combined = '';
foreach ($files as $file) {
if (file_exists($file)) {
- $combined .= file_get_contents($file) . "\n";
+ $combined .= file_get_contents($file)."\n";
}
}
@@ -86,14 +87,14 @@ public function combineCss(array $files): string
*/
public function combineJs(array $files): string
{
- if (!$this->config['combine_js']) {
+ if (! $this->config['combine_js']) {
return '';
}
$combined = '';
foreach ($files as $file) {
if (file_exists($file)) {
- $combined .= file_get_contents($file) . ";\n";
+ $combined .= file_get_contents($file).";\n";
}
}
@@ -105,7 +106,7 @@ public function combineJs(array $files): string
*/
public function generateVersion(string $content): string
{
- return substr(md5($content . $this->config['version_salt']), 0, 8);
+ return substr(md5($content.$this->config['version_salt']), 0, 8);
}
/**
@@ -113,8 +114,9 @@ public function generateVersion(string $content): string
*/
public function saveToCache(string $key, string $content): string
{
- $file = $this->cacheDir . $key . '.gz';
+ $file = $this->cacheDir.$key.'.gz';
file_put_contents($file, gzcompress($content, 6));
+
return $key;
}
@@ -123,8 +125,8 @@ public function saveToCache(string $key, string $content): string
*/
public function getFromCache(string $key): ?string
{
- $file = $this->cacheDir . $key . '.gz';
- if (!is_file($file)) {
+ $file = $this->cacheDir.$key.'.gz';
+ if (! is_file($file)) {
return null;
}
@@ -141,7 +143,7 @@ public function getFromCache(string $key): ?string
public function cleanupCache(int $maxAge = 604800, int $maxFiles = 500): void
{
- $files = glob($this->cacheDir . '*.gz') ?: [];
+ $files = glob($this->cacheDir.'*.gz') ?: [];
$now = time();
foreach ($files as $file) {
@@ -151,12 +153,12 @@ public function cleanupCache(int $maxAge = 604800, int $maxFiles = 500): void
}
}
- $files = glob($this->cacheDir . '*.gz') ?: [];
+ $files = glob($this->cacheDir.'*.gz') ?: [];
if (count($files) <= $maxFiles) {
return;
}
- usort($files, static fn(string $left, string $right): int => (filemtime($left) ?: 0) <=> (filemtime($right) ?: 0));
+ usort($files, static fn (string $left, string $right): int => (filemtime($left) ?: 0) <=> (filemtime($right) ?: 0));
foreach (array_slice($files, 0, count($files) - $maxFiles) as $file) {
unlink($file);
}
@@ -167,7 +169,7 @@ public function cleanupCache(int $maxAge = 604800, int $maxFiles = 500): void
*/
public function extractCriticalCss(string $css, array $selectors = []): string
{
- if (!$this->config['critical_css_enabled']) {
+ if (! $this->config['critical_css_enabled']) {
return '';
}
@@ -177,7 +179,7 @@ public function extractCriticalCss(string $css, array $selectors = []): string
foreach ($lines as $line) {
// Simple check for common critical selectors
if (preg_match('/^(body|html|\.site|\.header|\.nav|\.main|\.footer)/i', trim($line))) {
- $critical .= $line . "\n";
+ $critical .= $line."\n";
}
}
diff --git a/src/Services/AssetService.php b/src/Services/AssetService.php
index 6b30e82..3fdb707 100644
--- a/src/Services/AssetService.php
+++ b/src/Services/AssetService.php
@@ -34,11 +34,6 @@ class AssetService
/**
* Constructor
- *
- * @param string $file
- * @param string $url
- * @param string $name
- * @param string $version
*/
public function __construct(string $file, string $url, string $name, string $version)
{
@@ -60,7 +55,7 @@ public function enqueueScripts(): void
wp_enqueue_style(
$this->name,
- $this->url . 'assets/css/min/wp-addon.min.css',
+ $this->url.'assets/css/min/wp-addon.min.css',
[],
$this->version
);
diff --git a/src/Services/CacheService.php b/src/Services/CacheService.php
index 632d7dc..0439ea9 100644
--- a/src/Services/CacheService.php
+++ b/src/Services/CacheService.php
@@ -7,14 +7,15 @@
class CacheService implements CacheInterface
{
private string $cacheDir;
+
private int $ttl;
public function __construct(string $cacheDir = '', int $ttl = 3600)
{
- $this->cacheDir = $cacheDir ?: WP_CONTENT_DIR . '/cache/pages/';
+ $this->cacheDir = $cacheDir ?: WP_CONTENT_DIR.'/cache/pages/';
$this->ttl = $ttl;
- if (!is_dir($this->cacheDir)) {
- mkdir($this->cacheDir, 0755, true);
+ if (! is_dir($this->cacheDir) && ! mkdir($this->cacheDir, 0755, true) && ! is_dir($this->cacheDir)) {
+ throw new \RuntimeException(sprintf('Unable to create cache directory: %s', $this->cacheDir));
}
}
@@ -25,8 +26,8 @@ public function generateCacheKey(string $url): string
public function getCachedContent(string $key): ?string
{
- $file = $this->cacheDir . $key . '.gz';
- if (!is_file($file)) {
+ $file = $this->cacheDir.$key.'.gz';
+ if (! is_file($file)) {
return null;
}
@@ -50,7 +51,7 @@ public function getCachedContent(string $key): ?string
public function cleanup(int $maxEntries, int $maxAge, int $batchSize): void
{
- $files = glob($this->cacheDir . '*.gz') ?: [];
+ $files = glob($this->cacheDir.'*.gz') ?: [];
$now = time();
$removed = 0;
@@ -66,12 +67,12 @@ public function cleanup(int $maxEntries, int $maxAge, int $batchSize): void
}
}
- $files = glob($this->cacheDir . '*.gz') ?: [];
+ $files = glob($this->cacheDir.'*.gz') ?: [];
if (count($files) <= $maxEntries) {
return;
}
- usort($files, static fn(string $left, string $right): int => (filemtime($left) ?: 0) <=> (filemtime($right) ?: 0));
+ usort($files, static fn (string $left, string $right): int => (filemtime($left) ?: 0) <=> (filemtime($right) ?: 0));
$entriesToRemove = min(count($files) - $maxEntries, max(0, $batchSize - $removed));
foreach (array_slice($files, 0, $entriesToRemove) as $file) {
$this->deleteFile($file);
@@ -81,21 +82,33 @@ public function cleanup(int $maxEntries, int $maxAge, int $batchSize): void
private function deleteFile(string $file): void
{
if (is_file($file)) {
- unlink($file);
+ @unlink($file);
}
}
public function saveCachedContent(string $key, string $content): void
{
- $file = $this->cacheDir . $key . '.gz';
- file_put_contents($file, gzcompress($content, 6));
+ $file = $this->cacheDir.$key.'.gz';
+ $compressed = gzcompress($content, 6);
+ if ($compressed === false) {
+ return;
+ }
+
+ $temporaryFile = tempnam($this->cacheDir, $key.'.');
+ if ($temporaryFile === false) {
+ return;
+ }
+
+ if (file_put_contents($temporaryFile, $compressed, LOCK_EX) === false || ! rename($temporaryFile, $file)) {
+ @unlink($temporaryFile);
+ }
}
public function clearCache(): void
{
- $files = glob($this->cacheDir . '*.gz');
+ $files = glob($this->cacheDir.'*.gz') ?: [];
foreach ($files as $file) {
- unlink($file);
+ $this->deleteFile($file);
}
}
}
diff --git a/src/Services/ImageOptimizationService.php b/src/Services/ImageOptimizationService.php
index 5e63b36..254802d 100644
--- a/src/Services/ImageOptimizationService.php
+++ b/src/Services/ImageOptimizationService.php
@@ -10,10 +10,10 @@ class ImageOptimizationService
/**
* Generate blur placeholder for image
*
- * @param string $imagePath Path to the image file
- * @param int $blurIntensity Blur intensity (1-20, default 5)
- * @param int $thumbnailSize Maximum thumbnail size in pixels (default 50)
- * @param int $quality JPEG quality (1-100, default 70)
+ * @param string $imagePath Path to the image file
+ * @param int $blurIntensity Blur intensity (1-20, default 5)
+ * @param int $thumbnailSize Maximum thumbnail size in pixels (default 50)
+ * @param int $quality JPEG quality (1-100, default 70)
* @return string Base64 encoded blur placeholder or empty string on error
*/
public function generateBlurPlaceholder(
@@ -23,8 +23,12 @@ public function generateBlurPlaceholder(
int $quality = 70
): string {
try {
+ if (! $this->isGdAvailable()) {
+ return '';
+ }
+
// Validate input parameters
- if (!file_exists($imagePath) || !is_readable($imagePath)) {
+ if (! file_exists($imagePath) || ! is_readable($imagePath)) {
return '';
}
@@ -34,17 +38,20 @@ public function generateBlurPlaceholder(
// Get image info
$imageInfo = @getimagesize($imagePath);
- if (!$imageInfo) {
+ if (! $imageInfo) {
return '';
}
$originalWidth = $imageInfo[0];
$originalHeight = $imageInfo[1];
+ if ($originalWidth < 1 || $originalHeight < 1) {
+ return '';
+ }
$mimeType = $imageInfo['mime'] ?? '';
// Load image based on type
$sourceImage = $this->loadImage($imagePath, $mimeType);
- if (!$sourceImage) {
+ if (! $sourceImage) {
return '';
}
@@ -53,17 +60,18 @@ public function generateBlurPlaceholder(
if ($aspectRatio > 1) {
// Landscape
$thumbWidth = $thumbnailSize;
- $thumbHeight = (int)($thumbnailSize / $aspectRatio);
+ $thumbHeight = (int) ($thumbnailSize / $aspectRatio);
} else {
// Portrait or square
- $thumbWidth = (int)($thumbnailSize * $aspectRatio);
+ $thumbWidth = (int) ($thumbnailSize * $aspectRatio);
$thumbHeight = $thumbnailSize;
}
// Create thumbnail
$thumbnail = imagecreatetruecolor($thumbWidth, $thumbHeight);
- if (!$thumbnail) {
+ if (! $thumbnail) {
imagedestroy($sourceImage);
+
return '';
}
@@ -76,9 +84,10 @@ public function generateBlurPlaceholder(
}
// Resize image
- if (!imagecopyresampled($thumbnail, $sourceImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $originalWidth, $originalHeight)) {
+ if (! imagecopyresampled($thumbnail, $sourceImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $originalWidth, $originalHeight)) {
imagedestroy($sourceImage);
imagedestroy($thumbnail);
+
return '';
}
@@ -87,19 +96,20 @@ public function generateBlurPlaceholder(
// Apply blur effect
if ($blurIntensity > 1) {
$thumbnail = $this->applyBlur($thumbnail, $blurIntensity);
- if (!$thumbnail) {
+ if (! $thumbnail) {
return '';
}
}
// Convert to base64
- $base64Data = $this->imageToBase64($thumbnail, $quality);
+ $base64Data = $this->imageToBase64($thumbnail, $quality, $mimeType);
imagedestroy($thumbnail);
return $base64Data;
- } catch (\Exception $e) {
- error_log('ImageOptimizationService error: ' . $e->getMessage());
+ } catch (\Throwable $e) {
+ error_log('ImageOptimizationService error: '.$e->getMessage());
+
return '';
}
}
@@ -107,8 +117,6 @@ public function generateBlurPlaceholder(
/**
* Load image from file based on MIME type
*
- * @param string $imagePath
- * @param string $mimeType
* @return resource|\GdImage|null
*/
private function loadImage(string $imagePath, string $mimeType)
@@ -131,18 +139,27 @@ private function loadImage(string $imagePath, string $mimeType)
return null;
}
+ private function isGdAvailable(): bool
+ {
+ return function_exists('imagecreatetruecolor')
+ && function_exists('imagecopyresampled')
+ && function_exists('imagefilter')
+ && function_exists('imagejpeg')
+ && function_exists('imagepng')
+ && function_exists('imagedestroy');
+ }
+
/**
* Apply blur effect to image
*
- * @param resource|\GdImage $image
- * @param int $intensity
+ * @param resource|\GdImage $image
* @return resource|\GdImage|null
*/
private function applyBlur($image, int $intensity)
{
// Simple blur implementation using imagefilter
for ($i = 0; $i < $intensity; $i++) {
- if (!imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR)) {
+ if (! imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR)) {
return null;
}
}
@@ -153,55 +170,61 @@ private function applyBlur($image, int $intensity)
/**
* Convert image to base64 string
*
- * @param resource|\GdImage $image
- * @param int $quality
- * @return string
+ * @param resource|\GdImage $image
*/
- private function imageToBase64($image, int $quality): string
+ private function imageToBase64($image, int $quality, string $mimeType = 'image/jpeg'): string
{
ob_start();
- imagejpeg($image, null, $quality);
+ if ($mimeType === 'image/png') {
+ imagepng($image, null, 8);
+ } else {
+ imagejpeg($image, null, $quality);
+ }
$imageData = ob_get_clean();
- if (!$imageData) {
+ if (! $imageData) {
return '';
}
- return 'data:image/jpeg;base64,' . base64_encode($imageData);
+ return 'data:'.($mimeType === 'image/png' ? 'image/png' : 'image/jpeg').';base64,'.base64_encode($imageData);
}
/**
* Optimize image file (reduce size without quality loss)
*
- * @param string $imagePath
- * @param int $quality JPEG quality (1-100, default 85)
+ * @param int $quality JPEG quality (1-100, default 85)
* @return bool Success
*/
public function optimizeImage(string $imagePath, int $quality = 85): bool
{
try {
- if (!file_exists($imagePath) || !is_writable($imagePath)) {
+ if (! $this->isGdAvailable()) {
+ return false;
+ }
+
+ if (! file_exists($imagePath) || ! is_writable($imagePath)) {
return false;
}
$imageInfo = @getimagesize($imagePath);
- if (!$imageInfo) {
+ if (! $imageInfo) {
return false;
}
$mimeType = $imageInfo['mime'] ?? '';
$sourceImage = $this->loadImage($imagePath, $mimeType);
- if (!$sourceImage) {
+ if (! $sourceImage) {
return false;
}
$quality = max(1, min(100, $quality));
// Create temporary file
- $tempFile = tempnam(sys_get_temp_dir(), 'wp_addon_opt_');
- if (!$tempFile) {
+ $tempFile = tempnam(dirname($imagePath), '.wp_addon_opt_');
+ if (! $tempFile) {
imagedestroy($sourceImage);
+
return false;
}
@@ -227,17 +250,18 @@ public function optimizeImage(string $imagePath, int $quality = 85): bool
if ($success && filesize($tempFile) < filesize($imagePath)) {
// Replace original file if optimized version is smaller
- if (copy($tempFile, $imagePath)) {
- unlink($tempFile);
+ if (rename($tempFile, $imagePath)) {
return true;
}
}
unlink($tempFile);
- return $success;
- } catch (\Exception $e) {
- error_log('ImageOptimizationService optimizeImage error: ' . $e->getMessage());
+ return false;
+
+ } catch (\Throwable $e) {
+ error_log('ImageOptimizationService optimizeImage error: '.$e->getMessage());
+
return false;
}
}
@@ -245,8 +269,7 @@ public function optimizeImage(string $imagePath, int $quality = 85): bool
/**
* Generate responsive image thumbnails
*
- * @param string $imagePath
- * @param array $sizes Array of sizes ['width' => height] or ['width']
+ * @param array $sizes Array of sizes ['width' => height] or ['width']
* @return array Array of generated thumbnail paths
*/
public function generateThumbnails(string $imagePath, array $sizes): array
@@ -254,12 +277,12 @@ public function generateThumbnails(string $imagePath, array $sizes): array
$thumbnails = [];
try {
- if (!file_exists($imagePath)) {
+ if (! file_exists($imagePath)) {
return $thumbnails;
}
$imageInfo = @getimagesize($imagePath);
- if (!$imageInfo) {
+ if (! $imageInfo) {
return $thumbnails;
}
@@ -268,7 +291,7 @@ public function generateThumbnails(string $imagePath, array $sizes): array
$mimeType = $imageInfo['mime'] ?? '';
$sourceImage = $this->loadImage($imagePath, $mimeType);
- if (!$sourceImage) {
+ if (! $sourceImage) {
return $thumbnails;
}
@@ -281,18 +304,18 @@ public function generateThumbnails(string $imagePath, array $sizes): array
$thumbHeight = null;
}
- if (!$thumbWidth) {
+ if (! $thumbWidth) {
continue;
}
// Calculate height maintaining aspect ratio if not specified
- if (!$thumbHeight) {
+ if (! $thumbHeight) {
$aspectRatio = $originalWidth / $originalHeight;
- $thumbHeight = (int)($thumbWidth / $aspectRatio);
+ $thumbHeight = (int) ($thumbWidth / $aspectRatio);
}
$thumbnail = imagecreatetruecolor($thumbWidth, $thumbHeight);
- if (!$thumbnail) {
+ if (! $thumbnail) {
continue;
}
@@ -308,7 +331,7 @@ public function generateThumbnails(string $imagePath, array $sizes): array
if (imagecopyresampled($thumbnail, $sourceImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $originalWidth, $originalHeight)) {
// Generate filename
$pathInfo = pathinfo($imagePath);
- $thumbnailPath = $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '-' . $thumbWidth . 'x' . $thumbHeight . '.' . $pathInfo['extension'];
+ $thumbnailPath = $pathInfo['dirname'].'/'.$pathInfo['filename'].'-'.$thumbWidth.'x'.$thumbHeight.'.'.$pathInfo['extension'];
// Save thumbnail
$saved = false;
@@ -338,7 +361,7 @@ public function generateThumbnails(string $imagePath, array $sizes): array
imagedestroy($sourceImage);
} catch (\Exception $e) {
- error_log('ImageOptimizationService generateThumbnails error: ' . $e->getMessage());
+ error_log('ImageOptimizationService generateThumbnails error: '.$e->getMessage());
}
return $thumbnails;
diff --git a/src/Services/MediaCleanupService.php b/src/Services/MediaCleanupService.php
index 3b4515c..e53609e 100644
--- a/src/Services/MediaCleanupService.php
+++ b/src/Services/MediaCleanupService.php
@@ -2,8 +2,8 @@
namespace WpAddon\Services;
-use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
use RegexIterator;
/**
@@ -13,8 +13,6 @@ class MediaCleanupService
{
/**
* Get registered image sizes (static)
- *
- * @return array
*/
public static function getRegisteredSizesStatic(): array
{
@@ -45,7 +43,7 @@ public static function getRegisteredSizesStatic(): array
}
break;
}
- $registeredSizes[] = $width . 'x' . $height;
+ $registeredSizes[] = $width.'x'.$height;
}
return $registeredSizes;
@@ -53,14 +51,11 @@ public static function getRegisteredSizesStatic(): array
/**
* Check if file should be deleted
- *
- * @param string $basename
- * @return bool
*/
public function isFileToDelete(string $basename): bool
{
if (preg_match('/-(\d+)x(\d+)\.(jpg|jpeg|png|gif)$/i', $basename, $matches)) {
- $sizeKey = $matches[1] . 'x' . $matches[2];
+ $sizeKey = $matches[1].'x'.$matches[2];
// Exclude scaled and other special files
if (strpos($basename, '-scaled') !== false) {
@@ -68,7 +63,8 @@ public function isFileToDelete(string $basename): bool
}
$activeSizes = self::getRegisteredSizesStatic();
- return !in_array($sizeKey, $activeSizes);
+
+ return ! in_array($sizeKey, $activeSizes);
}
return false;
@@ -76,9 +72,6 @@ public function isFileToDelete(string $basename): bool
/**
* Get all image files in directory
- *
- * @param string $directory
- * @return array
*/
public function getAllImageFiles(string $directory): array
{
@@ -98,7 +91,6 @@ public function getAllImageFiles(string $directory): array
/**
* Get files to delete with total size
*
- * @param string $uploadPath
* @return array ['files' => array, 'totalSize' => int]
*/
public function getFilesToDelete(string $uploadPath): array
@@ -118,15 +110,13 @@ public function getFilesToDelete(string $uploadPath): array
return [
'files' => $toDelete,
- 'totalSize' => $totalSize
+ 'totalSize' => $totalSize,
];
}
/**
* Delete files
*
- * @param array $files
- * @param string $uploadPath
* @return array ['deleted' => int, 'errors' => int]
*/
public function deleteFiles(array $files, string $uploadPath = ''): array
@@ -144,7 +134,7 @@ public function deleteFiles(array $files, string $uploadPath = ''): array
return [
'deleted' => $deleted,
- 'errors' => $errors
+ 'errors' => $errors,
];
}
}
diff --git a/src/Services/OptionService.php b/src/Services/OptionService.php
index 94996f8..0ef73ac 100644
--- a/src/Services/OptionService.php
+++ b/src/Services/OptionService.php
@@ -14,8 +14,6 @@ class OptionService
/**
* Constructor
- *
- * @param string $optionKey
*/
public function __construct(string $optionKey = 'wp-addon')
{
@@ -24,8 +22,6 @@ public function __construct(string $optionKey = 'wp-addon')
/**
* Get plugin settings from DB
- *
- * @return array
*/
public function getSettings(): array
{
@@ -34,9 +30,6 @@ public function getSettings(): array
/**
* Update plugin settings
- *
- * @param array $settings
- * @return bool
*/
public function updateSettings(array $settings): bool
{
@@ -46,13 +39,13 @@ public function updateSettings(array $settings): bool
/**
* Get specific setting value
*
- * @param string $key
- * @param mixed $default
+ * @param mixed $default
* @return mixed
*/
public function getSetting(string $key, $default = null)
{
$settings = $this->getSettings();
+
return $settings[$key] ?? $default;
}
}
diff --git a/src/Traits/AjaxTrait.php b/src/Traits/AjaxTrait.php
index c68c5e8..2b84956 100644
--- a/src/Traits/AjaxTrait.php
+++ b/src/Traits/AjaxTrait.php
@@ -1,10 +1,13 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/DatabaseMigrations.php b/tests/DatabaseMigrations.php
index 694a889..4736aac 100644
--- a/tests/DatabaseMigrations.php
+++ b/tests/DatabaseMigrations.php
@@ -14,19 +14,19 @@ protected function runDatabaseMigrations(): void
{
global $db;
- if (!$db) {
+ if (! $db) {
return; // Skip if database not initialized
}
// Clear all tables
- $db->exec("DELETE FROM wp_options");
- $db->exec("DELETE FROM wp_posts");
- $db->exec("DELETE FROM wp_postmeta");
- $db->exec("DELETE FROM wp_users");
- $db->exec("DELETE FROM wp_usermeta");
+ $db->exec('DELETE FROM wp_options');
+ $db->exec('DELETE FROM wp_posts');
+ $db->exec('DELETE FROM wp_postmeta');
+ $db->exec('DELETE FROM wp_users');
+ $db->exec('DELETE FROM wp_usermeta');
// Reset auto-increment counters
- $db->exec("DELETE FROM sqlite_sequence");
+ $db->exec('DELETE FROM sqlite_sequence');
// Insert default WordPress options
$this->seedDefaultOptions();
@@ -48,7 +48,7 @@ private function seedDefaultOptions(): void
{
global $db;
- if (!$db) {
+ if (! $db) {
return; // Skip if database not initialized
}
@@ -62,7 +62,7 @@ private function seedDefaultOptions(): void
['option_name' => 'stylesheet', 'option_value' => 'twentytwentyone'],
];
- $stmt = $db->prepare("INSERT INTO wp_options (option_name, option_value) VALUES (?, ?)");
+ $stmt = $db->prepare('INSERT INTO wp_options (option_name, option_value) VALUES (?, ?)');
foreach ($defaultOptions as $option) {
$stmt->execute([$option['option_name'], $option['option_value']]);
}
@@ -72,7 +72,7 @@ protected function createPost(array $attributes = []): int
{
global $db;
- if (!$db) {
+ if (! $db) {
throw new \Exception('Database not initialized');
}
@@ -103,7 +103,7 @@ protected function createPost(array $attributes = []): int
$data = array_merge($defaults, $attributes);
- $stmt = $db->prepare("
+ $stmt = $db->prepare('
INSERT INTO wp_posts (
post_author, post_date, post_date_gmt, post_content, post_title,
post_excerpt, post_status, comment_status, ping_status, post_password,
@@ -111,9 +111,10 @@ protected function createPost(array $attributes = []): int
post_content_filtered, post_parent, guid, menu_order, post_type,
post_mime_type, comment_count
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- ");
+ ');
$stmt->execute(array_values($data));
+
return $db->lastInsertId();
}
@@ -124,7 +125,7 @@ protected function createUser(array $attributes = []): int
{
global $db;
- if (!$db) {
+ if (! $db) {
throw new \Exception('Database not initialized');
}
@@ -142,14 +143,15 @@ protected function createUser(array $attributes = []): int
$data = array_merge($defaults, $attributes);
- $stmt = $db->prepare("
+ $stmt = $db->prepare('
INSERT INTO wp_users (
user_login, user_pass, user_nicename, user_email, user_url,
user_registered, user_activation_key, user_status, display_name
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
- ");
+ ');
$stmt->execute(array_values($data));
+
return $db->lastInsertId();
}
}
diff --git a/tests/Factories/AssetFactory.php b/tests/Factories/AssetFactory.php
index 4ef992a..7725e7f 100644
--- a/tests/Factories/AssetFactory.php
+++ b/tests/Factories/AssetFactory.php
@@ -10,8 +10,8 @@ class AssetFactory extends Factory
protected function definition(): array
{
return [
- 'handle' => $this->faker->word() . '-asset',
- 'src' => $this->faker->url() . '/assets/' . $this->faker->word() . '.' . $this->faker->randomElement(['css', 'js']),
+ 'handle' => $this->faker->word().'-asset',
+ 'src' => $this->faker->url().'/assets/'.$this->faker->word().'.'.$this->faker->randomElement(['css', 'js']),
'deps' => [],
'ver' => $this->faker->randomFloat(1, 1, 9),
'media' => 'all',
@@ -82,7 +82,7 @@ public function asCss(): self
{
return $this->state([
'type' => 'style',
- 'src' => $this->faker->url() . '/assets/' . $this->faker->word() . '.css',
+ 'src' => $this->faker->url().'/assets/'.$this->faker->word().'.css',
'content' => $this->generateCssContent(),
]);
}
@@ -94,7 +94,7 @@ public function asJs(): self
{
return $this->state([
'type' => 'script',
- 'src' => $this->faker->url() . '/assets/' . $this->faker->word() . '.js',
+ 'src' => $this->faker->url().'/assets/'.$this->faker->word().'.js',
'content' => $this->generateJsContent(),
'media' => null,
]);
@@ -106,11 +106,11 @@ public function asJs(): self
public function minified(): self
{
$content = $this->attributes['content'] ?? $this->generateAssetContent();
- $minifiedContent = str_replace(["\n", "\t", " "], '', $content);
+ $minifiedContent = str_replace(["\n", "\t", ' '], '', $content);
return $this->state([
'content' => $minifiedContent,
- 'src' => str_replace('.css', '.min.css', $this->attributes['src'] ?? $this->faker->url() . '/assets/' . $this->faker->word() . '.css'),
+ 'src' => str_replace('.css', '.min.css', $this->attributes['src'] ?? $this->faker->url().'/assets/'.$this->faker->word().'.css'),
]);
}
@@ -132,7 +132,7 @@ public function small(): self
{
return $this->state([
'size' => $this->faker->numberBetween(100, 999),
- 'content' => $this->faker->word() . '{}',
+ 'content' => $this->faker->word().'{}',
]);
}
@@ -142,6 +142,7 @@ public function small(): self
protected function state(array $state): self
{
$this->attributes = array_merge($this->attributes, $state);
+
return $this;
}
}
diff --git a/tests/Factories/Factory.php b/tests/Factories/Factory.php
index bfca3dc..abfdd43 100644
--- a/tests/Factories/Factory.php
+++ b/tests/Factories/Factory.php
@@ -11,6 +11,7 @@
abstract class Factory
{
protected Generator $faker;
+
protected array $attributes = [];
public function __construct()
@@ -24,6 +25,7 @@ public function __construct()
public function create(array $attributes = []): mixed
{
$data = array_merge($this->definition(), $attributes);
+
return $this->createInstance($data);
}
@@ -36,6 +38,7 @@ public function createMany(int $count, array $attributes = []): array
for ($i = 0; $i < $count; $i++) {
$instances[] = $this->create($attributes);
}
+
return $instances;
}
diff --git a/tests/Factories/PostFactory.php b/tests/Factories/PostFactory.php
index db7ecca..043b011 100644
--- a/tests/Factories/PostFactory.php
+++ b/tests/Factories/PostFactory.php
@@ -39,7 +39,7 @@ protected function createInstance(array $data): int
{
global $db;
- $stmt = $db->prepare("
+ $stmt = $db->prepare('
INSERT INTO wp_posts (
post_author, post_date, post_date_gmt, post_content, post_title,
post_excerpt, post_status, comment_status, ping_status, post_password,
@@ -47,9 +47,10 @@ protected function createInstance(array $data): int
post_content_filtered, post_parent, guid, menu_order, post_type,
post_mime_type, comment_count
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- ");
+ ');
$stmt->execute(array_values($data));
+
return $db->lastInsertId();
}
@@ -83,6 +84,7 @@ public function withAuthor(int $authorId): self
protected function state(array $state): self
{
$this->attributes = array_merge($this->attributes, $state);
+
return $this;
}
}
diff --git a/tests/Feature/AssetMinificationIntegrationTest.php b/tests/Feature/AssetMinificationIntegrationTest.php
index ead932f..2fb0bb7 100644
--- a/tests/Feature/AssetMinificationIntegrationTest.php
+++ b/tests/Feature/AssetMinificationIntegrationTest.php
@@ -2,27 +2,30 @@
use Brain\Monkey;
use Brain\Monkey\Functions;
+use WpAddon\Services\AssetOptimizationService;
+use WpAddon\Services\OptionService;
/**
* Integration test for AssetMinification module
*/
describe('AssetMinification Integration', function () {
// Пропустить тесты, если WordPress не загружен (integration среда)
- if (!function_exists('wp_die')) {
+ if (! function_exists('wp_die')) {
test('skipped - requires WordPress environment', function () {})->skip('WordPress environment not available');
+
return;
}
beforeEach(function () {
Monkey\setUp();
- $this->cacheDir = sys_get_temp_dir() . '/wp_addon_integration_cache_' . uniqid();
+ $this->cacheDir = sys_get_temp_dir().'/wp_addon_integration_cache_'.uniqid();
mkdir($this->cacheDir, 0755, true);
- $this->mockOptionService = \Mockery::mock('\WpAddon\Services\OptionService');
+ $this->mockOptionService = Mockery::mock('\WpAddon\Services\OptionService');
// Mock option service to return enabled config
$this->mockOptionService->shouldReceive('getSetting')
- ->andReturnUsing(function($key, $default = null) {
+ ->andReturnUsing(function ($key, $default = null) {
$config = [
'enabled' => true,
'minify_css' => true,
@@ -36,6 +39,7 @@
'cache_dir' => $this->cacheDir,
'version_salt' => 'wp-addon-v1',
];
+
return $config[$key] ?? $default;
});
@@ -46,7 +50,7 @@
afterEach(function () {
// Clean up cache directory
if (is_dir($this->cacheDir)) {
- $files = glob($this->cacheDir . '/*');
+ $files = glob($this->cacheDir.'/*');
foreach ($files as $file) {
unlink($file);
}
@@ -54,7 +58,7 @@
}
Monkey\tearDown();
- \Mockery::close();
+ Mockery::close();
});
it('processes CSS assets', function () {
@@ -69,11 +73,11 @@
'src' => 'http://localhost/wp-content/plugins/plugin/style.css',
'deps' => [],
'ver' => '1.0.0',
- ]
+ ],
];
global $wp_styles;
- $wp_styles = new \stdClass();
+ $wp_styles = new stdClass;
$wp_styles->queue = array_keys($cssFiles);
$wp_styles->registered = [];
@@ -88,19 +92,20 @@
}
// Create temporary CSS files
- $tempCss1 = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.css';
+ $tempCss1 = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.css';
file_put_contents($tempCss1, 'body { color: red; }');
- $tempCss2 = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.css';
+ $tempCss2 = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.css';
file_put_contents($tempCss2, '.small { margin: 0; }');
// Mock file paths
Functions\when('file_exists')->justReturn(true);
Functions\when('filesize')->justReturn(2048);
Functions\when('file_get_contents')
- ->alias(function($path) use ($tempCss1, $tempCss2) {
+ ->alias(function ($path) use ($tempCss1, $tempCss2) {
if (str_contains($path, 'theme-style') || str_contains($path, 'style.css')) {
return file_get_contents($tempCss1);
}
+
return file_get_contents($tempCss2);
});
@@ -137,7 +142,7 @@
'src' => 'http://example.com/wp-content/plugins/plugin/script.js',
'deps' => [],
'ver' => '1.0.0',
- ]
+ ],
];
$this->mockWpScripts($jsFiles);
@@ -150,10 +155,11 @@
\Brain\Monkey\Functions\when('file_exists')->return(true);
\Brain\Monkey\Functions\when('filesize')->justReturn(2048);
\Brain\Monkey\Functions\when('file_get_contents')
- ->alias(function($path) use ($tempJs1, $tempJs2) {
+ ->alias(function ($path) use ($tempJs1, $tempJs2) {
if (str_contains($path, 'theme-script') || str_contains($path, 'script.js')) {
return file_get_contents($tempJs1);
}
+
return file_get_contents($tempJs2);
});
@@ -191,7 +197,7 @@
'src' => 'http://example.com/wp-includes/css/admin-bar.css',
'deps' => [],
'ver' => '1.0.0',
- ]
+ ],
];
$this->mockWpStyles($systemAssets);
@@ -227,7 +233,7 @@
'src' => 'http://example.com/wp-content/themes/theme/minified.css',
'deps' => [],
'ver' => '1.0.0',
- ]
+ ],
];
$this->mockWpStyles($cssFiles);
@@ -254,7 +260,7 @@
'src' => 'http://example.com/wp-content/themes/theme/small.css',
'deps' => [],
'ver' => '1.0.0',
- ]
+ ],
];
$this->mockWpStyles($cssFiles);
@@ -313,7 +319,7 @@
// Mock wp_add_inline_script to capture the added script
$addedScripts = [];
\Brain\Monkey\Functions\when('wp_add_inline_script')
- ->alias(function($handle, $data) use (&$addedScripts) {
+ ->alias(function ($handle, $data) use (&$addedScripts) {
$addedScripts[$handle] = $data;
});
@@ -328,8 +334,8 @@
it('clears cache files', function () {
// Create test cache files
- $testFile1 = $this->cacheDir . '/test1.gz';
- $testFile2 = $this->cacheDir . '/test2.gz';
+ $testFile1 = $this->cacheDir.'/test1.gz';
+ $testFile2 = $this->cacheDir.'/test2.gz';
file_put_contents($testFile1, 'test content 1');
file_put_contents($testFile2, 'test content 2');
@@ -348,14 +354,15 @@
it('does not register hooks when disabled', function () {
// Mock disabled config
- $this->mockOptionService = $this->createMock(\WpAddon\Services\OptionService::class);
+ $this->mockOptionService = $this->createMock(OptionService::class);
$this->mockOptionService->method('getSetting')
- ->willReturnCallback(function($key, $default = null) {
+ ->willReturnCallback(function ($key, $default = null) {
$config = [
'enabled' => false, // Disabled
'minify_css' => true,
'minify_js' => true,
];
+
return $config[$key] ?? $default;
});
@@ -364,7 +371,7 @@
// Mock add_action to capture registered actions
$registeredActions = [];
\Brain\Monkey\Functions\when('add_action')
- ->alias(function($hook, $callback) use (&$registeredActions) {
+ ->alias(function ($hook, $callback) use (&$registeredActions) {
$registeredActions[] = $hook;
});
@@ -379,7 +386,7 @@
// Mock add_action to capture registered actions
$registeredActions = [];
\Brain\Monkey\Functions\when('add_action')
- ->alias(function($hook, $callback) use (&$registeredActions) {
+ ->alias(function ($hook, $callback) use (&$registeredActions) {
$registeredActions[] = $hook;
});
@@ -423,7 +430,7 @@
it('checks real cache directory', function () {
// Проверяем директорию кэша в реальной среде
if (defined('WP_CONTENT_DIR')) {
- $cacheDir = WP_CONTENT_DIR . '/cache/assets/';
+ $cacheDir = WP_CONTENT_DIR.'/cache/assets/';
expect(is_dir($cacheDir))->toBeTrue();
expect(is_writable($cacheDir))->toBeTrue();
} else {
@@ -441,7 +448,7 @@
$criticalKeys = [
'asset_minification_enabled',
'asset_minify_css',
- 'asset_minify_js'
+ 'asset_minify_js',
];
foreach ($criticalKeys as $key) {
@@ -493,7 +500,7 @@
$this->assetMinification->processAssets();
// Проверяем что очередь изменилась или остались оригинальные стили
- expect(!empty($wp_styles->queue) || $wp_styles->queue === $originalQueue)->toBeTrue();
+ expect(! empty($wp_styles->queue) || $wp_styles->queue === $originalQueue)->toBeTrue();
} else {
skip('WordPress styles not available');
}
@@ -502,7 +509,7 @@
it('checks real critical CSS injection', function () {
// Проверяем инъекцию критического CSS
if (function_exists('get_template_directory')) {
- $themeCss = get_template_directory() . '/style.css';
+ $themeCss = get_template_directory().'/style.css';
if (file_exists($themeCss)) {
ob_start();
@@ -527,7 +534,7 @@
// Пробуем получить главную страницу
$response = wp_remote_get($homeUrl, ['timeout' => 5]);
- if (!is_wp_error($response)) {
+ if (! is_wp_error($response)) {
$html = wp_remote_retrieve_body($response);
// Проверяем наличие признаков оптимизации
@@ -554,8 +561,8 @@
it('checks real file system operations', function () {
// Проверяем файловые операции в реальной среде
- $service = new \WpAddon\Services\AssetOptimizationService([
- 'cache_dir' => sys_get_temp_dir() . '/test_real_cache/',
+ $service = new AssetOptimizationService([
+ 'cache_dir' => sys_get_temp_dir().'/test_real_cache/',
'version_salt' => 'real_test',
'minify_css' => true,
'minify_js' => true,
@@ -563,11 +570,11 @@
'combine_js' => true,
'critical_css_enabled' => true,
'exclude_css' => [],
- 'exclude_js' => []
+ 'exclude_js' => [],
]);
$testContent = 'body { color: red; }';
- $cacheKey = 'real_test_' . time();
+ $cacheKey = 'real_test_'.time();
// Тест сохранения
$service->saveToCache($cacheKey, $testContent);
@@ -577,7 +584,7 @@
expect($cached)->toBe($testContent);
// Очистка
- $cacheFile = sys_get_temp_dir() . '/test_real_cache/' . $cacheKey . '.gz';
+ $cacheFile = sys_get_temp_dir().'/test_real_cache/'.$cacheKey.'.gz';
if (file_exists($cacheFile)) {
unlink($cacheFile);
}
diff --git a/tests/Feature/AssetMinificationRealWorldTest.php b/tests/Feature/AssetMinificationRealWorldTest.php
index 1253a9d..d551603 100644
--- a/tests/Feature/AssetMinificationRealWorldTest.php
+++ b/tests/Feature/AssetMinificationRealWorldTest.php
@@ -2,11 +2,14 @@
use Brain\Monkey;
use Brain\Monkey\Functions;
+use WpAddon\Services\AssetOptimizationService;
+use WpAddon\Services\OptionService;
describe('AssetMinification Real World Integration', function () {
// Пропустить тесты, если WordPress не загружен (integration среда)
- if (!function_exists('wp_die')) {
+ if (! function_exists('wp_die')) {
test('skipped - requires WordPress environment', function () {})->skip('WordPress environment not available');
+
return;
}
beforeEach(function () {
@@ -22,10 +25,18 @@
'wp_dequeue_script' => null,
'wp_add_inline_script' => null,
'add_action' => null,
- 'site_url' => function() { return 'http://localhost'; },
- 'content_url' => function() { return 'http://localhost/wp-content'; },
- 'plugin_dir_path' => function() { return '/var/www/no-borders.ru/wp-content/plugins/wp-addon-plugin/'; },
- 'get_template_directory' => function() { return '/var/www/no-borders.ru/wp-content/themes/yootheme_child'; },
+ 'site_url' => function () {
+ return 'http://localhost';
+ },
+ 'content_url' => function () {
+ return 'http://localhost/wp-content';
+ },
+ 'plugin_dir_path' => function () {
+ return '/var/www/no-borders.ru/wp-content/plugins/wp-addon-plugin/';
+ },
+ 'get_template_directory' => function () {
+ return '/var/www/no-borders.ru/wp-content/themes/yootheme_child';
+ },
]);
});
@@ -53,11 +64,11 @@
it('loads asset minification config', function () {
// Чекпоинт 4: Конфиг загружается
- $optionService = new \WpAddon\Services\OptionService();
+ $optionService = new OptionService;
$assetMinification = new AssetMinification($optionService);
Functions\stubs([
- 'get_option' => function($key) {
+ 'get_option' => function ($key) {
return ['wp-addon' => [
'asset_minification_enabled' => true,
'asset_minify_css' => true,
@@ -67,14 +78,14 @@
'asset_critical_css_enabled' => true,
'asset_defer_non_critical_css' => true,
'asset_exclude_css' => 'admin-bar,dashicons',
- 'asset_exclude_js' => 'jquery,jquery-core'
+ 'asset_exclude_js' => 'jquery,jquery-core',
]];
- }
+ },
]);
$assetMinification->init();
- $reflection = new \ReflectionClass($assetMinification);
+ $reflection = new ReflectionClass($assetMinification);
$configProperty = $reflection->getProperty('config');
$configProperty->setAccessible(true);
$config = $configProperty->getValue($assetMinification);
@@ -86,7 +97,7 @@
it('creates cache directory', function () {
// Чекпоинт 5: Директория кэша существует
- $cacheDir = WP_CONTENT_DIR . '/cache/assets/';
+ $cacheDir = WP_CONTENT_DIR.'/cache/assets/';
expect(is_dir($cacheDir))->toBeTrue();
expect(is_writable($cacheDir))->toBeTrue();
});
@@ -94,7 +105,7 @@
it('works with asset optimization service', function () {
// Чекпоинт 6: Сервис оптимизации работает
$config = [
- 'cache_dir' => WP_CONTENT_DIR . '/cache/assets/',
+ 'cache_dir' => WP_CONTENT_DIR.'/cache/assets/',
'version_salt' => 'test',
'minify_css' => true,
'minify_js' => true,
@@ -102,10 +113,10 @@
'combine_js' => true,
'critical_css_enabled' => true,
'exclude_css' => [],
- 'exclude_js' => []
+ 'exclude_js' => [],
];
- $service = new \WpAddon\Services\AssetOptimizationService($config);
+ $service = new AssetOptimizationService($config);
expect($service)->toBeInstanceOf('WpAddon\\Services\\AssetOptimizationService');
// Тест минификации CSS
@@ -129,7 +140,7 @@
it('creates cache file for CSS minification', function () {
// Чекпоинт 7: Минификация CSS создает файл кэша
$config = [
- 'cache_dir' => WP_CONTENT_DIR . '/cache/assets/',
+ 'cache_dir' => WP_CONTENT_DIR.'/cache/assets/',
'version_salt' => 'test',
'minify_css' => true,
'minify_js' => true,
@@ -137,16 +148,16 @@
'combine_js' => true,
'critical_css_enabled' => true,
'exclude_css' => [],
- 'exclude_js' => []
+ 'exclude_js' => [],
];
- $service = new \WpAddon\Services\AssetOptimizationService($config);
+ $service = new AssetOptimizationService($config);
$css = '.test { color: red; font-size: 14px; }';
$version = $service->generateVersion($css);
- $cacheKey = 'test-css-' . $version;
+ $cacheKey = 'test-css-'.$version;
$service->saveToCache($cacheKey, $css);
- $cacheFile = $config['cache_dir'] . $cacheKey . '.gz';
+ $cacheFile = $config['cache_dir'].$cacheKey.'.gz';
expect(file_exists($cacheFile))->toBeTrue();
// Проверить содержимое
@@ -160,7 +171,7 @@
it('creates cache file for JS minification', function () {
// Чекпоинт 8: Минификация JS создает файл кэша
$config = [
- 'cache_dir' => WP_CONTENT_DIR . '/cache/assets/',
+ 'cache_dir' => WP_CONTENT_DIR.'/cache/assets/',
'version_salt' => 'test',
'minify_css' => true,
'minify_js' => true,
@@ -168,16 +179,16 @@
'combine_js' => true,
'critical_css_enabled' => true,
'exclude_css' => [],
- 'exclude_js' => []
+ 'exclude_js' => [],
];
- $service = new \WpAddon\Services\AssetOptimizationService($config);
+ $service = new AssetOptimizationService($config);
$js = 'function test() { return true; }';
$version = $service->generateVersion($js);
- $cacheKey = 'test-js-' . $version;
+ $cacheKey = 'test-js-'.$version;
$service->saveToCache($cacheKey, $js);
- $cacheFile = $config['cache_dir'] . $cacheKey . '.gz';
+ $cacheFile = $config['cache_dir'].$cacheKey.'.gz';
expect(file_exists($cacheFile))->toBeTrue();
$cachedContent = $service->getFromCache($cacheKey);
expect($cachedContent)->toBe($js);
@@ -186,13 +197,13 @@
it('extracts critical CSS', function () {
// Чекпоинт 9: Извлечение critical CSS работает
- $optionService = new \WpAddon\Services\OptionService();
+ $optionService = new OptionService;
$assetMinification = new AssetMinification($optionService);
Functions\stubs([
- 'get_option' => function($key) {
+ 'get_option' => function ($key) {
return ['wp-addon' => ['asset_critical_css_enabled' => true]];
- }
+ },
]);
$assetMinification->init();
@@ -207,7 +218,7 @@
it('registers asset processing hooks', function () {
// Чекпоинт 10: Хуки зарегистрированы
- $optionService = new \WpAddon\Services\OptionService();
+ $optionService = new OptionService;
$assetMinification = new AssetMinification($optionService);
$assetMinification->init();
@@ -222,7 +233,7 @@
if (function_exists('wp_remote_get')) {
$response = wp_remote_get($url);
- if (!is_wp_error($response) && $response['response']['code'] === 200) {
+ if (! is_wp_error($response) && $response['response']['code'] === 200) {
$html = wp_remote_retrieve_body($response);
$hasCriticalCss = strpos($html, 'wp-addon-critical-css') !== false;
diff --git a/tests/Feature/LazyLoadingIntegrationTest.php b/tests/Feature/LazyLoadingIntegrationTest.php
index 5849838..ea54cf5 100644
--- a/tests/Feature/LazyLoadingIntegrationTest.php
+++ b/tests/Feature/LazyLoadingIntegrationTest.php
@@ -5,8 +5,9 @@
*/
describe('LazyLoading Integration', function () {
// Пропустить тесты, если WordPress не загружен
- if (!function_exists('wp_die')) {
+ if (! function_exists('wp_die')) {
test('skipped - requires WordPress environment', function () {})->skip('WordPress environment not available');
+
return;
}
@@ -14,11 +15,11 @@
// Убираем Brain Monkey, чтобы избежать конфликтов с Patchwork
// Monkey\setUp();
- $this->mockOptionService = \Mockery::mock('\WpAddon\Services\OptionService');
+ $this->mockOptionService = Mockery::mock('\WpAddon\Services\OptionService');
// Mock option service для настроек
$this->mockOptionService->shouldReceive('getSetting')
- ->andReturnUsing(function($key, $default = null) {
+ ->andReturnUsing(function ($key, $default = null) {
$config = [
'enable_lazy_loading' => true,
'lazy_types' => ['img'],
@@ -27,13 +28,14 @@
'threshold' => 0.1,
'enable_fallback' => true,
];
+
return $config[$key] ?? $default;
});
});
afterEach(function () {
// Monkey\tearDown();
- \Mockery::close();
+ Mockery::close();
});
it('activates module without errors', function () {
@@ -44,7 +46,7 @@
expect($lazyLoading)->toBeInstanceOf('\WpAddon\Interfaces\ModuleInterface');
// Инициализация не должна вызывать ошибки
- expect(function() use ($lazyLoading) {
+ expect(function () use ($lazyLoading) {
$lazyLoading->init();
})->not->toThrow(Exception::class);
});
@@ -104,7 +106,7 @@
// Измеряем время выполнения
$startTime = microtime(true);
- $content = str_repeat('
', 5);
+ $content = str_repeat('
', 5);
$lazyLoading = new LazyLoading($this->mockOptionService);
$lazyLoading->init();
@@ -125,7 +127,7 @@
$lazyLoading->init();
// Обработка не должна вызывать исключения
- expect(function() use ($lazyLoading, $contentWithErrors) {
+ expect(function () use ($lazyLoading, $contentWithErrors) {
$lazyLoading->processContent($contentWithErrors);
})->not->toThrow(Exception::class);
});
diff --git a/tests/Feature/SmokeTest.php b/tests/Feature/SmokeTest.php
index 3bedc65..db23ac2 100644
--- a/tests/Feature/SmokeTest.php
+++ b/tests/Feature/SmokeTest.php
@@ -1,5 +1,8 @@
toBeInstanceOf(\WpAddon\Services\OptionService::class);
+ $optionService = new OptionService;
+ expect($optionService)->toBeInstanceOf(OptionService::class);
- $mediaCleanupService = new \WpAddon\Services\MediaCleanupService();
- expect($mediaCleanupService)->toBeInstanceOf(\WpAddon\Services\MediaCleanupService::class);
+ $mediaCleanupService = new MediaCleanupService;
+ expect($mediaCleanupService)->toBeInstanceOf(MediaCleanupService::class);
});
});
diff --git a/tests/Pest.php b/tests/Pest.php
index 8396017..f1fab3e 100644
--- a/tests/Pest.php
+++ b/tests/Pest.php
@@ -1,5 +1,7 @@
in('Unit', 'Feature');
+uses(TestCase::class)->in('Unit', 'Feature');
/*
|--------------------------------------------------------------------------
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 8f4d521..d2746c5 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -3,6 +3,7 @@
namespace WpAddon\Tests;
use PHPUnit\Framework\TestCase as BaseTestCase;
+use WpAddon\Services\AssetOptimizationService;
/**
* Base test case for WP Addon Plugin tests with database support
@@ -44,8 +45,9 @@ protected function tearDown(): void
*/
protected function getTestDataPath(string $filename = ''): string
{
- $path = __DIR__ . '/data';
- return $filename ? $path . '/' . $filename : $path;
+ $path = __DIR__.'/data';
+
+ return $filename ? $path.'/'.$filename : $path;
}
/**
@@ -53,8 +55,9 @@ protected function getTestDataPath(string $filename = ''): string
*/
protected function createTempFile(string $content, string $extension = 'css'): string
{
- $filename = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.' . $extension;
+ $filename = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.'.$extension;
file_put_contents($filename, $content);
+
return $filename;
}
@@ -74,7 +77,7 @@ protected function removeTempFile(string $filename): void
protected function mockWpStyles(array $styles): void
{
global $wp_styles;
- $wp_styles = new \stdClass();
+ $wp_styles = new \stdClass;
$wp_styles->queue = array_keys($styles);
$wp_styles->registered = [];
@@ -95,7 +98,7 @@ protected function mockWpStyles(array $styles): void
protected function mockWpScripts(array $scripts): void
{
global $wp_scripts;
- $wp_scripts = new \stdClass();
+ $wp_scripts = new \stdClass;
$wp_scripts->queue = array_keys($scripts);
$wp_scripts->registered = [];
@@ -113,30 +116,30 @@ protected function mockWpScripts(array $scripts): void
/**
* Get mock asset optimization service
*/
- protected function getMockAssetOptimizationService(): \WpAddon\Services\AssetOptimizationService
+ protected function getMockAssetOptimizationService(): AssetOptimizationService
{
- $mock = $this->getMockBuilder(\WpAddon\Services\AssetOptimizationService::class)
+ $mock = $this->getMockBuilder(AssetOptimizationService::class)
->disableOriginalConstructor()
->getMock();
// Default behaviors
- $mock->method('minifyCss')->willReturnCallback(function($css) {
+ $mock->method('minifyCss')->willReturnCallback(function ($css) {
return str_replace([' ', "\n", "\t"], '', $css);
});
- $mock->method('minifyJs')->willReturnCallback(function($js) {
+ $mock->method('minifyJs')->willReturnCallback(function ($js) {
return str_replace([' ', "\n", "\t"], '', $js);
});
- $mock->method('combineCss')->willReturnCallback(function($files) {
+ $mock->method('combineCss')->willReturnCallback(function ($files) {
return implode("\n", array_map('file_get_contents', $files));
});
- $mock->method('combineJs')->willReturnCallback(function($files) {
+ $mock->method('combineJs')->willReturnCallback(function ($files) {
return implode(";\n", array_map('file_get_contents', $files));
});
- $mock->method('generateVersion')->willReturnCallback(function($content) {
+ $mock->method('generateVersion')->willReturnCallback(function ($content) {
return md5($content);
});
@@ -160,6 +163,7 @@ protected function callPrivateMethod($object, string $methodName, array $args =
$reflection = new \ReflectionClass($object);
$method = $reflection->getMethod($methodName);
$method->setAccessible(true);
+
return $method->invokeArgs($object, $args);
}
}
diff --git a/tests/Unit/AssetMinificationEdgeCasesTest.php b/tests/Unit/AssetMinificationEdgeCasesTest.php
index 6effcd9..4cb74a6 100644
--- a/tests/Unit/AssetMinificationEdgeCasesTest.php
+++ b/tests/Unit/AssetMinificationEdgeCasesTest.php
@@ -2,23 +2,25 @@
/**
* Test AssetMinification edge cases and error handling
+ *
* @group problematic
*/
describe('AssetMinification Edge Cases', function () {
// Пропускаем эти тесты в CI из-за Patchwork конфликтов
if (getenv('CI') === 'true' || getenv('GITHUB_ACTIONS') === 'true') {
test('skipped in CI', function () {})->skip('Patchwork conflicts in CI');
+
return;
}
beforeEach(function () {
global $mock_functions;
$mock_functions = [];
- $this->mockOptionService = \Mockery::mock('\WpAddon\Services\OptionService');
+ $this->mockOptionService = Mockery::mock('\WpAddon\Services\OptionService');
// Mock option service with default config
$this->mockOptionService->shouldReceive('getSetting')
- ->andReturnUsing(function($key, $default = null) {
+ ->andReturnUsing(function ($key, $default = null) {
$config = [
'enabled' => true,
'minify_css' => true,
@@ -29,9 +31,10 @@
'defer_non_critical_css' => true,
'exclude_css' => [],
'exclude_js' => [],
- 'cache_dir' => sys_get_temp_dir() . '/wp_addon_cache',
+ 'cache_dir' => sys_get_temp_dir().'/wp_addon_cache',
'version_salt' => 'wp-addon-v1',
];
+
return $config[$key] ?? $default;
});
@@ -40,15 +43,15 @@
});
afterEach(function () {
- \Mockery::close();
+ Mockery::close();
});
it('processes assets with empty queue', function () {
// Setup: Empty queues
global $wp_styles, $wp_scripts;
- $wp_styles = new \stdClass();
+ $wp_styles = new stdClass;
$wp_styles->queue = [];
- $wp_scripts = new \stdClass();
+ $wp_scripts = new stdClass;
$wp_scripts->queue = [];
// Execute - should not throw any errors
@@ -86,7 +89,7 @@
});
it('does not process assets with empty src', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, ['test-handle', '', []]);
@@ -94,7 +97,7 @@
});
it('does not process assets with null src', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, ['test-handle', '', []]);
@@ -105,20 +108,20 @@
global $mock_functions;
$mock_functions['file_exists'] = false;
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, [
'test-handle',
'http://example.com/wp-content/themes/theme/invalid.css',
- []
+ [],
]);
expect($result)->toBeFalse();
});
it('handles malformed CSS gracefully', function () {
$malformedCss = '.class { color: #fff; font-size: 14px; /* unclosed comment ';
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('isAlreadyMinified');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, [$malformedCss, 'css']);
@@ -129,7 +132,7 @@
it('handles malformed JS gracefully', function () {
$malformedJs = 'function test() { console.log("test"); /* unclosed comment ';
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('isAlreadyMinified');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, [$malformedJs, 'js']);
@@ -139,7 +142,7 @@
});
it('returns empty string for empty URL', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('urlToPath');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, ['']);
@@ -148,7 +151,7 @@
it('handles non-matching URL', function () {
$url = 'https://cdn.example.com/style.css';
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('urlToPath');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, [$url]);
@@ -159,7 +162,7 @@
});
it('generates cache URL with empty key', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('getCacheUrl');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, ['']);
@@ -169,7 +172,7 @@
it('handles special characters in cache key', function () {
$key = 'test@key#with$special%chars';
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('getCacheUrl');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, [$key]);
@@ -193,7 +196,7 @@
it('handles empty theme CSS file', function () {
// Create empty theme CSS file
- $emptyCssFile = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.css';
+ $emptyCssFile = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.css';
file_put_contents($emptyCssFile, '');
$themeDir = dirname($emptyCssFile);
@@ -215,7 +218,7 @@
it('handles corrupt theme CSS file', function () {
// Create corrupt CSS file
$corruptCss = 'this is not css {{{ }}} }}}';
- $corruptCssFile = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.css';
+ $corruptCssFile = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.css';
file_put_contents($corruptCssFile, $corruptCss);
$themeDir = dirname($corruptCssFile);
@@ -249,11 +252,11 @@
it('handles clearing cache with non-existent directory', function () {
// Mock cache directory that doesn't exist
- $nonExistentDir = '/tmp/non_existent_wp_addon_cache_' . uniqid();
+ $nonExistentDir = '/tmp/non_existent_wp_addon_cache_'.uniqid();
- $mockOptionService = \Mockery::mock('\WpAddon\Services\OptionService');
+ $mockOptionService = Mockery::mock('\WpAddon\Services\OptionService');
$mockOptionService->shouldReceive('getSetting')
- ->andReturnUsing(function($key) use ($nonExistentDir) {
+ ->andReturnUsing(function ($key) use ($nonExistentDir) {
return $key === 'cache_dir' ? $nonExistentDir : true;
});
@@ -269,12 +272,12 @@
it('handles clearing cache with permission denied', function () {
// Create cache directory and make it read-only
- $cacheDir = sys_get_temp_dir() . '/wp_addon_readonly_cache_' . uniqid();
+ $cacheDir = sys_get_temp_dir().'/wp_addon_readonly_cache_'.uniqid();
mkdir($cacheDir, 0444, true); // Read-only
- $mockOptionService = \Mockery::mock('\WpAddon\Services\OptionService');
+ $mockOptionService = Mockery::mock('\WpAddon\Services\OptionService');
$mockOptionService->shouldReceive('getSetting')
- ->andReturnUsing(function($key) use ($cacheDir) {
+ ->andReturnUsing(function ($key) use ($cacheDir) {
return $key === 'cache_dir' ? $cacheDir : true;
});
@@ -298,7 +301,7 @@
// Setup some assets
global $wp_styles, $wp_scripts;
- $wp_styles = new \stdClass();
+ $wp_styles = new stdClass;
$wp_styles->queue = ['test-style'];
$wp_styles->registered = [
'test-style' => (object) [
@@ -306,10 +309,10 @@
'src' => 'http://example.com/style.css',
'deps' => [],
'ver' => false,
- 'args' => 'all'
- ]
+ 'args' => 'all',
+ ],
];
- $wp_scripts = new \stdClass();
+ $wp_scripts = new stdClass;
$wp_scripts->queue = ['test-script'];
$wp_scripts->registered = [
'test-script' => (object) [
@@ -317,8 +320,8 @@
'src' => 'http://example.com/script.js',
'deps' => [],
'ver' => false,
- 'args' => false
- ]
+ 'args' => false,
+ ],
];
// Execute
@@ -335,7 +338,7 @@
// Setup some assets
global $wp_styles, $wp_scripts;
- $wp_styles = new \stdClass();
+ $wp_styles = new stdClass;
$wp_styles->queue = ['test-style'];
$wp_styles->registered = [
'test-style' => (object) [
@@ -343,10 +346,10 @@
'src' => 'http://example.com/style.css',
'deps' => [],
'ver' => false,
- 'args' => 'all'
- ]
+ 'args' => 'all',
+ ],
];
- $wp_scripts = new \stdClass();
+ $wp_scripts = new stdClass;
$wp_scripts->queue = ['test-script'];
$wp_scripts->registered = [
'test-script' => (object) [
@@ -354,8 +357,8 @@
'src' => 'http://example.com/script.js',
'deps' => [],
'ver' => false,
- 'args' => false
- ]
+ 'args' => false,
+ ],
];
// Execute
@@ -367,7 +370,7 @@
});
it('returns normal priority for unknown asset', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('getAssetPriority');
$method->setAccessible(true);
$priority = $method->invokeArgs($this->assetMinification, ['unknown-asset-handle']);
@@ -375,7 +378,7 @@
});
it('returns normal priority for empty handle', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('getAssetPriority');
$method->setAccessible(true);
$priority = $method->invokeArgs($this->assetMinification, ['']);
@@ -383,7 +386,7 @@
});
it('does not consider empty handle as system asset', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('isSystemAsset');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, ['']);
@@ -391,7 +394,7 @@
});
it('does not consider null handle as system asset', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('isSystemAsset');
$method->setAccessible(true);
$result = $method->invokeArgs($this->assetMinification, ['']);
diff --git a/tests/Unit/AssetMinificationSmartLogicTest.php b/tests/Unit/AssetMinificationSmartLogicTest.php
index f23a1c0..cbd57f9 100644
--- a/tests/Unit/AssetMinificationSmartLogicTest.php
+++ b/tests/Unit/AssetMinificationSmartLogicTest.php
@@ -2,23 +2,25 @@
/**
* Test AssetMinification smart logic
+ *
* @group problematic
*/
describe('AssetMinification Smart Logic', function () {
// Пропускаем эти тесты в CI из-за Patchwork конфликтов
if (getenv('CI') === 'true' || getenv('GITHUB_ACTIONS') === 'true') {
test('skipped in CI', function () {})->skip('Patchwork conflicts in CI');
+
return;
}
beforeEach(function () {
global $mock_functions;
$mock_functions = [];
- $this->mockOptionService = \Mockery::mock('\WpAddon\Services\OptionService');
+ $this->mockOptionService = Mockery::mock('\WpAddon\Services\OptionService');
// Mock option service to return default config
$this->mockOptionService->shouldReceive('getSetting')
- ->andReturnUsing(function($key, $default = null) {
+ ->andReturnUsing(function ($key, $default = null) {
$config = [
'enabled' => true,
'minify_css' => true,
@@ -29,9 +31,10 @@
'defer_non_critical_css' => true,
'exclude_css' => ['admin-bar', 'dashicons'],
'exclude_js' => ['jquery', 'jquery-core'],
- 'cache_dir' => sys_get_temp_dir() . '/wp_addon_cache',
+ 'cache_dir' => sys_get_temp_dir().'/wp_addon_cache',
'version_salt' => 'wp-addon-v1',
];
+
return $config[$key] ?? $default;
});
@@ -40,7 +43,7 @@
});
afterEach(function () {
- \Mockery::close();
+ Mockery::close();
});
it('excludes system assets', function () {
@@ -57,7 +60,7 @@
'wp-emoji',
];
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
@@ -70,7 +73,7 @@
it('excludes explicitly excluded assets', function () {
$excludes = ['custom-plugin-css', 'theme-style'];
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
@@ -89,7 +92,7 @@
'https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js',
];
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
@@ -111,7 +114,7 @@
$mock_functions['file_exists'] = true;
$mock_functions['filesize'] = 2048;
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
@@ -126,7 +129,7 @@
global $mock_functions;
$mock_functions['filesize'] = 500; // 500 bytes
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
@@ -140,7 +143,7 @@
$mock_functions['file_exists'] = true;
$mock_functions['filesize'] = 2048; // 2KB
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
@@ -153,7 +156,7 @@
global $mock_functions;
$mock_functions['file_exists'] = false;
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
@@ -167,7 +170,7 @@
$mock_functions['file_exists'] = true;
$mock_functions['filesize'] = 2048;
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('shouldProcessAsset');
$method->setAccessible(true);
@@ -179,7 +182,7 @@
// Test minified CSS
$minifiedCss = '.class{color:#fff;font-size:14px}.another{margin:0}';
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('isAlreadyMinified');
$method->setAccessible(true);
@@ -196,7 +199,7 @@
// Test minified JS
$minifiedJs = 'function test(){var a=1;return a*2}document.addEventListener("load",test)';
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('isAlreadyMinified');
$method->setAccessible(true);
@@ -210,7 +213,7 @@
});
it('handles minification edge cases', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('isAlreadyMinified');
$method->setAccessible(true);
@@ -230,10 +233,10 @@
// Test known system assets
$systemAssets = [
'jquery', 'jquery-core', 'jquery-migrate', 'jquery-ui',
- 'admin-bar', 'dashicons', 'heartbeat', 'wp-embed'
+ 'admin-bar', 'dashicons', 'heartbeat', 'wp-embed',
];
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('isSystemAsset');
$method->setAccessible(true);
@@ -244,7 +247,7 @@
// Test non-system assets
$nonSystemAssets = [
- 'custom-script', 'theme-style', 'plugin-css', 'bootstrap'
+ 'custom-script', 'theme-style', 'plugin-css', 'bootstrap',
];
foreach ($nonSystemAssets as $asset) {
@@ -254,7 +257,7 @@
});
it('returns correct asset priorities', function () {
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('getAssetPriority');
$method->setAccessible(true);
@@ -289,9 +292,9 @@
it('converts URL to path', function () {
$url = 'http://localhost/wp-content/themes/theme/style.css';
- $expectedPath = ABSPATH . 'wp-content/themes/theme/style.css';
+ $expectedPath = ABSPATH.'wp-content/themes/theme/style.css';
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('urlToPath');
$method->setAccessible(true);
@@ -303,7 +306,7 @@
$key = 'test-cache-key';
$expectedUrl = 'http://localhost/wp-content/cache/assets/test-cache-key.gz';
- $reflection = new \ReflectionClass($this->assetMinification);
+ $reflection = new ReflectionClass($this->assetMinification);
$method = $reflection->getMethod('getCacheUrl');
$method->setAccessible(true);
diff --git a/tests/Unit/AssetMinificationTest.php b/tests/Unit/AssetMinificationTest.php
index 8ec98f1..3f3c348 100644
--- a/tests/Unit/AssetMinificationTest.php
+++ b/tests/Unit/AssetMinificationTest.php
@@ -1,8 +1,9 @@
skip('Complex dependencies in CI');
+
return;
}
it('creates cache files for CSS assets', function () {
- $cacheDir = sys_get_temp_dir() . '/wp_addon_cache/';
- $optionService = \Mockery::mock('\\WpAddon\\Services\\OptionService');
- $assetMinification = new \AssetMinification($optionService);
+ $cacheDir = sys_get_temp_dir().'/wp_addon_cache/';
+ $optionService = Mockery::mock('\\WpAddon\\Services\\OptionService');
+ $assetMinification = new AssetMinification($optionService);
// Mock config
$optionService->shouldReceive('getSetting')
- ->andReturnUsing(function($key, $default) {
+ ->andReturnUsing(function ($key, $default) {
$config = [
'asset_minification_enabled' => true,
'asset_minify_css' => true,
@@ -37,20 +40,21 @@ function site_url() {
'asset_defer_non_critical_css' => false,
'asset_exclude_css' => '',
'asset_exclude_js' => '',
- 'cache_dir' => sys_get_temp_dir() . '/wp_addon_cache',
+ 'cache_dir' => sys_get_temp_dir().'/wp_addon_cache',
'version_salt' => 'wp-addon-v1',
];
+
return $config[$key] ?? $default;
});
// Mock WordPress globals
global $wp_styles;
- $wp_styles = new \stdClass();
+ $wp_styles = new stdClass;
$wp_styles->queue = ['test-style'];
// Create test CSS file
$cssContent = str_repeat(".test {\n color: red;\n font-size: 14px;\n margin: 10px;\n padding: 5px;\n}\n", 20); // CSS with newlines, > 1KB
- $testCssPath = sys_get_temp_dir() . '/test.css';
+ $testCssPath = sys_get_temp_dir().'/test.css';
file_put_contents($testCssPath, $cssContent);
$wp_styles->registered = [
@@ -59,15 +63,15 @@ function site_url() {
'src' => 'http://localhost/test.css',
'deps' => [],
'ver' => '1.0.0',
- 'args' => 'all'
- ]
+ 'args' => 'all',
+ ],
];
// Mock ABSPATH for urlToPath
- define('ABSPATH', sys_get_temp_dir() . '/');
+ define('ABSPATH', sys_get_temp_dir().'/');
// Ensure cache dir exists
- if (!is_dir($cacheDir)) {
+ if (! is_dir($cacheDir)) {
mkdir($cacheDir, 0755, true);
}
@@ -78,7 +82,7 @@ function site_url() {
$assetMinification->processAssets();
// Check if cache file was created
- $files = glob($cacheDir . '*.gz');
+ $files = glob($cacheDir.'*.gz');
expect(count($files))->toBeGreaterThan(0, 'Cache file should be created');
@@ -90,13 +94,13 @@ function site_url() {
});
it('creates cache files for JS assets', function () {
- $cacheDir = sys_get_temp_dir() . '/wp_addon_cache/';
- $optionService = \Mockery::mock('\\WpAddon\\Services\\OptionService');
- $assetMinification = new \AssetMinification($optionService);
+ $cacheDir = sys_get_temp_dir().'/wp_addon_cache/';
+ $optionService = Mockery::mock('\\WpAddon\\Services\\OptionService');
+ $assetMinification = new AssetMinification($optionService);
// Mock config for JS
$optionService->shouldReceive('getSetting')
- ->andReturnUsing(function($key, $default) {
+ ->andReturnUsing(function ($key, $default) {
$config = [
'asset_minification_enabled' => true,
'asset_minify_css' => false,
@@ -107,20 +111,21 @@ function site_url() {
'asset_defer_non_critical_css' => false,
'asset_exclude_css' => '',
'asset_exclude_js' => '',
- 'cache_dir' => sys_get_temp_dir() . '/wp_addon_cache',
+ 'cache_dir' => sys_get_temp_dir().'/wp_addon_cache',
'version_salt' => 'wp-addon-v1',
];
+
return $config[$key] ?? $default;
});
// Mock WordPress globals
global $wp_scripts;
- $wp_scripts = new \stdClass();
+ $wp_scripts = new stdClass;
$wp_scripts->queue = ['test-script'];
// Create test JS file
$jsContent = str_repeat("function test() {\n console.log('test');\n return true;\n}\n", 20); // JS with newlines
- $testJsPath = sys_get_temp_dir() . '/test.js';
+ $testJsPath = sys_get_temp_dir().'/test.js';
file_put_contents($testJsPath, $jsContent);
$wp_scripts->registered = [
@@ -129,15 +134,15 @@ function site_url() {
'src' => 'http://localhost/test.js',
'deps' => [],
'ver' => '1.0.0',
- 'args' => false
- ]
+ 'args' => false,
+ ],
];
// Mock ABSPATH for urlToPath
- define('ABSPATH', sys_get_temp_dir() . '/');
+ define('ABSPATH', sys_get_temp_dir().'/');
// Ensure cache dir exists
- if (!is_dir($cacheDir)) {
+ if (! is_dir($cacheDir)) {
mkdir($cacheDir, 0755, true);
}
@@ -148,7 +153,7 @@ function site_url() {
$assetMinification->processAssets();
// Check if cache file was created
- $files = glob($cacheDir . '*.gz');
+ $files = glob($cacheDir.'*.gz');
expect(count($files))->toBeGreaterThan(0, 'Cache file should be created');
diff --git a/tests/Unit/FactoriesTest.php b/tests/Unit/FactoriesTest.php
index 3c0bdaa..b89c5b4 100644
--- a/tests/Unit/FactoriesTest.php
+++ b/tests/Unit/FactoriesTest.php
@@ -1,18 +1,18 @@
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
});
it('creates posts with PostFactory', function () {
- $factory = new PostFactory();
+ $factory = new PostFactory;
$post = $factory->create(['post_title' => 'Test Post']);
expect($post)->toBeInt();
@@ -20,7 +20,7 @@
});
it('creates multiple posts', function () {
- $factory = new PostFactory();
+ $factory = new PostFactory;
$posts = $factory->createMany(3);
expect($posts)->toBeArray();
@@ -33,7 +33,7 @@
});
it('creates assets with AssetFactory', function () {
- $factory = new AssetFactory();
+ $factory = new AssetFactory;
$asset = $factory->create(['handle' => 'test-asset']);
expect($asset)->toBeArray();
@@ -42,7 +42,7 @@
});
it('creates CSS assets', function () {
- $factory = new AssetFactory();
+ $factory = new AssetFactory;
$factory->asCss();
$asset = $factory->create();
@@ -52,7 +52,7 @@
});
it('creates JS assets', function () {
- $factory = new AssetFactory();
+ $factory = new AssetFactory;
$factory->asJs();
$asset = $factory->create();
diff --git a/tests/Unit/ImageOptimizationServiceTest.php b/tests/Unit/ImageOptimizationServiceTest.php
index 5461788..c60b62b 100644
--- a/tests/Unit/ImageOptimizationServiceTest.php
+++ b/tests/Unit/ImageOptimizationServiceTest.php
@@ -1,19 +1,21 @@
skip('Patchwork conflicts in CI');
+
return;
}
beforeEach(function () {
- $this->imageOptimizationService = new ImageOptimizationService();
+ $this->imageOptimizationService = new ImageOptimizationService;
});
afterEach(function () {
@@ -22,13 +24,14 @@
it('generates blur placeholder for valid image', function () {
// Skip test if GD is not available or in CI environment
- if (!function_exists('imagecreatetruecolor') || getenv('CI') === 'true' || getenv('GITHUB_ACTIONS') === 'true') {
+ if (! function_exists('imagecreatetruecolor') || getenv('CI') === 'true' || getenv('GITHUB_ACTIONS') === 'true') {
expect(true)->toBeTrue(); // Skip test
+
return;
}
// Создаем тестовое изображение
- $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.jpg';
+ $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.jpg';
$image = imagecreatetruecolor(200, 200);
$blue = imagecolorallocate($image, 0, 0, 255);
imagefill($image, 0, 0, $blue);
@@ -51,7 +54,7 @@
});
it('handles invalid image files', function () {
- $tempFile = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.jpg';
+ $tempFile = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.jpg';
file_put_contents($tempFile, 'not an image content');
$result = $this->imageOptimizationService->generateBlurPlaceholder($tempFile);
@@ -62,7 +65,7 @@
});
it('respects blur intensity parameter', function () {
- $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.png';
+ $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.png';
$image = imagecreatetruecolor(100, 100);
$red = imagecolorallocate($image, 255, 0, 0);
imagefill($image, 0, 0, $red);
@@ -73,15 +76,15 @@
$resultLow = $this->imageOptimizationService->generateBlurPlaceholder($tempImage, 2);
$resultHigh = $this->imageOptimizationService->generateBlurPlaceholder($tempImage, 8);
- expect($resultLow)->toStartWith('data:image/jpeg;base64,');
- expect($resultHigh)->toStartWith('data:image/jpeg;base64,');
+ expect($resultLow)->toStartWith('data:image/png;base64,');
+ expect($resultHigh)->toStartWith('data:image/png;base64,');
expect($resultLow)->not->toBe($resultHigh); // Разные уровни размытия дают разные результаты
unlink($tempImage);
});
it('generates correct thumbnail size', function () {
- $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.jpg';
+ $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.jpg';
$image = imagecreatetruecolor(800, 600); // Большое изображение
$green = imagecolorallocate($image, 0, 255, 0);
imagefill($image, 0, 0, $green);
@@ -94,7 +97,7 @@
// Декодируем и проверяем размер
$imageData = base64_decode(str_replace('data:image/jpeg;base64,', '', $result));
- $tempDecoded = tempnam(sys_get_temp_dir(), 'wp_addon_decoded_') . '.jpg';
+ $tempDecoded = tempnam(sys_get_temp_dir(), 'wp_addon_decoded_').'.jpg';
file_put_contents($tempDecoded, $imageData);
if (function_exists('getimagesize')) {
@@ -108,7 +111,7 @@
});
it('optimizes image quality', function () {
- $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.jpg';
+ $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.jpg';
$image = imagecreatetruecolor(100, 100);
$yellow = imagecolorallocate($image, 255, 255, 0);
imagefill($image, 0, 0, $yellow);
@@ -130,7 +133,7 @@
$formats = ['jpg', 'jpeg', 'png'];
foreach ($formats as $format) {
- $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.' . $format;
+ $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.'.$format;
$image = imagecreatetruecolor(50, 50);
$color = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
imagefill($image, 0, 0, $color);
@@ -144,18 +147,19 @@
$result = $this->imageOptimizationService->generateBlurPlaceholder($tempImage);
- expect($result)->toStartWith('data:image/jpeg;base64,'); // Всегда возвращает JPEG
+ $expectedMime = $format === 'png' ? 'image/png' : 'image/jpeg';
+ expect($result)->toStartWith('data:'.$expectedMime.';base64,');
unlink($tempImage);
}
});
it('handles images with alpha channel', function () {
- if (!function_exists('imagecreatetruecolor')) {
+ if (! function_exists('imagecreatetruecolor')) {
skip('GD library not available');
}
- $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.png';
+ $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.png';
$image = imagecreatetruecolor(50, 50);
imagealphablending($image, false);
$transparent = imagecolorallocatealpha($image, 0, 0, 0, 127);
@@ -166,14 +170,14 @@
$result = $this->imageOptimizationService->generateBlurPlaceholder($tempImage);
- expect($result)->toStartWith('data:image/jpeg;base64,');
+ expect($result)->toStartWith('data:image/png;base64,');
expect(strlen($result))->toBeGreaterThan(100);
unlink($tempImage);
});
it('validates input parameters', function () {
- $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.jpg';
+ $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.jpg';
$image = imagecreatetruecolor(10, 10);
imagejpeg($image, $tempImage);
imagedestroy($image);
@@ -191,7 +195,7 @@
});
it('handles file permission errors', function () {
- $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.jpg';
+ $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.jpg';
$image = imagecreatetruecolor(10, 10);
imagejpeg($image, $tempImage);
imagedestroy($image);
@@ -209,7 +213,7 @@
});
it('optimizes image dimensions proportionally', function () {
- $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_') . '.jpg';
+ $tempImage = tempnam(sys_get_temp_dir(), 'wp_addon_test_').'.jpg';
$image = imagecreatetruecolor(400, 200); // Прямоугольное изображение
$color = imagecolorallocate($image, 100, 100, 100);
imagefill($image, 0, 0, $color);
@@ -220,7 +224,7 @@
// Декодируем и проверяем пропорции
$imageData = base64_decode(str_replace('data:image/jpeg;base64,', '', $result));
- $tempDecoded = tempnam(sys_get_temp_dir(), 'wp_addon_decoded_') . '.jpg';
+ $tempDecoded = tempnam(sys_get_temp_dir(), 'wp_addon_decoded_').'.jpg';
file_put_contents($tempDecoded, $imageData);
if (function_exists('getimagesize')) {
diff --git a/tests/Unit/LazyLoadingTest.php b/tests/Unit/LazyLoadingTest.php
index 6bba027..eb7de43 100644
--- a/tests/Unit/LazyLoadingTest.php
+++ b/tests/Unit/LazyLoadingTest.php
@@ -9,8 +9,9 @@
beforeEach(function () {
$this->mockOptionService = Mockery::mock('WpAddon\Services\OptionService');
$this->mockOptionService->shouldReceive('getSetting')
- ->andReturnUsing(function($key, $default = null) {
+ ->andReturnUsing(function ($key, $default = null) {
$config = ['enable_lazy_loading' => true];
+
return $config[$key] ?? $default;
});
});
@@ -110,4 +111,32 @@
expect($result)->toContain('class="existing-class lazy-img"');
expect($result)->toContain('id="test-img"');
});
+
+ it('defers responsive images without losing sizes', function () {
+ $lazyLoading = new LazyLoading($this->mockOptionService);
+
+ $result = $lazyLoading->processContent('
');
+
+ expect($result)->toContain('data-src="/image.jpg"');
+ expect($result)->toContain('data-srcset="/image-400.jpg 400w, /image-800.jpg 800w"');
+ expect($result)->toContain('sizes="(max-width: 600px) 100vw, 600px"');
+ expect($result)->not()->toMatch('/\ssrcset=/');
+ });
+
+ it('supports single quoted attributes and remains idempotent', function () {
+ $lazyLoading = new LazyLoading($this->mockOptionService);
+
+ $result = $lazyLoading->processContent("
");
+
+ expect($result)->toContain('data-src="/image.jpg"');
+ expect($lazyLoading->processContent($result))->toBe($result);
+ });
+
+ it('matches no-lazy as a complete CSS class', function () {
+ $lazyLoading = new LazyLoading($this->mockOptionService);
+
+ $result = $lazyLoading->processContent('
');
+
+ expect($result)->toContain('data-src="/image.jpg"');
+ });
});
diff --git a/tests/Unit/MediaCleanupServiceTest.php b/tests/Unit/MediaCleanupServiceTest.php
index 11dae64..6a8903c 100644
--- a/tests/Unit/MediaCleanupServiceTest.php
+++ b/tests/Unit/MediaCleanupServiceTest.php
@@ -9,6 +9,7 @@
// Пропускаем эти тесты в CI из-за проблем с mock'ами
if (getenv('CI') === 'true' || getenv('GITHUB_ACTIONS') === 'true') {
test('skipped in CI', function () {})->skip('Mock issues in CI');
+
return;
}
beforeEach(function () {
@@ -16,7 +17,7 @@
$mock_functions = [];
// Mock get_option
- $mock_functions['get_option'] = function($key, $default = '') {
+ $mock_functions['get_option'] = function ($key, $default = '') {
$options = [
'thumbnail_size_w' => 150,
'thumbnail_size_h' => 150,
@@ -25,10 +26,11 @@
'large_size_w' => 1024,
'large_size_h' => 1024,
];
+
return $options[$key] ?? $default;
};
- $this->service = new MediaCleanupService();
+ $this->service = new MediaCleanupService;
});
it('returns registered sizes', function () {
diff --git a/tests/Unit/ModuleSystemTest.php b/tests/Unit/ModuleSystemTest.php
index 36825ec..43b8e34 100644
--- a/tests/Unit/ModuleSystemTest.php
+++ b/tests/Unit/ModuleSystemTest.php
@@ -3,7 +3,6 @@
use WpAddon\Interfaces\ModuleInterface;
use WpAddon\Traits\AjaxTrait;
use WpAddon\Traits\WidgetTrait;
-use WpAddon\Traits\HookTrait;
describe('Module System', function () {
it('has ModuleInterface', function () {
@@ -17,9 +16,12 @@
});
it('AjaxTrait has methods', function () {
- $mock = new class implements ModuleInterface {
+ $mock = new class implements ModuleInterface
+ {
use AjaxTrait;
+
public function init(): void {}
+
public function handleAjax(): void {}
};
@@ -27,9 +29,12 @@ public function handleAjax(): void {}
});
it('WidgetTrait has methods', function () {
- $mock = new class implements ModuleInterface {
+ $mock = new class implements ModuleInterface
+ {
use WidgetTrait;
+
public function init(): void {}
+
public function widget($args, $instance): void {}
};
@@ -37,17 +42,13 @@ public function widget($args, $instance): void {}
});
it('Redirects module works', function () {
- // Assume class is autoloaded
- if (class_exists('Redirects')) {
- expect(class_exists('Redirects'))->toBeTrue();
- expect(is_subclass_of('Redirects', 'WpAddon\Interfaces\ModuleInterface'))->toBeTrue();
-
- $redirects = new Redirects();
- expect($redirects)->toBeInstanceOf(ModuleInterface::class);
- expect(method_exists($redirects, 'init'))->toBeTrue();
- } else {
- // Skip if not available
- expect(true)->toBeTrue();
- }
+ require_once dirname(__DIR__, 2).'/functions/Redirects.php';
+
+ expect(class_exists('Redirects'))->toBeTrue();
+ expect(is_subclass_of('Redirects', 'WpAddon\Interfaces\ModuleInterface'))->toBeTrue();
+
+ $redirects = new Redirects;
+ expect($redirects)->toBeInstanceOf(ModuleInterface::class);
+ expect(method_exists($redirects, 'init'))->toBeTrue();
});
});
diff --git a/tests/Unit/Services/AssetOptimizationServiceTest.php b/tests/Unit/Services/AssetOptimizationServiceTest.php
index 2d73674..b1e926b 100644
--- a/tests/Unit/Services/AssetOptimizationServiceTest.php
+++ b/tests/Unit/Services/AssetOptimizationServiceTest.php
@@ -1,11 +1,11 @@
cacheDir = sys_get_temp_dir() . '/wp_addon_test_cache_' . uniqid();
+ $this->cacheDir = sys_get_temp_dir().'/wp_addon_test_cache_'.uniqid();
mkdir($this->cacheDir, 0755, true);
$config = [
@@ -17,16 +17,16 @@
'combine_js' => true,
'critical_css_enabled' => true,
'exclude_css' => [],
- 'exclude_js' => []
+ 'exclude_js' => [],
];
- $this->service = new \WpAddon\Services\AssetOptimizationService($config);
+ $this->service = new AssetOptimizationService($config);
});
afterEach(function () {
// Clean up cache directory
if (is_dir($this->cacheDir)) {
- $files = glob($this->cacheDir . '/*');
+ $files = glob($this->cacheDir.'/*');
foreach ($files as $file) {
unlink($file);
}
@@ -83,7 +83,7 @@
it('combines CSS files', function () {
$files = [
$this->getTestDataPath('test.css'),
- $this->getTestDataPath('small.css')
+ $this->getTestDataPath('small.css'),
];
$combined = $this->service->combineCss($files);
@@ -96,7 +96,7 @@
it('combines JS files', function () {
$files = [
$this->createTempFile('function a(){return 1;}'),
- $this->createTempFile('function b(){return 2;}')
+ $this->createTempFile('function b(){return 2;}'),
];
$combined = $this->service->combineJs($files);
@@ -138,7 +138,7 @@
$this->service->saveToCache($key, $content);
- $cacheFile = $this->cacheDir . '/' . $key . '.gz';
+ $cacheFile = $this->cacheDir.'/'.$key.'.gz';
// Mock file_exists to return true for this test
$this->setMockFunction('file_exists', true);
expect(file_exists($cacheFile))->toBeTrue();
diff --git a/tests/Unit/Services/SimpleAssetOptimizationServiceTest.php b/tests/Unit/Services/SimpleAssetOptimizationServiceTest.php
index 0f2acf3..d57e674 100644
--- a/tests/Unit/Services/SimpleAssetOptimizationServiceTest.php
+++ b/tests/Unit/Services/SimpleAssetOptimizationServiceTest.php
@@ -1,11 +1,11 @@
cacheDir = sys_get_temp_dir() . '/wp_addon_simple_test_cache_' . uniqid();
+ $this->cacheDir = sys_get_temp_dir().'/wp_addon_simple_test_cache_'.uniqid();
mkdir($this->cacheDir, 0755, true);
$config = [
@@ -17,16 +17,16 @@
'combine_js' => true,
'critical_css_enabled' => true,
'exclude_css' => [],
- 'exclude_js' => []
+ 'exclude_js' => [],
];
- $this->service = new \WpAddon\Services\AssetOptimizationService($config);
+ $this->service = new AssetOptimizationService($config);
});
afterEach(function () {
// Clean up cache directory
if (is_dir($this->cacheDir)) {
- $files = glob($this->cacheDir . '/*');
+ $files = glob($this->cacheDir.'/*');
foreach ($files as $file) {
unlink($file);
}
@@ -35,24 +35,24 @@
});
it('minifies basic CSS', function () {
- $css = "
+ $css = '
.test-class {
color: #ff0000;
font-size: 14px;
}
.another { margin: 0; }
- ";
+ ';
$minified = $this->service->minifyCss($css);
// Check that CSS is minified
expect(strpos($minified, "\n"))->toBeFalse();
- expect(strpos($minified, " "))->toBeFalse();
+ expect(strpos($minified, ' '))->toBeFalse();
expect(strpos($minified, '.test-class{color:#ff0000;font-size:14px}.another{margin:0}'))->not->toBeFalse();
});
it('removes comments from CSS', function () {
- $css = "/* This is a comment */ .test { color: red; } /* Another comment */";
+ $css = '/* This is a comment */ .test { color: red; } /* Another comment */';
$minified = $this->service->minifyCss($css);
expect(strpos($minified, '/*'))->toBeFalse();
@@ -61,23 +61,23 @@
});
it('minifies basic JS', function () {
- $js = "
+ $js = '
function test() {
var a = 1;
return a + 2;
}
- ";
+ ';
$minified = $this->service->minifyJs($js);
// Check that JS is minified
expect(strpos($minified, "\n"))->toBeFalse();
- expect(strpos($minified, " "))->toBeFalse();
+ expect(strpos($minified, ' '))->toBeFalse();
expect(strpos($minified, 'function test(){var a=1;return a+2;}'))->not->toBeFalse();
});
it('removes comments from JS', function () {
- $js = "/* Block comment */ function test() { return 1; } // Line comment";
+ $js = '/* Block comment */ function test() { return 1; } // Line comment';
$minified = $this->service->minifyJs($js);
expect(strpos($minified, '/*'))->toBeFalse();
@@ -126,12 +126,12 @@ function test() {
});
it('extracts critical CSS', function () {
- $css = "
+ $css = '
.header { position: fixed; background: white; }
.content { margin-top: 100px; }
.footer { position: absolute; bottom: 0; }
.nav { display: block; }
- ";
+ ';
$criticalCss = $this->service->extractCriticalCss($css);
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index b7f6340..bc7d459 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -4,45 +4,49 @@
// Complete prevention of Patchwork loading and conflicts
// Mock Patchwork namespace and classes BEFORE autoloader
-if (!class_exists('Patchwork')) {
- class Patchwork {
- public static function redefine() { }
- public static function restoreAll() { }
- public static function disable() { }
- public static function enable() { }
+if (! class_exists('Patchwork')) {
+ class Patchwork
+ {
+ public static function redefine() {}
+
+ public static function restoreAll() {}
+
+ public static function disable() {}
+
+ public static function enable() {}
}
}
// Mock Patchwork\redefine function
-if (!function_exists('redefine')) {
- function redefine() { }
+if (! function_exists('redefine')) {
+ function redefine() {}
}
// Mock Patchwork\restoreAll function
-if (!function_exists('restoreAll')) {
- function restoreAll() { }
+if (! function_exists('restoreAll')) {
+ function restoreAll() {}
}
// Mock Patchwork\replace function
-if (!function_exists('replace')) {
- function replace() { }
+if (! function_exists('replace')) {
+ function replace() {}
}
// Mock Patchwork\relay function
-if (!function_exists('relay')) {
- function relay() { }
+if (! function_exists('relay')) {
+ function relay() {}
}
// Mock Patchwork\redefineMethod function
-if (!function_exists('redefineMethod')) {
- function redefineMethod() { }
+if (! function_exists('redefineMethod')) {
+ function redefineMethod() {}
}
// Mock Brain Monkey functions
-if (!function_exists('Brain\Monkey\setUp')) {
+if (! function_exists('Brain\Monkey\setUp')) {
eval('namespace Brain\Monkey; function setUp() {} function tearDown() {}');
}
-if (!function_exists('Brain\Monkey\tearDown')) {
+if (! function_exists('Brain\Monkey\tearDown')) {
eval('namespace Brain\Monkey; function tearDown() {}');
}
@@ -51,8 +55,10 @@ function redefineMethod() { }
if (strpos($class, 'Patchwork') === 0 || strpos($class, 'Brain\\Monkey') === 0) {
// Return a mock class for any Patchwork or Brain Monkey class
eval("class {$class} { public static function __callStatic(\$method, \$args) { return \$args ? \$args[0] : null; } public function __call(\$method, \$args) { return \$args ? \$args[0] : null; } }");
+
return true;
}
+
return false;
}, true, true);
@@ -62,11 +68,11 @@ function redefineMethod() { }
'call_user_func_array', 'spl_autoload_register', 'array_map',
'array_intersect_uassoc', 'array_udiff', 'array_uintersect_uassoc',
'libxml_set_external_entity_loader', 'array_diff_uassoc', 'call_user_func',
- 'array_udiff_assoc', 'iterator_apply', 'array_udiff_uassoc'
+ 'array_udiff_assoc', 'iterator_apply', 'array_udiff_uassoc',
];
foreach ($patchworkFunctions as $func) {
- if (!function_exists("Patchwork\\Redefinitions\\{$func}")) {
+ if (! function_exists("Patchwork\\Redefinitions\\{$func}")) {
eval("namespace Patchwork\\Redefinitions; function {$func}(...\$args) { return \$args ? \$args[0] : null; }");
}
}
@@ -74,7 +80,7 @@ function redefineMethod() { }
// === END PATCHWORK PREVENTION ===
// Load composer autoloader
-require_once __DIR__ . '/../vendor/autoload.php';
+require_once __DIR__.'/../vendor/autoload.php';
// Disable any remaining Patchwork functionality
if (class_exists('Patchwork')) {
@@ -95,59 +101,61 @@ function redefineMethod() { }
}
// Mock basic WordPress functions early
-if (!function_exists('plugin_dir_path')) {
- function plugin_dir_path($file) {
- return dirname($file) . '/';
+if (! function_exists('plugin_dir_path')) {
+ function plugin_dir_path($file)
+ {
+ return dirname($file).'/';
}
}
-if (!function_exists('wp_die')) {
- function wp_die($message = '', $title = '', $args = []) {
+if (! function_exists('wp_die')) {
+ function wp_die($message = '', $title = '', $args = [])
+ {
throw new Exception($message ?: 'WordPress died');
}
}
// === WORDPRESS TEST ENVIRONMENT SETUP ===
$wp_tests_dir = getenv('WP_TESTS_DIR');
-if ($wp_tests_dir && file_exists($wp_tests_dir . '/includes/bootstrap.php')) {
+if ($wp_tests_dir && file_exists($wp_tests_dir.'/includes/bootstrap.php')) {
// Load WordPress test bootstrap for proper environment
- require_once $wp_tests_dir . '/includes/bootstrap.php';
+ require_once $wp_tests_dir.'/includes/bootstrap.php';
} else {
// Fallback for local development without WordPress test suite
// Define WordPress constants
- if (!defined('ABSPATH')) {
- define('ABSPATH', dirname(dirname(__DIR__)) . '/');
+ if (! defined('ABSPATH')) {
+ define('ABSPATH', dirname(dirname(__DIR__)).'/');
}
- if (!defined('WPINC')) {
+ if (! defined('WPINC')) {
define('WPINC', 'wp-includes');
}
- if (!defined('WP_CONTENT_DIR')) {
- define('WP_CONTENT_DIR', ABSPATH . 'wp-content');
+ if (! defined('WP_CONTENT_DIR')) {
+ define('WP_CONTENT_DIR', ABSPATH.'wp-content');
}
- if (!defined('WP_PLUGIN_DIR')) {
- define('WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins');
+ if (! defined('WP_PLUGIN_DIR')) {
+ define('WP_PLUGIN_DIR', WP_CONTENT_DIR.'/plugins');
}
- if (!defined('WP_CONTENT_URL')) {
+ if (! defined('WP_CONTENT_URL')) {
define('WP_CONTENT_URL', 'http://localhost/wp-content');
}
- if (!defined('WP_PLUGIN_URL')) {
- define('WP_PLUGIN_URL', WP_CONTENT_URL . '/plugins');
+ if (! defined('WP_PLUGIN_URL')) {
+ define('WP_PLUGIN_URL', WP_CONTENT_URL.'/plugins');
}
- if (!defined('WP_DEBUG')) {
+ if (! defined('WP_DEBUG')) {
define('WP_DEBUG', true);
}
- if (!defined('WP_DEBUG_LOG')) {
+ if (! defined('WP_DEBUG_LOG')) {
define('WP_DEBUG_LOG', false);
}
- if (!defined('WP_DEBUG_DISPLAY')) {
+ if (! defined('WP_DEBUG_DISPLAY')) {
define('WP_DEBUG_DISPLAY', true);
}
// Set up in-memory database for tests
global $wpdb, $db;
- if (!isset($wpdb)) {
- $wpdb = new stdClass();
+ if (! isset($wpdb)) {
+ $wpdb = new stdClass;
$wpdb->prefix = 'wp_';
}
@@ -230,56 +238,66 @@ function wp_die($message = '', $title = '', $args = []) {
");
// Mock WordPress functions for local testing
- if (!function_exists('get_option')) {
- function get_option($key, $default = '') {
+ if (! function_exists('get_option')) {
+ function get_option($key, $default = '')
+ {
global $db;
- $stmt = $db->prepare("SELECT option_value FROM wp_options WHERE option_name = ?");
+ $stmt = $db->prepare('SELECT option_value FROM wp_options WHERE option_name = ?');
$stmt->execute([$key]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
+
return $result ? $result['option_value'] : $default;
}
}
- if (!function_exists('update_option')) {
- function update_option($key, $value) {
+ if (! function_exists('update_option')) {
+ function update_option($key, $value)
+ {
global $db;
- $stmt = $db->prepare("INSERT OR REPLACE INTO wp_options (option_name, option_value) VALUES (?, ?)");
+ $stmt = $db->prepare('INSERT OR REPLACE INTO wp_options (option_name, option_value) VALUES (?, ?)');
+
return $stmt->execute([$key, $value]);
}
}
- if (!function_exists('wp_die')) {
- function wp_die($message = '', $title = '', $args = []) {
+ if (! function_exists('wp_die')) {
+ function wp_die($message = '', $title = '', $args = [])
+ {
throw new Exception($message ?: 'WordPress died');
}
}
- if (!function_exists('apply_filters')) {
- function apply_filters($tag, $value) {
+ if (! function_exists('apply_filters')) {
+ function apply_filters($tag, $value)
+ {
return $value;
}
}
- if (!function_exists('add_action')) {
- function add_action($tag, $callback, $priority = 10, $accepted_args = 1) {
+ if (! function_exists('add_action')) {
+ function add_action($tag, $callback, $priority = 10, $accepted_args = 1)
+ {
// Mock add_action - do nothing
}
}
- if (!function_exists('is_admin')) {
- function is_admin() {
+ if (! function_exists('is_admin')) {
+ function is_admin()
+ {
return false;
}
}
- if (!function_exists('home_url')) {
- function home_url($path = '') {
- return 'http://localhost' . $path;
+ if (! function_exists('home_url')) {
+ function home_url($path = '')
+ {
+ return 'http://localhost'.$path;
}
}
- if (!function_exists('wp_upload_dir')) {
- function wp_upload_dir() {
+ if (! function_exists('wp_upload_dir')) {
+ function wp_upload_dir()
+ {
return [
'path' => '/tmp/uploads',
'url' => 'http://localhost/wp-content/uploads',
@@ -291,56 +309,65 @@ function wp_upload_dir() {
}
}
- if (!function_exists('get_file_data')) {
- function get_file_data($file, $headers) {
- return ['Version' => '1.3.6'];
+ if (! function_exists('get_file_data')) {
+ function get_file_data($file, $headers)
+ {
+ return ['Version' => '1.4.0'];
}
}
- if (!function_exists('plugin_dir_path')) {
- function plugin_dir_path($file) {
- return dirname($file) . '/';
+ if (! function_exists('plugin_dir_path')) {
+ function plugin_dir_path($file)
+ {
+ return dirname($file).'/';
}
}
- if (!function_exists('wp_json_encode')) {
- function wp_json_encode($data, $options = 0, $depth = 512) {
+ if (! function_exists('wp_json_encode')) {
+ function wp_json_encode($data, $options = 0, $depth = 512)
+ {
return \json_encode($data, $options, $depth);
}
}
- if (!function_exists('__')) {
- function __($text, $domain = 'default') {
+ if (! function_exists('__')) {
+ function __($text, $domain = 'default')
+ {
return $text;
}
}
- if (!function_exists('_e')) {
- function _e($text, $domain = 'default') {
+ if (! function_exists('_e')) {
+ function _e($text, $domain = 'default')
+ {
echo $text;
}
}
- if (!function_exists('site_url')) {
- function site_url($path = '') {
- return 'http://localhost' . $path;
+ if (! function_exists('site_url')) {
+ function site_url($path = '')
+ {
+ return 'http://localhost'.$path;
}
}
- if (!function_exists('admin_url')) {
- function admin_url($path = '') {
- return 'http://localhost/wp-admin' . $path;
+ if (! function_exists('admin_url')) {
+ function admin_url($path = '')
+ {
+ return 'http://localhost/wp-admin'.$path;
}
}
- if (!function_exists('get_site_url')) {
- function get_site_url($blog_id = null, $path = '', $scheme = null) {
- return 'http://localhost' . $path;
+ if (! function_exists('get_site_url')) {
+ function get_site_url($blog_id = null, $path = '', $scheme = null)
+ {
+ return 'http://localhost'.$path;
}
}
- if (!function_exists('wp_get_upload_dir')) {
- function wp_get_upload_dir() {
+ if (! function_exists('wp_get_upload_dir')) {
+ function wp_get_upload_dir()
+ {
return [
'path' => '/tmp/uploads',
'url' => 'http://localhost/wp-content/uploads',
@@ -352,140 +379,163 @@ function wp_get_upload_dir() {
}
}
- if (!function_exists('wp_normalize_path')) {
- function wp_normalize_path($path) {
+ if (! function_exists('wp_normalize_path')) {
+ function wp_normalize_path($path)
+ {
return str_replace('\\', '/', $path);
}
}
- if (!function_exists('wp_doing_ajax')) {
- function wp_doing_ajax() {
+ if (! function_exists('wp_doing_ajax')) {
+ function wp_doing_ajax()
+ {
return defined('DOING_AJAX') && DOING_AJAX;
}
}
- if (!function_exists('wp_doing_cron')) {
- function wp_doing_cron() {
+ if (! function_exists('wp_doing_cron')) {
+ function wp_doing_cron()
+ {
return defined('DOING_CRON') && DOING_CRON;
}
}
- if (!function_exists('wp_is_xml_request')) {
- function wp_is_xml_request() {
+ if (! function_exists('wp_is_xml_request')) {
+ function wp_is_xml_request()
+ {
return false;
}
}
- if (!function_exists('wp_is_json_request')) {
- function wp_is_json_request() {
+ if (! function_exists('wp_is_json_request')) {
+ function wp_is_json_request()
+ {
return false;
}
}
- if (!function_exists('wp_is_jsonp_request')) {
- function wp_is_jsonp_request() {
+ if (! function_exists('wp_is_jsonp_request')) {
+ function wp_is_jsonp_request()
+ {
return false;
}
}
- if (!function_exists('wp_kses_post')) {
- function wp_kses_post($data) {
+ if (! function_exists('wp_kses_post')) {
+ function wp_kses_post($data)
+ {
return $data;
}
}
- if (!function_exists('sanitize_text_field')) {
- function sanitize_text_field($str) {
+ if (! function_exists('sanitize_text_field')) {
+ function sanitize_text_field($str)
+ {
return trim($str);
}
}
- if (!function_exists('esc_attr')) {
- function esc_attr($text) {
+ if (! function_exists('esc_attr')) {
+ function esc_attr($text)
+ {
return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
}
}
- if (!function_exists('esc_html')) {
- function esc_html($text) {
+ if (! function_exists('esc_html')) {
+ function esc_html($text)
+ {
return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
}
}
- if (!function_exists('esc_url')) {
- function esc_url($url) {
+ if (! function_exists('esc_url')) {
+ function esc_url($url)
+ {
return filter_var($url, FILTER_SANITIZE_URL);
}
}
- if (!function_exists('wp_enqueue_script')) {
- function wp_enqueue_script($handle, $src = '', $deps = [], $ver = false, $in_footer = false) {
+ if (! function_exists('wp_enqueue_script')) {
+ function wp_enqueue_script($handle, $src = '', $deps = [], $ver = false, $in_footer = false)
+ {
// Mock - do nothing
}
}
- if (!function_exists('wp_enqueue_style')) {
- function wp_enqueue_style($handle, $src = '', $deps = [], $ver = false, $media = 'all') {
+ if (! function_exists('wp_enqueue_style')) {
+ function wp_enqueue_style($handle, $src = '', $deps = [], $ver = false, $media = 'all')
+ {
// Mock - do nothing
}
}
- if (!function_exists('wp_register_script')) {
- function wp_register_script($handle, $src = '', $deps = [], $ver = false, $in_footer = false) {
+ if (! function_exists('wp_register_script')) {
+ function wp_register_script($handle, $src = '', $deps = [], $ver = false, $in_footer = false)
+ {
// Mock - do nothing
}
}
- if (!function_exists('wp_register_style')) {
- function wp_register_style($handle, $src = '', $deps = [], $ver = false, $media = 'all') {
+ if (! function_exists('wp_register_style')) {
+ function wp_register_style($handle, $src = '', $deps = [], $ver = false, $media = 'all')
+ {
// Mock - do nothing
}
}
- if (!function_exists('wp_deregister_script')) {
- function wp_deregister_script($handle) {
+ if (! function_exists('wp_deregister_script')) {
+ function wp_deregister_script($handle)
+ {
// Mock - do nothing
}
}
- if (!function_exists('wp_deregister_style')) {
- function wp_deregister_style($handle) {
+ if (! function_exists('wp_deregister_style')) {
+ function wp_deregister_style($handle)
+ {
// Mock - do nothing
}
}
- if (!function_exists('wp_localize_script')) {
- function wp_localize_script($handle, $object_name, $l10n) {
+ if (! function_exists('wp_localize_script')) {
+ function wp_localize_script($handle, $object_name, $l10n)
+ {
// Mock - do nothing
}
}
- if (!function_exists('wp_create_nonce')) {
- function wp_create_nonce($action = -1) {
- return 'test_nonce_' . $action;
+ if (! function_exists('wp_create_nonce')) {
+ function wp_create_nonce($action = -1)
+ {
+ return 'test_nonce_'.$action;
}
}
- if (!function_exists('wp_verify_nonce')) {
- function wp_verify_nonce($nonce, $action = -1) {
+ if (! function_exists('wp_verify_nonce')) {
+ function wp_verify_nonce($nonce, $action = -1)
+ {
return strpos($nonce, 'test_nonce_') === 0;
}
}
- if (!function_exists('current_user_can')) {
- function current_user_can($capability) {
+ if (! function_exists('current_user_can')) {
+ function current_user_can($capability)
+ {
return true; // Assume admin for tests
}
}
- if (!function_exists('get_current_user_id')) {
- function get_current_user_id() {
+ if (! function_exists('get_current_user_id')) {
+ function get_current_user_id()
+ {
return 1;
}
}
- if (!function_exists('get_userdata')) {
- function get_userdata($user_id) {
+ if (! function_exists('get_userdata')) {
+ function get_userdata($user_id)
+ {
return (object) [
'ID' => $user_id,
'user_login' => 'testuser',
@@ -495,14 +545,16 @@ function get_userdata($user_id) {
}
}
- if (!function_exists('is_user_logged_in')) {
- function is_user_logged_in() {
+ if (! function_exists('is_user_logged_in')) {
+ function is_user_logged_in()
+ {
return true;
}
}
- if (!function_exists('wp_get_current_user')) {
- function wp_get_current_user() {
+ if (! function_exists('wp_get_current_user')) {
+ function wp_get_current_user()
+ {
return (object) [
'ID' => 1,
'user_login' => 'testuser',
@@ -513,8 +565,9 @@ function wp_get_current_user() {
}
}
- if (!function_exists('get_bloginfo')) {
- function get_bloginfo($show = '') {
+ if (! function_exists('get_bloginfo')) {
+ function get_bloginfo($show = '')
+ {
$info = [
'name' => 'Test Site',
'description' => 'Test Description',
@@ -522,60 +575,71 @@ function get_bloginfo($show = '') {
'version' => '6.0',
'charset' => 'UTF-8',
];
+
return $info[$show] ?? '';
}
}
- if (!function_exists('get_option')) {
- function get_option($key, $default = '') {
+ if (! function_exists('get_option')) {
+ function get_option($key, $default = '')
+ {
global $db;
- $stmt = $db->prepare("SELECT option_value FROM wp_options WHERE option_name = ?");
+ $stmt = $db->prepare('SELECT option_value FROM wp_options WHERE option_name = ?');
$stmt->execute([$key]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
+
return $result ? $result['option_value'] : $default;
}
}
- if (!function_exists('update_option')) {
- function update_option($key, $value) {
+ if (! function_exists('update_option')) {
+ function update_option($key, $value)
+ {
global $db;
- $stmt = $db->prepare("INSERT OR REPLACE INTO wp_options (option_name, option_value) VALUES (?, ?)");
+ $stmt = $db->prepare('INSERT OR REPLACE INTO wp_options (option_name, option_value) VALUES (?, ?)');
+
return $stmt->execute([$key, $value]);
}
}
- if (!function_exists('wp_die')) {
- function wp_die($message = '', $title = '', $args = []) {
+ if (! function_exists('wp_die')) {
+ function wp_die($message = '', $title = '', $args = [])
+ {
throw new Exception($message ?: 'WordPress died');
}
}
- if (!function_exists('apply_filters')) {
- function apply_filters($tag, $value) {
+ if (! function_exists('apply_filters')) {
+ function apply_filters($tag, $value)
+ {
return $value;
}
}
- if (!function_exists('add_action')) {
- function add_action($tag, $callback, $priority = 10, $accepted_args = 1) {
+ if (! function_exists('add_action')) {
+ function add_action($tag, $callback, $priority = 10, $accepted_args = 1)
+ {
// Mock add_action - do nothing
}
}
- if (!function_exists('is_admin')) {
- function is_admin() {
+ if (! function_exists('is_admin')) {
+ function is_admin()
+ {
return false;
}
}
- if (!function_exists('home_url')) {
- function home_url($path = '') {
- return 'http://localhost' . $path;
+ if (! function_exists('home_url')) {
+ function home_url($path = '')
+ {
+ return 'http://localhost'.$path;
}
}
- if (!function_exists('wp_upload_dir')) {
- function wp_upload_dir() {
+ if (! function_exists('wp_upload_dir')) {
+ function wp_upload_dir()
+ {
return [
'path' => '/tmp/uploads',
'url' => 'http://localhost/wp-content/uploads',
@@ -587,26 +651,30 @@ function wp_upload_dir() {
}
}
- if (!function_exists('get_file_data')) {
- function get_file_data($file, $headers) {
- return ['Version' => '1.3.6'];
+ if (! function_exists('get_file_data')) {
+ function get_file_data($file, $headers)
+ {
+ return ['Version' => '1.4.0'];
}
}
- if (!function_exists('plugin_dir_path')) {
- function plugin_dir_path($file) {
- return dirname($file) . '/';
+ if (! function_exists('plugin_dir_path')) {
+ function plugin_dir_path($file)
+ {
+ return dirname($file).'/';
}
}
- if (!function_exists('wp_json_encode')) {
- function wp_json_encode($data, $options = 0, $depth = 512) {
+ if (! function_exists('wp_json_encode')) {
+ function wp_json_encode($data, $options = 0, $depth = 512)
+ {
return \json_encode($data, $options, $depth);
}
}
- if (!function_exists('__')) {
- function __($text, $domain = 'default') {
+ if (! function_exists('__')) {
+ function __($text, $domain = 'default')
+ {
return $text;
}
}
diff --git a/wp-addon-plugin.php b/wp-addon-plugin.php
index 75245b4..3bbd65d 100644
--- a/wp-addon-plugin.php
+++ b/wp-addon-plugin.php
@@ -1,9 +1,13 @@
init();
\ No newline at end of file
+$plugin = new Plugin(__FILE__);
+$plugin->init();