| @@ -4,9 +4,9 @@ | ||
| 4 | 4 | * Plugin URI: https://wpforo.com |
| 5 | 5 | * Description: WordPress Forum plugin. wpForo is the only AI powered forum solution for your community. Modern design and 5 forum layouts. |
| 6 | 6 | * Author: gVectors Team |
| 7 | 7 | * Author URI: https://gvectors.com/ |
| 8 | -* Version: 3.0.9 | |
| 8 | +* Version: 3.2.0 | |
| 9 | 9 | * Requires at least: 5.2 |
| 10 | 10 | * Requires PHP: 7.1 |
| 11 | 11 | * Text Domain: wpforo |
| 12 | 12 | * Domain Path: /languages |
| @@ -13,9 +13,9 @@ | ||
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | 15 | namespace wpforo; |
| 16 | 16 | |
| 17 | -define( 'WPFORO_VERSION', '3.0.9' ); | |
| 17 | +define( 'WPFORO_VERSION', '3.2.0' ); | |
| 18 | 18 | |
| 19 | 19 | //Exit if accessed directly |
| 20 | 20 | if( ! defined( 'ABSPATH' ) ) exit; |
| 21 | 21 | |
| @@ -20,9 +20,10 @@ | ||
| 20 | 20 | if( ! defined( 'ABSPATH' ) ) exit; |
| 21 | 21 | |
| 22 | 22 | define( 'WPFORO_DIR', rtrim( plugin_dir_path( __FILE__ ), '/' ) ); |
| 23 | 23 | define( 'WPFORO_URL', rtrim( plugins_url( '', __FILE__ ), '/' ) ); |
| 24 | -define( 'WPFORO_BASENAME', plugin_basename( __FILE__ ) ); //wpforo/wpforo.php | |
| 24 | +define( 'WPFORO_BASENAME', plugin_basename( __FILE__ ) ); // "wpforo/wpforo.php" | |
| 25 | +define( 'WPFORO_BASEFOLDER', basename(WPFORO_DIR) ); // "wpforo" | |
| 25 | 26 | |
| 26 | 27 | require_once WPFORO_DIR . "/autoload.php"; |
| 27 | 28 | |
| 28 | 29 | use stdClass; |
| @@ -46,8 +47,9 @@ | ||
| 46 | 47 | use wpforo\classes\Moderation; |
| 47 | 48 | use wpforo\classes\Notices; |
| 48 | 49 | use wpforo\classes\Permissions; |
| 49 | 50 | use wpforo\classes\Phrases; |
| 51 | +use wpforo\classes\PluginsOrdering; | |
| 50 | 52 | use wpforo\classes\PostMeta; |
| 51 | 53 | use wpforo\classes\Posts; |
| 52 | 54 | use wpforo\classes\RamCache; |
| 53 | 55 | use wpforo\classes\SEO; |
| @@ -52,17 +54,20 @@ | ||
| 52 | 54 | use wpforo\classes\RamCache; |
| 53 | 55 | use wpforo\classes\SEO; |
| 54 | 56 | use wpforo\classes\Settings; |
| 55 | 57 | use wpforo\classes\TaskManager; |
| 58 | +use wpforo\classes\EmailQueue; | |
| 56 | 59 | use wpforo\classes\Template; |
| 57 | 60 | use wpforo\classes\Topics; |
| 61 | +use wpforo\classes\UserGroups; | |
| 58 | 62 | use wpforo\classes\VectorStorageManager; |
| 59 | -use wpforo\classes\UserGroups; | |
| 60 | 63 | use wpforo\modules\bookmarks\Bookmarks; |
| 61 | 64 | use wpforo\modules\reactions\Reactions; |
| 62 | 65 | use wpforo\modules\revisions\Revisions; |
| 63 | 66 | use wpforo\modules\subscriptions\Subscriptions; |
| 64 | 67 | |
| 68 | +new PluginsOrdering( WPFORO_BASENAME ); | |
| 69 | + | |
| 65 | 70 | final class wpforo { |
| 66 | 71 | private static $_instance = null; |
| 67 | 72 | |
| 68 | 73 | /** @var wpdb * */ |
| @@ -79,8 +84,9 @@ | ||
| 79 | 84 | 'logs', |
| 80 | 85 | 'follows', |
| 81 | 86 | 'bookmarks', |
| 82 | 87 | 'accesses', |
| 88 | + 'email_queue', | |
| 83 | 89 | ]; |
| 84 | 90 | public $_tables = [ |
| 85 | 91 | 'activity', |
| 86 | 92 | 'ai_cache', |
| @@ -202,8 +208,10 @@ | ||
| 202 | 208 | /** @var SEO */ |
| 203 | 209 | public $seo; |
| 204 | 210 | /** @var Subscriptions */ |
| 205 | 211 | public $sbscrb; |
| 212 | + /** @var EmailQueue */ | |
| 213 | + public $email_queue; | |
| 206 | 214 | /** @var Template */ |
| 207 | 215 | public $tpl; |
| 208 | 216 | /** @var Topics */ |
| 209 | 217 | public $topic; |
| @@ -208,9 +216,9 @@ | ||
| 208 | 216 | /** @var Topics */ |
| 209 | 217 | public $topic; |
| 210 | 218 | /** @var UserGroups */ |
| 211 | 219 | public $usergroup; |
| 212 | - | |
| 220 | + | |
| 213 | 221 | public static function instance() { |
| 214 | 222 | if( is_null( self::$_instance ) ) self::$_instance = new self(); |
| 215 | 223 | |
| 216 | 224 | return self::$_instance; |
| @@ -324,9 +332,10 @@ | ||
| 324 | 332 | $this->seo = new SEO(); |
| 325 | 333 | $this->topic = new Topics(); |
| 326 | 334 | $this->reaction = new Reactions(); |
| 327 | 335 | $this->bookmark = new Bookmarks(); |
| 328 | - $this->sbscrb = new Subscriptions(); | |
| 336 | + $this->sbscrb = new Subscriptions(); | |
| 337 | + $this->email_queue = new EmailQueue(); | |
| 329 | 338 | if( wpforo_is_module_enabled( 'revisions' ) ) $this->revision = new Revisions(); |
| 330 | 339 | |
| 331 | 340 | do_action( 'wpforo_after_init_classes' ); |
| 332 | 341 | } |
| @@ -1286,9 +1295,16 @@ | ||
| 1286 | 1295 | 'period' => $period, |
| 1287 | 1296 | ]; |
| 1288 | 1297 | } elseif( $this->current_object['template'] === 'tags' ) { |
| 1289 | 1298 | $current_object['items_per_page'] = wpforo_setting( 'tags', 'per_page' ); |
| 1299 | + // Tag sort: whitelist the URL key, then map to orderby/order. Never pass raw input to get_tags(). | |
| 1300 | + $tag_sort_map = [ 'count' => [ 'count', 'DESC' ], 'az' => [ 'tag', 'ASC' ], 'za' => [ 'tag', 'DESC' ] ]; | |
| 1301 | + $tag_sort_key = sanitize_key( (string) wpfval( $_GET, 'wpf_tag_sort' ) ); | |
| 1302 | + if( ! isset( $tag_sort_map[ $tag_sort_key ] ) ) $tag_sort_key = 'count'; | |
| 1303 | + $current_object['tag_sort'] = $tag_sort_key; | |
| 1290 | 1304 | $args = [ |
| 1305 | + 'orderby' => $tag_sort_map[ $tag_sort_key ][0], | |
| 1306 | + 'order' => $tag_sort_map[ $tag_sort_key ][1], | |
| 1291 | 1307 | 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'], |
| 1292 | 1308 | 'row_count' => $current_object['items_per_page'], |
| 1293 | 1309 | ]; |
| 1294 | 1310 | $current_object['tags'] = $this->topic->get_tags( $args, $current_object['items_count'] ); |