<?xml version="1.0" encoding="UTF-8"?>        <rss version="2.0"
             xmlns:atom="http://www.w3.org/2005/Atom"
             xmlns:dc="http://purl.org/dc/elements/1.1/"
             xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
             xmlns:admin="http://webns.net/mvcb/"
             xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:content="http://purl.org/rss/1.0/modules/content/">
        <channel>
            <title>
									wpForo - gVectors Team - Forum				            </title>
            <link>https://gvectors.com/forum/general-questions/</link>
            <description>WordPress Plugins Support Forum</description>
            <language>en-US</language>
            <lastBuildDate>Sun, 12 Apr 2026 00:19:02 +0000</lastBuildDate>
            <generator>wpForo</generator>
            <ttl>60</ttl>
							                    <item>
                        <title>Delay in wpForo</title>
                        <link>https://gvectors.com/forum/general-questions/delay-in-wpforo/</link>
                        <pubDate>Sun, 25 Jan 2026 11:55:07 +0000</pubDate>
                        <description><![CDATA[Hi gVectors,
I am using wpForo on my website where I publish various news and related content. Unfortunately, I have a few individuals who, over the course of several years, have systematic...]]></description>
                        <content:encoded><![CDATA[<p data-start="125" data-end="376">Hi <span>gVectors,</span></p>
<p data-start="125" data-end="376">I am using wpForo on my website where I publish various news and related content. Unfortunately, I have a few individuals who, over the course of several years, have systematically copied everything I publish and reposted it on their own copy-website.</p>
<p data-start="378" data-end="685">These individuals have not registered as users on my website or in the forum, but I have identified their IP addresses. I would like to emphasize that I do <strong data-start="534" data-end="541">not</strong> want to restrict the content so that it is only available to logged-in members, as this would have a significant negative impact on my website.</p>
<p data-start="687" data-end="841">Of course, I could simply block the unwanted IP addresses, but that would only be a temporary solution. They would just continue using other IP addresses.</p>
<p data-start="843" data-end="1158">My idea is therefore to solve this challenge in a different way: by allowing me, in the wpForo admin area, to enter unwanted IP addresses and assign an optional delay to them—so that these visitors can only see forum posts after a specified time delay. Such a delay could, for example, be measured in hours or days.</p>
<p data-start="1160" data-end="1383">Would it be possible for you to implement such a feature either directly in the forum or as an add-on?<br data-start="1262" data-end="1265" />Ideally, this functionality should apply consistently across the forum itself, forum listings, widgets, and RSS feeds.</p>
<p data-start="1385" data-end="1459">Thank you very much in advance—and thank you especially for a great forum.</p>
<p data-start="1461" data-end="1473">Kind regards</p>
<p data-start="1461" data-end="1473">KFJ1972</p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>KFJ1972</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/delay-in-wpforo/</guid>
                    </item>
				                    <item>
                        <title># wpForo Performance Analysis Report ## Critical Bottlenecks Found (0.94s TTFB)</title>
                        <link>https://gvectors.com/forum/general-questions/wpforo-performance-analysis-report-critical-bottlenecks-found-0-94s-ttfb/</link>
                        <pubDate>Sat, 13 Dec 2025 09:33:00 +0000</pubDate>
                        <description><![CDATA[# wpForo Performance Analysis Report## Critical Bottlenecks Found (0.94s TTFB)
---
**To:** wpForo Development Team**From:** Development Team @ hmeonot.org.il**Date:** December 13, 2025**Su...]]></description>
                        <content:encoded><![CDATA[<p># wpForo Performance Analysis Report<br />## Critical Bottlenecks Found (0.94s TTFB)</p>
<p>---</p>
<p>**To:** wpForo Development Team<br />**From:** Development Team @ hmeonot.org.il<br />**Date:** December 13, 2025<br />**Subject:** Performance Analysis Report - Critical Bottlenecks Found</p>
<p>---</p>
<p>## Executive Summary</p>
<p>| Metric | Value |<br />|--------|-------|<br />| **wpForo TTFB** | 0.94 seconds (before optimization) |<br />| **Main bottleneck** | functions.php - 60.6% of load time |<br />| **Forum size** | Only 28 posts, 5 topics, 565 profiles |<br />| **Environment** | PHP 8.3, LiteSpeed Enterprise, Redis |</p>
<p>The forum is **extremely small**, yet wpForo still takes nearly 1 second. This proves the issue is in the code architecture, not data volume.</p>
<p>---</p>
<p>## Issue #1: wpforo_is_bot() - Uncached Regex (High Impact)</p>
<p>**Location:** functions.php lines 465-490</p>
<p>**Problem:**</p>
<p>```php<br />function wpforo_is_bot() {<br />$user_agent = wpfval( $_SERVER, 'HTTP_USER_AGENT' );<br />$bots = 'googlebot|bingbot|msnbot|yahoo|...' // ~800 characters, ~40 alternatives!<br />return (bool) preg_match( '#(' . $bots . ')#iu', (string) $user_agent );<br />}<br />```</p>
<p>This function:<br />- Runs a **complex regex with ~40 alternatives** on every request<br />- Has **no caching** - recalculates even for the same user<br />- Is called multiple times per page load</p>
<p>**Suggested Fix:**</p>
<p>```php<br />function wpforo_is_bot() {<br />static $is_bot = null;<br />if ($is_bot !== null) {<br />return $is_bot;<br />}</p>
<p>$user_agent = wpfval($_SERVER, 'HTTP_USER_AGENT');<br />if (empty($user_agent)) {<br />return $is_bot = false;<br />}</p>
<p>// Check common bots first (short-circuit)<br />$ua_lower = strtolower($user_agent);<br />$common_bots = ;<br />foreach ($common_bots as $bot) {<br />if (strpos($ua_lower, $bot) !== false) {<br />return $is_bot = true;<br />}<br />}</p>
<p>// Full regex only if common bots not found<br />$bots = 'bot|crawl|slurp|spider|mediapartners';<br />return $is_bot = (bool) preg_match('#(' . $bots . ')#i', $user_agent);<br />}<br />```</p>
<p>---</p>
<p>## Issue #2: wpforo_phrase() - Redundant String Operations (High Impact)</p>
<p>**Location:** functions.php lines 280-340</p>
<p>**Problem:**</p>
<p>```php<br />function wpforo_phrase( $phrase, $echo = true ) {<br />$phrase_key = addslashes( strtolower( trim( (string) $phrase ) ) );<br />// ...<br />}<br />```</p>
<p>This function:<br />- Calls addslashes(), strtolower(), and trim() on **every phrase lookup**<br />- Is called **hundreds of times** per page<br />- addslashes() is unnecessary for array key lookup</p>
<p>**Suggested Fix:**</p>
<p>Pre-compute lowercase keys once when phrases are loaded, then use direct lookup:</p>
<p>```php<br />class WPForo_Phrase_Cache {<br />private static $phrases = null;<br />private static $keys_map = [];</p>
<p>public static function init($phrases) {<br />self::$phrases = $phrases;<br />foreach ($phrases as $key =&gt; $value) {<br />self::$keys_map = $key;<br />}<br />}</p>
<p>public static function get($phrase) {<br />$key = strtolower(trim($phrase));<br />if (isset(self::$keys_map)) {<br />return self::$phrases[self::$keys_map];<br />}<br />return $phrase;<br />}<br />}<br />```</p>
<p>---</p>
<p>## Issue #3: wpforo_kses() - Massive Arrays Rebuilt Every Call (Medium Impact)</p>
<p>**Location:** functions.php lines 1766-2186</p>
<p>**Problem:**</p>
<p>```php<br />function wpforo_kses($content, $type = 'post') {<br />// ~200 allowed tags defined here - REBUILT ON EVERY CALL<br />$allowed_tags = ;</p>
<p>// ~150 allowed attributes defined here - REBUILT ON EVERY CALL<br />$allowed_attrs = ;<br />}<br />```</p>
<p>These arrays are **rebuilt from scratch on every call** instead of being cached statically.</p>
<p>**Suggested Fix:**</p>
<p>```php<br />function wpforo_kses($content, $type = 'post') {<br />static $allowed_html = null;<br />static $allowed_svg = null;</p>
<p>if ($allowed_html === null) {<br />$allowed_html = [<br />'a' =&gt; ,<br />// ... rest of tags<br />];<br />$allowed_svg = [<br />'svg' =&gt; ,<br />// ... rest of SVG tags<br />];<br />}</p>
<p>// Use cached arrays instead of rebuilding<br />return wp_kses($content, array_merge($allowed_html, $allowed_svg));<br />}<br />```</p>
<p>---</p>
<p>## Issue #4: wpforo_deep_merge() - O(n^5) Complexity (CRITICAL!)</p>
<p>**Location:** functions.php lines 2219-2247</p>
<p>**Problem:**</p>
<p>```php<br />function wpforo_deep_merge( $default, $current = [] ) {<br />foreach( $default as $k =&gt; $v ) {<br />if( is_array( $v ) ) {<br />foreach( $v as $kk =&gt; $vv ) {<br />if( is_array( $vv ) ) {<br />foreach( $vv as $kkk =&gt; $vvv ) {<br />if( is_array( $vvv ) ) {<br />foreach( $vvv as $kkkk =&gt; $vvvv ) {<br />if( is_array( $vvvv ) ) {<br />foreach( $vvvv as $kkkkk =&gt; $vvvvv ) {<br />// 5 LEVELS OF NESTED LOOPS!<br />```</p>
<p>This is **O(n^5) complexity** - exponentially slow with nested arrays.</p>
<p>**Suggested Fix:**</p>
<p>```php<br />function wpforo_deep_merge($default, $current = []) {<br />if (!is_array($default)) return $current;<br />if (!is_array($current)) return $default;<br />return array_replace_recursive($default, $current); // O(n), built-in PHP<br />}<br />```</p>
<p>**Performance comparison:**<br />- Original: O(n^5) - 5 nested loops<br />- Fixed: O(n) - single recursive call</p>
<p>---</p>
<p>## Issue #5: No Lazy Loading - All 20+ Classes Initialize on Every Request</p>
<p>**Location:** wpforo.php lines 237-282</p>
<p>**Problem:**</p>
<p>```php<br />private function init_base_classes() {<br />$this-&gt;settings = new Settings(); // DB queries in constructor<br />$this-&gt;tpl = new Template(); // DB queries in constructor<br />$this-&gt;ram_cache = new RamCache();<br />$this-&gt;cache = new Cache();<br />$this-&gt;action = new Actions();<br />$this-&gt;board = new Boards(); // DB queries in constructor<br />$this-&gt;usergroup = new UserGroups(); // DB queries in constructor<br />$this-&gt;member = new Members(); // DB queries in constructor<br />$this-&gt;perm = new Permissions(); // DB queries in constructor<br />$this-&gt;notice = new Notices();<br />$this-&gt;moderation = new Moderation();<br />$this-&gt;phrase = new Phrases(); // DB queries in constructor<br />// ... and more classes<br />}<br />```</p>
<p>**All 20+ classes instantiate on every page load**, even on pages that don't use the forum. Each constructor typically runs database queries.</p>
<p>**Suggested Fix - Lazy Loading:**</p>
<p>```php<br />class wpForo {<br />private $instances = [];</p>
<p>public function __get($name) {<br />if (!isset($this-&gt;instances)) {<br />$class_map = ;<br />if (isset($class_map)) {<br />$class = 'wpforo\\classes\\' . $class_map;<br />$this-&gt;instances = new $class();<br />}<br />}<br />return $this-&gt;instances ?? null;<br />}<br />}<br />```</p>
<p>---</p>
<p>## Issue #6: File-Based Caching Instead of Object Cache</p>
<p>**Location:** functions.php lines 2268-2305</p>
<p>**Problem:**</p>
<p>```php<br />$option_file = WPF()-&gt;folders . '/item/option/' . md5($option);<br />$value = maybe_unserialize( wpforo_get_file_content( $option_file ) );<br />```</p>
<p>Using filesystem for caching when **Redis/Memcached object cache** is available is significantly slower.</p>
<p>**Benchmarks:**</p>
<p>| Cache Type | Read Time |<br />|------------|-----------|<br />| File system | ~1-5ms |<br />| Redis | ~0.1-0.5ms |<br />| APCu | ~0.01-0.1ms |</p>
<p>**Suggested Fix:**</p>
<p>```php<br />function wpforo_get_option($option) {<br />// Try object cache first (Redis/Memcached)<br />$cached = wp_cache_get($option, 'wpforo_options');<br />if ($cached !== false) {<br />return $cached;<br />}</p>
<p>// Fallback to database<br />$value = get_option('wpforo_' . $option);</p>
<p>// Store in object cache<br />wp_cache_set($option, $value, 'wpforo_options', 3600);</p>
<p>return $value;<br />}<br />```</p>
<p>---</p>
<p>## Our Workaround (MU-Plugin)</p>
<p>We created a Must-Use plugin that patches these issues without modifying wpForo core files. See attached file: wpforo-performance-fixes.php</p>
<p>**Results:**</p>
<p>| Metric | Before | After | Improvement |<br />|--------|--------|-------|-------------|<br />| TTFB | 0.94s | 0.09s | **90% faster** |<br />| DB Queries | 50+ | ~10 | **80% reduction** |<br />| Cache Status | miss | hit | Enabled |</p>
<p>---</p>
<p>## Recommendations Summary</p>
<p>| Priority | Issue | Fix |<br />|----------|-------|-----|<br />| CRITICAL | wpforo_deep_merge() O(n^5) | Use array_replace_recursive() |<br />| CRITICAL | No lazy loading | Implement __get() magic method |<br />| HIGH | wpforo_is_bot() uncached | Static variable caching |<br />| HIGH | wpforo_phrase() string ops | Pre-compute keys |<br />| MEDIUM | wpforo_kses() arrays | Static caching |<br />| MEDIUM | File-based cache | Use wp_cache_*() API |</p>
<p>---</p>
<p>## Offer to Contribute</p>
<p>I would be happy to submit a pull request with these optimizations if the team is interested. The changes are backward-compatible and don't affect functionality.</p>
<p>**Repository:**<span> </span><a class="wpforo-auto-embeded-link" href="https://github.com/gVectors/wpforo" target="_blank" rel="nofollow noopener">https://github.com/gVectors/wpforo</a></p>
<p>Best regards,</p>
<p>**Development Team**<br />hmeonot.org.il<br />Israel</p>
<p>---</p>
<p>## Attachments</p>
<p>1. Full analysis report (Hebrew): wpforo_deep_analysis.md<br />2. Our MU-plugin workaround: wpforo-performance-fixes.php</p>
<p>---</p>
<p>*This report was generated during a performance audit on December 13, 2025*</p>
<p>&nbsp;</p>
<p># דוח ניתוח ביצועים של wpForo<br />## בעיות קריטיות שנמצאו (TTFB של 0.94 שניות)</p>
<p>---</p>
<p>**נושא:** ניתוח ביצועים של wpForo - בעיות קריטיות ופתרונות<br />**מאת:** צוות פיתוח, hmeonot.org.il<br />**תאריך:** 13 בדצמבר 2025</p>
<p>---</p>
<p>שלום לכולם,</p>
<p>אני מפתח שעובד על אתר **hmeonot.org.il** (התאחדות מעונות היום בישראל). במהלך אופטימיזציית ביצועים, מצאתי מספר בעיות קריטיות ב-wpForo שגורמות לזמני טעינה ארוכים.</p>
<p>---</p>
<p>## תקציר מנהלים</p>
<p>| מדד | ערך |<br />|-----|-----|<br />| **TTFB של wpForo** | 0.94 שניות (לפני אופטימיזציה) |<br />| **צוואר הבקבוק העיקרי** | functions.php - 60.6% מזמן הטעינה |<br />| **גודל הפורום** | רק 28 פוסטים, 5 נושאים, 565 פרופילים |<br />| **סביבה** | PHP 8.3, LiteSpeed Enterprise, Redis |</p>
<p>הפורום שלנו **קטן מאוד**, אבל wpForo עדיין לוקח כמעט שנייה. זה מוכיח שהבעיה היא בארכיטקטורת הקוד, לא בכמות הנתונים.</p>
<p>---</p>
<p>## בעיה #1: wpforo_is_bot() - Regex ללא Cache (השפעה גבוהה)</p>
<p>**מיקום:** functions.php שורות 465-490</p>
<p>**הבעיה:**</p>
<p>```php<br />function wpforo_is_bot() {<br />$user_agent = wpfval( $_SERVER, 'HTTP_USER_AGENT' );<br />$bots = 'googlebot|bingbot|msnbot|yahoo|...' // ~800 תווים, ~40 אלטרנטיבות!<br />return (bool) preg_match( '#(' . $bots . ')#iu', (string) $user_agent );<br />}<br />```</p>
<p>הפונקציה הזו:<br />- מריצה **regex מורכב עם ~40 אלטרנטיבות** בכל בקשה<br />- **ללא caching** - מחשבת מחדש גם עבור אותו משתמש<br />- נקראת מספר פעמים בכל טעינת דף</p>
<p>**פתרון מוצע:**</p>
<p>```php<br />function wpforo_is_bot() {<br />static $is_bot = null;<br />if ($is_bot !== null) {<br />return $is_bot;<br />}</p>
<p>$user_agent = wpfval($_SERVER, 'HTTP_USER_AGENT');<br />if (empty($user_agent)) {<br />return $is_bot = false;<br />}</p>
<p>// בדיקת בוטים נפוצים קודם (short-circuit)<br />$ua_lower = strtolower($user_agent);<br />$common_bots = ;<br />foreach ($common_bots as $bot) {<br />if (strpos($ua_lower, $bot) !== false) {<br />return $is_bot = true;<br />}<br />}</p>
<p>// regex מלא רק אם לא נמצאו בוטים נפוצים<br />$bots = 'bot|crawl|slurp|spider|mediapartners';<br />return $is_bot = (bool) preg_match('#(' . $bots . ')#i', $user_agent);<br />}<br />```</p>
<p>---</p>
<p>## בעיה #2: wpforo_phrase() - פעולות מיותרות על מחרוזות (השפעה גבוהה)</p>
<p>**מיקום:** functions.php שורות 280-340</p>
<p>**הבעיה:**</p>
<p>```php<br />function wpforo_phrase( $phrase, $echo = true ) {<br />$phrase_key = addslashes( strtolower( trim( (string) $phrase ) ) );<br />// ...<br />}<br />```</p>
<p>הפונקציה הזו:<br />- קוראת ל-addslashes(), strtolower(), ו-trim() על **כל חיפוש ביטוי**<br />- נקראת **מאות פעמים** בכל דף<br />- addslashes() מיותר לחלוטין לחיפוש במערך</p>
<p>**פתרון מוצע:**</p>
<p>חישוב מקדים של מפתחות באותיות קטנות פעם אחת בטעינה:</p>
<p>```php<br />class WPForo_Phrase_Cache {<br />private static $phrases = null;<br />private static $keys_map = [];</p>
<p>public static function init($phrases) {<br />self::$phrases = $phrases;<br />foreach ($phrases as $key =&gt; $value) {<br />self::$keys_map = $key;<br />}<br />}</p>
<p>public static function get($phrase) {<br />$key = strtolower(trim($phrase));<br />if (isset(self::$keys_map)) {<br />return self::$phrases[self::$keys_map];<br />}<br />return $phrase;<br />}<br />}<br />```</p>
<p>---</p>
<p>## בעיה #3: wpforo_kses() - מערכים ענקיים נבנים מחדש (השפעה בינונית)</p>
<p>**מיקום:** functions.php שורות 1766-2186</p>
<p>**הבעיה:**</p>
<p>```php<br />function wpforo_kses($content, $type = 'post') {<br />// ~200 תגיות מותרות מוגדרות כאן - נבנות מחדש בכל קריאה!<br />$allowed_tags = ;</p>
<p>// ~150 attributes מותרים מוגדרים כאן - נבנים מחדש בכל קריאה!<br />$allowed_attrs = ;<br />}<br />```</p>
<p>מערכים אלה **נבנים מחדש מאפס בכל קריאה** במקום להישמר ב-cache סטטי.</p>
<p>**פתרון מוצע:**</p>
<p>```php<br />function wpforo_kses($content, $type = 'post') {<br />static $allowed_html = null;<br />static $allowed_svg = null;</p>
<p>if ($allowed_html === null) {<br />$allowed_html = [<br />'a' =&gt; ,<br />// ... שאר התגיות<br />];<br />$allowed_svg = [<br />'svg' =&gt; ,<br />// ... שאר תגיות SVG<br />];<br />}</p>
<p>// שימוש במערכים מ-cache במקום בנייה מחדש<br />return wp_kses($content, array_merge($allowed_html, $allowed_svg));<br />}<br />```</p>
<p>---</p>
<p>## בעיה #4: wpforo_deep_merge() - סיבוכיות O(n^5) (קריטי!)</p>
<p>**מיקום:** functions.php שורות 2219-2247</p>
<p>**הבעיה:**</p>
<p>```php<br />function wpforo_deep_merge( $default, $current = [] ) {<br />foreach( $default as $k =&gt; $v ) {<br />if( is_array( $v ) ) {<br />foreach( $v as $kk =&gt; $vv ) {<br />if( is_array( $vv ) ) {<br />foreach( $vv as $kkk =&gt; $vvv ) {<br />if( is_array( $vvv ) ) {<br />foreach( $vvv as $kkkk =&gt; $vvvv ) {<br />if( is_array( $vvvv ) ) {<br />foreach( $vvvv as $kkkkk =&gt; $vvvvv ) {<br />// 5 רמות של לולאות מקוננות!!!<br />```</p>
<p>זו **סיבוכיות O(n^5)** - איטית באופן אקספוננציאלי עם מערכים מקוננים.</p>
<p>**פתרון מוצע:**</p>
<p>```php<br />function wpforo_deep_merge($default, $current = []) {<br />if (!is_array($default)) return $current;<br />if (!is_array($current)) return $default;<br />return array_replace_recursive($default, $current); // O(n), פונקציית PHP מובנית<br />}<br />```</p>
<p>**השוואת ביצועים:**<br />- מקורי: O(n^5) - 5 לולאות מקוננות<br />- מתוקן: O(n) - קריאה רקורסיבית אחת</p>
<p>---</p>
<p>## בעיה #5: אין Lazy Loading - כל 20+ המחלקות נטענות תמיד</p>
<p>**מיקום:** wpforo.php שורות 237-282</p>
<p>**הבעיה:**</p>
<p>```php<br />private function init_base_classes() {<br />$this-&gt;settings = new Settings(); // שאילתות DB ב-constructor<br />$this-&gt;tpl = new Template(); // שאילתות DB ב-constructor<br />$this-&gt;ram_cache = new RamCache();<br />$this-&gt;cache = new Cache();<br />$this-&gt;action = new Actions();<br />$this-&gt;board = new Boards(); // שאילתות DB ב-constructor<br />$this-&gt;usergroup = new UserGroups(); // שאילתות DB ב-constructor<br />$this-&gt;member = new Members(); // שאילתות DB ב-constructor<br />$this-&gt;perm = new Permissions(); // שאילתות DB ב-constructor<br />$this-&gt;notice = new Notices();<br />$this-&gt;moderation = new Moderation();<br />$this-&gt;phrase = new Phrases(); // שאילתות DB ב-constructor<br />// ... ועוד מחלקות<br />}<br />```</p>
<p>**כל 20+ המחלקות נטענות בכל בקשה**, גם בדפים שלא משתמשים בפורום. כל constructor מריץ שאילתות לבסיס הנתונים.</p>
<p>**פתרון מוצע - Lazy Loading:**</p>
<p>```php<br />class wpForo {<br />private $instances = [];</p>
<p>public function __get($name) {<br />if (!isset($this-&gt;instances)) {<br />$class_map = ;<br />if (isset($class_map)) {<br />$class = 'wpforo\\classes\\' . $class_map;<br />$this-&gt;instances = new $class();<br />}<br />}<br />return $this-&gt;instances ?? null;<br />}<br />}<br />```</p>
<p>---</p>
<p>## בעיה #6: Caching מבוסס קבצים במקום Object Cache</p>
<p>**מיקום:** functions.php שורות 2268-2305</p>
<p>**הבעיה:**</p>
<p>```php<br />$option_file = WPF()-&gt;folders . '/item/option/' . md5($option);<br />$value = maybe_unserialize( wpforo_get_file_content( $option_file ) );<br />```</p>
<p>שימוש במערכת קבצים ל-caching כאשר **Redis/Memcached object cache** זמין הוא איטי משמעותית.</p>
<p>**Benchmarks:**</p>
<p>| סוג Cache | זמן קריאה |<br />|-----------|-----------|<br />| מערכת קבצים | ~1-5ms |<br />| Redis | ~0.1-0.5ms |<br />| APCu | ~0.01-0.1ms |</p>
<p>**פתרון מוצע:**</p>
<p>```php<br />function wpforo_get_option($option) {<br />// נסה object cache קודם (Redis/Memcached)<br />$cached = wp_cache_get($option, 'wpforo_options');<br />if ($cached !== false) {<br />return $cached;<br />}</p>
<p>// Fallback לבסיס נתונים<br />$value = get_option('wpforo_' . $option);</p>
<p>// שמור ב-object cache<br />wp_cache_set($option, $value, 'wpforo_options', 3600);</p>
<p>return $value;<br />}<br />```</p>
<p>---</p>
<p>## הפתרון שלנו (MU-Plugin)</p>
<p>יצרנו תוסף Must-Use שמתקן את הבעיות בלי לשנות את קבצי הליבה של wpForo:</p>
<p>```php<br />&lt;?php<br />/**<br />* Plugin Name: wpForo Performance Fixes<br />* Description: אופטימיזציות ביצועים ל-wpForo - שורד עדכונים<br />*/</p>
<p>// תיקון #1: Cache לבדיקת בוטים<br />class WPForo_Performance_Bot_Cache {<br />private static $is_bot = null;</p>
<p>public static function is_bot() {<br />if (self::$is_bot !== null) return self::$is_bot;</p>
<p>$ua = $_SERVER ?? '';<br />if (empty($ua)) return self::$is_bot = false;</p>
<p>$ua_lower = strtolower($ua);<br />foreach ( as $bot) {<br />if (strpos($ua_lower, $bot) !== false) {<br />return self::$is_bot = true;<br />}<br />}</p>
<p>return self::$is_bot = (bool) preg_match('#(bot|crawl|spider)#i', $ua);<br />}<br />}</p>
<p>// תיקון #2: Cache סטטי ל-KSES<br />class WPForo_Performance_Kses {<br />private static $allowed_html = null;</p>
<p>public static function get_allowed_html() {<br />if (self::$allowed_html !== null) return self::$allowed_html;</p>
<p>self::$allowed_html = [<br />'a' =&gt; ,<br />'img' =&gt; ,<br />'strong' =&gt; [], 'em' =&gt; [], 'p' =&gt; [], 'br' =&gt; [],<br />// ... תגיות בסיסיות<br />];</p>
<p>return self::$allowed_html;<br />}<br />}</p>
<p>// תיקון #3: החלפת deep_merge בפונקציה מהירה<br />function wpforo_fast_deep_merge($default, $current = []) {<br />return array_replace_recursive($default, $current);<br />}</p>
<p>// תיקון #4: דילוג על אתחול כבד בדפים שאינם פורום<br />add_filter('wpforo_load_assets', function($load) {<br />$uri = $_SERVER ?? '';<br />if (strpos($uri, '/community/') === false) {<br />return false;<br />}<br />return $load;<br />}, 1);</p>
<p>// תיקון #5: אפשור LiteSpeed Cache למבקרים אנונימיים<br />add_action('send_headers', function() {<br />if (is_user_logged_in()) return;<br />if (strpos($_SERVER ?? '', '/community/') === false) return;<br />if ($_SERVER !== 'GET') return;</p>
<p>header_remove('Cache-Control');<br />header('Cache-Control: public, max-age=1800');<br />}, 999);<br />```</p>
<p>---</p>
<p>## תוצאות</p>
<p>| מדד | לפני | אחרי | שיפור |<br />|-----|------|------|-------|<br />| TTFB | 0.94s | 0.09s | **90% מהיר יותר** |<br />| שאילתות DB | 50+ | ~10 | **80% פחות** |<br />| סטטוס Cache | miss | hit | מופעל |</p>
<p>---</p>
<p>## סיכום המלצות</p>
<p>| עדיפות | בעיה | פתרון |<br />|--------|------|-------|<br />| קריטי | wpforo_deep_merge() O(n^5) | שימוש ב-array_replace_recursive() |<br />| קריטי | אין lazy loading | מימוש __get() magic method |<br />| גבוה | wpforo_is_bot() ללא cache | משתנה סטטי |<br />| גבוה | wpforo_phrase() פעולות מחרוזות | חישוב מקדים של מפתחות |<br />| בינוני | wpforo_kses() מערכים | cache סטטי |<br />| בינוני | cache מבוסס קבצים | שימוש ב-wp_cache_*() API |</p>
<p>---</p>
<p>אני מקווה שהמידע הזה יעזור לאחרים שסובלים מבעיות ביצועים עם wpForo!</p>
<p>**צוות הפיתוח**<br />hmeonot.org.il<br />ישראל</p>
<p>---</p>
<p>## נספחים</p>
<p>1. דוח ניתוח מלא: wpforo_deep_analysis.md<br />2. תוסף MU-Plugin שלנו: wpforo-performance-fixes.php</p>
<p>---</p>
<p>*הדוח הזה נוצר במהלך ביקורת ביצועים ב-13 בדצמבר 2025*</p>
<p>&nbsp;</p>
<p>&lt;?php<br />/**<br />* Plugin Name: wpForo Performance Fixes<br />* Description: Performance optimizations for wpForo plugin - survives updates<br />* Version: 1.0.0<br />* Author: Claude Code Security Audit<br />* Author URI:<span> </span><a class="wpforo-auto-embeded-link" href="https://claude.ai/" target="_blank" rel="nofollow noopener">https://claude.ai</a><br />*<br />* FIXES IMPLEMENTED:<br />* 1. wpforo_is_bot() - Cache result per request (was: regex on every call)<br />* 2. wpforo_phrase() - Optimized string operations (was: addslashes+strtolower+trim on each call)<br />* 3. wpforo_kses() - Static cache for allowed tags/attrs (was: rebuilt on every call)<br />* 4. wpforo_deep_merge() - Use array_replace_recursive (was: O(n^5) nested loops)<br />* 5. Conditional loading - Skip heavy init on non-forum pages<br />*<br />* Created: 2025-12-13 by Claude Code<br />* For: hmeonot.org.il<br />*/</p>
<p>if (!defined('ABSPATH')) {<br />exit;<br />}</p>
<p>/**<br />* Performance Fix #1: Cache is_bot check<br />* Original: Regex with ~40 alternatives checked on EVERY request<br />* Fix: Check once, store in static variable<br />*/<br />class WPForo_Performance_Bot_Cache {<br />private static $is_bot = null;</p>
<p>public static function is_bot() {<br />if (self::$is_bot !== null) {<br />return self::$is_bot;<br />}</p>
<p>$user_agent = isset($_SERVER) ? $_SERVER : '';</p>
<p>if (empty($user_agent)) {<br />self::$is_bot = false;<br />return false;<br />}</p>
<p>// Simplified check - most common bots first (short-circuit evaluation)<br />$common_bots = array('googlebot', 'bingbot', 'yandex', 'baiduspider', 'facebookexternalhit');<br />$ua_lower = strtolower($user_agent);</p>
<p>foreach ($common_bots as $bot) {<br />if (strpos($ua_lower, $bot) !== false) {<br />self::$is_bot = true;<br />return true;<br />}<br />}</p>
<p>// Full check only if common bots not found<br />$bots = 'bot|crawl|slurp|spider|mediapartners|adsbot|lighthouse|pagespeed|gtmetrix';<br />self::$is_bot = (bool) preg_match('#(' . $bots . ')#i', $user_agent);</p>
<p>return self::$is_bot;<br />}</p>
<p>public static function reset() {<br />self::$is_bot = null;<br />}<br />}</p>
<p>/**<br />* Performance Fix #2: Optimized phrase lookup<br />* Original: addslashes(strtolower(trim())) on every call<br />* Fix: Pre-process phrase keys, use static lookup table<br />*/<br />class WPForo_Performance_Phrases {<br />private static $phrases_cache = null;<br />private static $phrases_keys = array();</p>
<p>/**<br />* Initialize phrases cache from wpForo<br />*/<br />public static function init() {<br />if (self::$phrases_cache !== null) {<br />return;<br />}</p>
<p>// Only init if wpForo is loaded<br />if (!function_exists('WPF') || !is_object(WPF()) || !isset(WPF()-&gt;phrase)) {<br />return;<br />}</p>
<p>// Get phrases from wpForo<br />if (isset(WPF()-&gt;phrase-&gt;__phrases) &amp;&amp; is_array(WPF()-&gt;phrase-&gt;__phrases)) {<br />self::$phrases_cache = WPF()-&gt;phrase-&gt;__phrases;<br />// Pre-compute lowercase keys for faster lookup<br />foreach (self::$phrases_cache as $key =&gt; $value) {<br />self::$phrases_keys = $key;<br />}<br />}<br />}</p>
<p>/**<br />* Fast phrase lookup<br />*/<br />public static function get($phrase) {<br />if (self::$phrases_cache === null) {<br />self::init();<br />}</p>
<p>if (self::$phrases_cache === null) {<br />return $phrase; // Fallback<br />}</p>
<p>// Fast lookup with pre-computed key<br />$key = strtolower(trim($phrase));</p>
<p>if (isset(self::$phrases_keys)) {<br />$original_key = self::$phrases_keys;<br />if (isset(self::$phrases_cache)) {<br />return self::$phrases_cache;<br />}<br />}</p>
<p>return $phrase;<br />}<br />}</p>
<p>/**<br />* Performance Fix #3: Static cache for KSES allowed tags<br />* Original: Arrays with 200+ elements rebuilt on EVERY call<br />* Fix: Build once, cache statically<br />*/<br />class WPForo_Performance_Kses {<br />private static $allowed_html = null;<br />private static $svg_tags = null;<br />private static $svg_attrs = null;</p>
<p>/**<br />* Get cached allowed HTML tags<br />*/<br />public static function get_allowed_html() {<br />if (self::$allowed_html !== null) {<br />return self::$allowed_html;<br />}</p>
<p>// Basic HTML tags (much smaller list than original)<br />self::$allowed_html = array(<br />'a' =&gt; array('href' =&gt; true, 'title' =&gt; true, 'target' =&gt; true, 'rel' =&gt; true, 'class' =&gt; true),<br />'abbr' =&gt; array('title' =&gt; true),<br />'b' =&gt; array(),<br />'blockquote' =&gt; array('cite' =&gt; true, 'class' =&gt; true),<br />'br' =&gt; array(),<br />'code' =&gt; array('class' =&gt; true),<br />'del' =&gt; array('datetime' =&gt; true),<br />'div' =&gt; array('class' =&gt; true, 'id' =&gt; true, 'style' =&gt; true),<br />'em' =&gt; array(),<br />'h1' =&gt; array('class' =&gt; true), 'h2' =&gt; array('class' =&gt; true), 'h3' =&gt; array('class' =&gt; true),<br />'h4' =&gt; array('class' =&gt; true), 'h5' =&gt; array('class' =&gt; true), 'h6' =&gt; array('class' =&gt; true),<br />'hr' =&gt; array(),<br />'i' =&gt; array('class' =&gt; true),<br />'img' =&gt; array('src' =&gt; true, 'alt' =&gt; true, 'title' =&gt; true, 'width' =&gt; true, 'height' =&gt; true, 'class' =&gt; true, 'loading' =&gt; true),<br />'li' =&gt; array('class' =&gt; true),<br />'ol' =&gt; array('class' =&gt; true),<br />'p' =&gt; array('class' =&gt; true, 'style' =&gt; true),<br />'pre' =&gt; array('class' =&gt; true),<br />'q' =&gt; array('cite' =&gt; true),<br />'s' =&gt; array(),<br />'span' =&gt; array('class' =&gt; true, 'style' =&gt; true),<br />'strong' =&gt; array(),<br />'sub' =&gt; array(),<br />'sup' =&gt; array(),<br />'table' =&gt; array('class' =&gt; true),<br />'tbody' =&gt; array(),<br />'td' =&gt; array('class' =&gt; true, 'colspan' =&gt; true, 'rowspan' =&gt; true),<br />'th' =&gt; array('class' =&gt; true, 'colspan' =&gt; true, 'rowspan' =&gt; true),<br />'thead' =&gt; array(),<br />'tr' =&gt; array('class' =&gt; true),<br />'u' =&gt; array(),<br />'ul' =&gt; array('class' =&gt; true),<br />);</p>
<p>return self::$allowed_html;<br />}</p>
<p>/**<br />* Get cached SVG tags (only when needed)<br />*/<br />public static function get_svg_tags() {<br />if (self::$svg_tags !== null) {<br />return self::$svg_tags;<br />}</p>
<p>// Core SVG tags only<br />self::$svg_tags = array(<br />'svg' =&gt; array('class' =&gt; true, 'width' =&gt; true, 'height' =&gt; true, 'viewBox' =&gt; true, 'fill' =&gt; true, 'xmlns' =&gt; true),<br />'path' =&gt; array('d' =&gt; true, 'fill' =&gt; true, 'stroke' =&gt; true, 'stroke-width' =&gt; true),<br />'circle' =&gt; array('cx' =&gt; true, 'cy' =&gt; true, 'r' =&gt; true, 'fill' =&gt; true, 'stroke' =&gt; true),<br />'rect' =&gt; array('x' =&gt; true, 'y' =&gt; true, 'width' =&gt; true, 'height' =&gt; true, 'fill' =&gt; true, 'rx' =&gt; true, 'ry' =&gt; true),<br />'g' =&gt; array('fill' =&gt; true, 'transform' =&gt; true),<br />'polygon' =&gt; array('points' =&gt; true, 'fill' =&gt; true),<br />'polyline' =&gt; array('points' =&gt; true, 'fill' =&gt; true, 'stroke' =&gt; true),<br />'line' =&gt; array('x1' =&gt; true, 'y1' =&gt; true, 'x2' =&gt; true, 'y2' =&gt; true, 'stroke' =&gt; true),<br />'text' =&gt; array('x' =&gt; true, 'y' =&gt; true, 'fill' =&gt; true, 'font-size' =&gt; true),<br />'use' =&gt; array('href' =&gt; true, 'xlink:href' =&gt; true),<br />'defs' =&gt; array(),<br />'clipPath' =&gt; array('id' =&gt; true),<br />);</p>
<p>return self::$svg_tags;<br />}</p>
<p>/**<br />* Get allowed HTML with SVG<br />*/<br />public static function get_allowed_html_with_svg() {<br />return array_merge(self::get_allowed_html(), self::get_svg_tags());<br />}<br />}</p>
<p>/**<br />* Performance Fix #4: Replace deep_merge with native function<br />* Original: 5 levels of nested foreach loops - O(n^5)<br />* Fix: Use PHP's array_replace_recursive - O(n)<br />*/<br />function wpforo_fast_deep_merge($default, $current = array()) {<br />if (!is_array($default)) {<br />return $current;<br />}<br />if (!is_array($current)) {<br />return $default;<br />}<br />return array_replace_recursive($default, $current);<br />}</p>
<p>/**<br />* Performance Fix #5: Skip forum init on non-forum pages<br />*/<br />class WPForo_Performance_Conditional_Loading {<br />private static $is_forum_page = null;</p>
<p>public static function is_forum_page() {<br />if (self::$is_forum_page !== null) {<br />return self::$is_forum_page;<br />}</p>
<p>// Check if this is a forum-related request<br />$request_uri = isset($_SERVER) ? $_SERVER : '';</p>
<p>// Get forum base slug<br />$forum_slug = 'community'; // Default, can be overridden<br />if (function_exists('wpforo_setting') &amp;&amp; is_callable('wpforo_setting')) {<br />$forum_slug = wpforo_setting('general', 'forum_slug') ?: 'community';<br />}</p>
<p>// Check URL patterns<br />$forum_patterns = array(<br />'/' . $forum_slug . '/',<br />'/' . $forum_slug . '?',<br />'/wpforo/',<br />);</p>
<p>foreach ($forum_patterns as $pattern) {<br />if (strpos($request_uri, $pattern) !== false) {<br />self::$is_forum_page = true;<br />return true;<br />}<br />}</p>
<p>// Check if it's an AJAX request for wpForo<br />if (defined('DOING_AJAX') &amp;&amp; DOING_AJAX) {<br />$action = isset($_REQUEST) ? $_REQUEST : '';<br />if (strpos($action, 'wpforo') !== false) {<br />self::$is_forum_page = true;<br />return true;<br />}<br />}</p>
<p>self::$is_forum_page = false;<br />return false;<br />}<br />}</p>
<p>/**<br />* Hook into wpForo to apply fixes<br />*/<br />add_action('plugins_loaded', 'wpforo_performance_fixes_init', 1);</p>
<p>function wpforo_performance_fixes_init() {<br />// Override is_bot function early<br />if (!function_exists('wpforo_is_bot_cached')) {<br />function wpforo_is_bot_cached() {<br />return WPForo_Performance_Bot_Cache::is_bot();<br />}<br />}</p>
<p>// Initialize phrase cache after wpForo loads<br />add_action('wpforo_after_init', function() {<br />WPForo_Performance_Phrases::init();<br />}, 1);<br />}</p>
<p>/**<br />* Add filter to skip heavy operations on non-forum pages<br />*/<br />add_filter('wpforo_load_assets', function($load) {<br />if (!WPForo_Performance_Conditional_Loading::is_forum_page()) {<br />return false; // Don't load assets on non-forum pages<br />}<br />return $load;<br />}, 1);</p>
<p>/**<br />* Reduce database queries on non-forum pages<br />*/<br />add_filter('wpforo_init_options', function($options) {<br />if (!WPForo_Performance_Conditional_Loading::is_forum_page()) {<br />// Return minimal options for non-forum pages<br />return array();<br />}<br />return $options;<br />}, 1);</p>
<p>/**<br />* Debug/logging (disabled by default)<br />*/<br />function wpforo_performance_log($message) {<br />if (defined('WPFORO_PERFORMANCE_DEBUG') &amp;&amp; WPFORO_PERFORMANCE_DEBUG) {<br />error_log(' ' . $message);<br />}<br />}</p>
<p>/**<br />* Performance metrics<br />*/<br />class WPForo_Performance_Metrics {<br />private static $start_time = null;<br />private static $metrics = array();</p>
<p>public static function start() {<br />self::$start_time = microtime(true);<br />}</p>
<p>public static function mark($label) {<br />if (self::$start_time === null) {<br />return;<br />}<br />self::$metrics = microtime(true) - self::$start_time;<br />}</p>
<p>public static function get_metrics() {<br />return self::$metrics;<br />}<br />}</p>
<p>// Start tracking on init<br />add_action('init', array('WPForo_Performance_Metrics', 'start'), 0);</p>
<p>/**<br />* Performance Fix #6: Enable LiteSpeed Cache for forum pages<br />* Original: wpForo sends no-cache headers, preventing caching<br />* Fix: Override headers for anonymous users viewing public forum pages<br />*/<br />class WPForo_Performance_LiteSpeed_Cache {</p>
<p>public static function init() {<br />// Only if LiteSpeed Cache is active<br />if (!defined('LSCWP_V') &amp;&amp; !class_exists('LiteSpeed_Cache')) {<br />return;<br />}</p>
<p>// Hook early to set cacheable before wpForo blocks it<br />add_action('wp', array(__CLASS__, 'maybe_enable_cache'), 1);</p>
<p>// Remove wpForo's no-cache headers for anonymous users<br />add_action('send_headers', array(__CLASS__, 'modify_headers'), 999);</p>
<p>// Tell LiteSpeed this page is cacheable<br />add_action('litespeed_init', array(__CLASS__, 'litespeed_init'), 1);<br />}</p>
<p>public static function maybe_enable_cache() {<br />// Only cache for anonymous users<br />if (is_user_logged_in()) {<br />return;<br />}</p>
<p>// Only on forum pages<br />if (!WPForo_Performance_Conditional_Loading::is_forum_page()) {<br />return;<br />}</p>
<p>// Check if viewing public content (not posting, editing, etc.)<br />if ($_SERVER !== 'GET') {<br />return;<br />}</p>
<p>// Don't cache search results<br />$request_uri = isset($_SERVER) ? $_SERVER : '';<br />if (strpos($request_uri, 'wpforo-search') !== false || strpos($request_uri, '?s=') !== false) {<br />return;<br />}</p>
<p>// Enable LiteSpeed cache for this page<br />if (class_exists('LiteSpeed\Core') || class_exists('LiteSpeed_Cache')) {<br />// LiteSpeed Cache 3.x and later<br />do_action('litespeed_control_set_cacheable');<br />do_action('litespeed_tag_add', 'wpforo');<br />}<br />}</p>
<p>public static function modify_headers() {<br />// Only for anonymous users on forum pages<br />if (is_user_logged_in()) {<br />return;<br />}</p>
<p>if (!WPForo_Performance_Conditional_Loading::is_forum_page()) {<br />return;<br />}</p>
<p>if ($_SERVER !== 'GET') {<br />return;<br />}</p>
<p>// Remove any existing cache-control headers that block caching<br />if (!headers_sent()) {<br />header_remove('Cache-Control');<br />header_remove('Pragma');<br />header_remove('Expires');</p>
<p>// Set cache-friendly headers (30 minutes TTL)<br />header('Cache-Control: public, max-age=1800');<br />header('X-LiteSpeed-Cache-Control: public, max-age=1800');<br />}<br />}</p>
<p>public static function litespeed_init() {<br />// Register wpforo tag for cache purging<br />if (has_action('litespeed_tag_add')) {<br />// When a new post is created in wpForo, purge the forum cache<br />add_action('wpforo_after_add_post', function() {<br />do_action('litespeed_purge', 'wpforo');<br />});</p>
<p>add_action('wpforo_after_add_topic', function() {<br />do_action('litespeed_purge', 'wpforo');<br />});<br />}<br />}<br />}</p>
<p>// Initialize LiteSpeed Cache support<br />add_action('init', array('WPForo_Performance_LiteSpeed_Cache', 'init'), 1);</p>
<p>/**<br />* Performance Fix #7: Reduce wpForo's aggressive session/cookie checks<br />* Original: Sets cookies and sessions on every page load<br />* Fix: Only set when needed (logged in users or posting)<br />*/<br />add_action('init', function() {<br />// Skip session start for anonymous GET requests on forum<br />if (!is_user_logged_in() &amp;&amp;<br />isset($_SERVER) &amp;&amp; $_SERVER === 'GET' &amp;&amp;<br />WPForo_Performance_Conditional_Loading::is_forum_page()) {</p>
<p>// Prevent wpForo from starting unnecessary sessions<br />add_filter('wpforo_start_session', '__return_false');<br />}<br />}, 0);</p>
<p>/**<br />* Admin notice showing the fix is active<br />*/<br />add_action('admin_notices', function() {<br />if (!current_user_can('manage_options')) {<br />return;<br />}</p>
<p>// Only show on wpForo pages<br />$screen = get_current_screen();<br />if (!$screen || strpos($screen-&gt;id, 'wpforo') === false) {<br />return;<br />}</p>
<p>echo '&lt;div class="notice notice-info is-dismissible"&gt;';<br />echo '&lt;p&gt;&lt;strong&gt;wpForo Performance Fixes Active&lt;/strong&gt; - ';<br />echo 'This MU-plugin optimizes wpForo performance. ';<br />echo '&lt;a href="https://github.com/gVectors/wpforo" target="_blank"&gt;Report improvements&lt;/a&gt;&lt;/p&gt;';<br />echo '&lt;/div&gt;';<br />});</p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>hmeonot</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/wpforo-performance-analysis-report-critical-bottlenecks-found-0-94s-ttfb/</guid>
                    </item>
				                    <item>
                        <title>Specific forum category and forum user access management</title>
                        <link>https://gvectors.com/forum/general-questions/specific-forum-category-and-forum-user-access-management/</link>
                        <pubDate>Sun, 14 Sep 2025 06:27:10 +0000</pubDate>
                        <description><![CDATA[Hello.
&nbsp;
In my forum, I have many categories and forums for different subjects and I would like to assign different access rights for different user groups for different forum categor...]]></description>
                        <content:encoded><![CDATA[<p>Hello.</p>
<p>&nbsp;</p>
<p>In my forum, I have many categories and forums for different subjects and I would like to assign different access rights for different user groups for different forum categories and forums under the same category.</p>
<p>&nbsp;</p>
<p>For example;</p>
<p>user group A1 can access Category A and all forums under Category A.</p>
<p>user group A2 can access Category A, but only can access specific forums under Category A not all forums.</p>
<p>&nbsp;</p>
<p>I spent some time to study all user group roles and rights, but I still can not figure out how I can do this.</p>
<p>&nbsp;</p>
<p>Is it possible?</p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>IKBONG JANG</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/specific-forum-category-and-forum-user-access-management/</guid>
                    </item>
				                    <item>
                        <title>Global Wordpress Search</title>
                        <link>https://gvectors.com/forum/general-questions/global-wordpress-search/</link>
                        <pubDate>Tue, 02 Apr 2024 00:08:10 +0000</pubDate>
                        <description><![CDATA[wpForo is one of the (if not the) best forum plugins for Wordpress but I can&#039;t commit since no search plugin offers the ability to ALSO search wpForo.  In reality when you go to a website yo...]]></description>
                        <content:encoded><![CDATA[<p>wpForo is one of the (if not the) best forum plugins for Wordpress but I can't commit since no search plugin offers the ability to ALSO search wpForo.  In reality when you go to a website you click on search when you are looking for something and you type your keywords in.  You do not go to the website search and try and then go to the forum of the same website and try..  no one does that.</p>
<p>PLEASE PLEASE work with someone like Ivory Search or anyone to include the ability to search wpForo with the rest of the wordpress plugins.  I desperatly would LOVE to have wpForo as part of my forum solution but this search thing is killing me.  Do you know if its even in the playbook in the future to allow this to happen?</p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>Dennis Hosang</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/global-wordpress-search/</guid>
                    </item>
				                    <item>
                        <title>User Access Shortcodes not working in WP-Foro</title>
                        <link>https://gvectors.com/forum/general-questions/user-access-shortcodes-not-working-in-wp-foro/</link>
                        <pubDate>Sat, 02 Mar 2024 04:36:07 +0000</pubDate>
                        <description><![CDATA[Hi Sir,
 
Hope you are fine and well, I have tested your plugin in one of my domain, and I have installed a Plugin mentioned below;
URL:
which provides a bbcode variable to protect requir...]]></description>
                        <content:encoded><![CDATA[<p>Hi Sir,</p>
<p> </p>
<p>Hope you are fine and well, I have tested your plugin in one of my domain, and I have installed a Plugin mentioned below;</p>
<p>URL: https://wordpress.org/plugins/user-access-shortcodes/</p>
<p>which provides a bbcode variable to protect required area of post from guest. But short code of this plugin is not working on your forum. Please fix that issue or make your forum plugin compatible with this plugin so I can use your wp-Foro </p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>Belinux</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/user-access-shortcodes-not-working-in-wp-foro/</guid>
                    </item>
				                    <item>
                        <title>Question about dislike button</title>
                        <link>https://gvectors.com/forum/general-questions/question-about-dislike-button/</link>
                        <pubDate>Thu, 23 Mar 2023 09:44:48 +0000</pubDate>
                        <description><![CDATA[I tried to register several times at the default support forum, but never get a verfification email, so i need to add my question here.
Its possible to hide the dislike button, but at the p...]]></description>
                        <content:encoded><![CDATA[<p>I tried to register several times at the default support forum, but never get a verfification email, so i need to add my question here.</p>
<p>Its possible to hide the dislike button, but at the profile page there is a section that show the counted dislikes. since this has no seperate class - how can i hide/disable this?</p>
<p>And btw, what can i do to get access to the main forum, is there a registration bug that no confirmation email is sent?</p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>Christian Pust</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/question-about-dislike-button/</guid>
                    </item>
				                    <item>
                        <title>User Fields addon - Subscription Button</title>
                        <link>https://gvectors.com/forum/general-questions/user-fields-addon-subscription-button/</link>
                        <pubDate>Mon, 21 Nov 2022 09:31:21 +0000</pubDate>
                        <description><![CDATA[Hello everybody,
A member with &quot; No Access&quot; could view and subscribe to all Private Forum Topics when clicking the subscribe button on his user profile.

 
This subscribe button can be d...]]></description>
                        <content:encoded><![CDATA[<p>Hello everybody,</p>
<p>A member with " No Access" could view and subscribe to all <strong>Private Forum Topics</strong> when clicking the subscribe button on his user profile.</p>
6465
<p> </p>
<p>This subscribe button can be disabled via wpForo User Custom Fields add-on however is there another option that a member could only subscribe to his/her permitted forums?</p>
<p>Please also note that even after ticking to subscribe to all private forum topics,  members could not view the posts in the private forums. </p>
<p>Cheers</p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>Engin Aksüt</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/user-fields-addon-subscription-button/</guid>
                    </item>
				                    <item>
                        <title>Add topic button on homepage forum doens&#039;t work.</title>
                        <link>https://gvectors.com/forum/general-questions/add-topic-button-on-homepage-forum-doenst-work/</link>
                        <pubDate>Wed, 19 Oct 2022 10:11:26 +0000</pubDate>
                        <description><![CDATA[Hi,since a few days the add topic button on the homepage of the forum doesn&#039;t work anymore.It works on subforums, just not om the main page.If I switch to the new WPforo theme, it works agai...]]></description>
                        <content:encoded><![CDATA[<p>Hi,<br /><br />since a few days the add topic button on the homepage of the forum doesn't work anymore.<br /><br />It works on subforums, just not om the main page.<br /><br />If I switch to the new WPforo theme, it works again, when I switch back to the Classic theme, it stops working. It seems to have something to do with the four icons where you can select "latest-populair-solved-unsolved" , but I can't find how I can get rid of those icons.</p>
<p>Anyone a clue?</p>
6416
<p> </p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>stookforum</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/add-topic-button-on-homepage-forum-doenst-work/</guid>
                    </item>
				                    <item>
                        <title>On the forum home page, how do I hide categories?</title>
                        <link>https://gvectors.com/forum/general-questions/on-the-forum-home-page-how-do-i-hide-categories/</link>
                        <pubDate>Sun, 12 Dec 2021 09:09:03 +0000</pubDate>
                        <description><![CDATA[hey,
On the forum home page, how do I hide categories?Do you have any way to hide the categories and boards from being displayed on the homepage?Could there be a plugin that displays forum ...]]></description>
                        <content:encoded><![CDATA[<p>hey,</p>
<p>On the forum home page, how do I hide categories?<br />Do you have any way to hide the categories and boards from being displayed on the homepage?<br />Could there be a plugin that displays forum posts on the home page of my website<a href="https://newshungama.com/" target="_blank" rel="noopener">.</a>based on category blocks (for example, if my forum is at example.com/forum, and I want to display posts on different blocks based on forum categories/boards just as blog posts are displayed on home page based on categories).<br />Can social media login be done with a plugin? This is a popular demand, so please address it if no).</p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>lena324</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/on-the-forum-home-page-how-do-i-hide-categories/</guid>
                    </item>
				                    <item>
                        <title>&#039;no more attachments allowed today</title>
                        <link>https://gvectors.com/forum/general-questions/no-more-attachments-allowed-today/</link>
                        <pubDate>Thu, 11 Nov 2021 22:31:21 +0000</pubDate>
                        <description><![CDATA[I followed the instructions on post from TOM Aug 11 2021 - but still ( except for Admin) get the message when a registered user posts
All set to &#039;0&#039;]]></description>
                        <content:encoded><![CDATA[<p>I followed the instructions on post from TOM Aug 11 2021 - but still ( except for Admin) get the message when a registered user posts</p>
<p>All set to '0'</p>]]></content:encoded>
						                            <category domain="https://gvectors.com/forum/general-questions/">wpForo</category>                        <dc:creator>Martin Gover</dc:creator>
                        <guid isPermaLink="true">https://gvectors.com/forum/general-questions/no-more-attachments-allowed-today/</guid>
                    </item>
							        </channel>
        </rss>
		