Changeset 3380394
- Timestamp:
- 10/18/2025 06:08:15 AM (5 weeks ago)
- Location:
- magical-posts-display/trunk
- Files:
-
- 9 added
- 26 edited
-
README.txt (modified) (3 diffs)
-
admin/admin-page/admin-info.php (modified) (5 diffs)
-
admin/admin-page/admin-page.php (modified) (2 diffs)
-
admin/admin-page/welcome-page.php (modified) (2 diffs)
-
admin/extra-function.php (modified) (1 diff)
-
admin/src/cmb2/includes/CMB2.php (modified) (79 diffs)
-
assets/css/admin-style.css (modified) (7 diffs)
-
assets/css/mgadmin-page.css (modified) (1 diff)
-
assets/css/mp-style.css (modified) (3 diffs)
-
assets/js/main.js (modified) (1 diff)
-
assets/js/mgpd-premium-features.js (added)
-
composer.json (modified) (1 diff)
-
file-include.php (modified) (5 diffs)
-
includes/blocks/posts-tab.php (modified) (1 diff)
-
includes/class-ajax-handler.php (added)
-
includes/class-assets-manager.php (added)
-
includes/class-error-checker.php (added)
-
includes/class-hooks-handler.php (added)
-
includes/elementor/elementor-main.php (modified) (3 diffs)
-
includes/elementor/widgets/advanced-posts-grid1.php (modified) (1 diff)
-
includes/elementor/widgets/advanced-posts-grid2.php (modified) (1 diff)
-
includes/elementor/widgets/advanced-posts-img-grid.php (modified) (39 diffs)
-
includes/elementor/widgets/posts-carousel.php (modified) (1 diff)
-
includes/elementor/widgets/posts-cat.php (modified) (1 diff)
-
includes/elementor/widgets/posts-grid.php (modified) (88 diffs)
-
includes/elementor/widgets/posts-list.php (modified) (1 diff)
-
includes/elementor/widgets/posts-slider.php (modified) (4 diffs)
-
includes/elementor/widgets/posts-tab.php (modified) (1 diff)
-
includes/elementor/widgets/posts-ticker.php (modified) (1 diff)
-
includes/mp-posts-function.php (modified) (2 diffs)
-
includes/traits (added)
-
includes/traits/Advanced_Media_Trait.php (added)
-
includes/traits/Premium_Features_Trait.php (added)
-
includes/traits/SVG_Icons_Trait.php (added)
-
magical-posts-display.php (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
magical-posts-display/trunk/README.txt
r3334686 r3380394 3 3 Donate link: https://wpthemespace.com/donation 4 4 Tags: post display, Page display, custom Post, elementor widget, post slider 5 Requires at least: 5.05 Requires at least: 6.0 6 6 Tested up to: 6.8 7 7 Stable tag: trunk … … 57 57 <li><strong>All options show hide features. </strong></li> 58 58 <li><strong>User-friendly Editor.</strong></li> 59 <li><strong>Ajax Loadmore button.</strong></li> 60 <li><strong>Ajax Categories filter.</strong></li> 59 61 60 62 </ul> … … 137 139 138 140 == Changelog == 141 142 = 1.2.54 = 143 * Enhanced Security: Added comprehensive nonce verification and input sanitization across all AJAX handlers 144 * Premium Features: Reading Time, View Count, and Social Share Buttons 145 * Code Quality: Refactored AJAX methods following WordPress coding standards 146 * Advanced Media Support: Video, Gallery with priority fallback system 147 * Hover Effects added: Zoom, Lift, Tilt animations for cards 148 * Categories Filter Buttons Added 149 * Improved: Better error handling and default values for AJAX requests 150 * Performance: Optimized category filtering and infinite scroll functionality 139 151 140 152 = 1.2.53 = -
magical-posts-display/trunk/admin/admin-page/admin-info.php
r3235168 r3380394 16 16 add_action('admin_notices', [__CLASS__, 'mp_display_admin_info']); 17 17 add_action('init', [__CLASS__, 'mp_display_admin_info_init']); 18 add_action('admin_notices', [__CLASS__, 'admin_notice_update_info']); 19 add_action('admin_notices', [__CLASS__, 'admin_notice_minimum_php_version']); 20 add_action('admin_notices', [__CLASS__, 'admin_notice_missing_main_plugin']); 21 add_action('init', [__CLASS__, 'elementor_notice_hide_options']); 18 22 } 19 23 … … 26 30 <div class="mge-info-hello"> 27 31 <?php 28 $addons_name = esc_html__('Magical Addons, ', 'magical-addons-for-elementor');32 $addons_name = esc_html__('Magical Posts Display, ', 'magical-posts-display'); 29 33 $current_user = wp_get_current_user(); 30 34 … … 32 36 $pricing_link = esc_url('https://wpthemespace.com/product/magical-posts-display-pro/'); 33 37 34 esc_html_e('He llo, ', 'magical-addons-for-elementor');38 esc_html_e('Hey there, ', 'magical-posts-display'); 35 39 echo esc_html($current_user->display_name); 36 40 ?> 37 41 38 <?php esc_html_e(' 👋🏻', 'magical-addons-for-elementor'); ?>42 <?php esc_html_e('�', 'magical-posts-display'); ?> 39 43 </div> 40 44 <div class="mge-info-desc"> 41 <div><?php printf(esc_html__(' Thank you for choosing Magical Posts Display! ✨ We\'re excited to share that our Pro version is now available, with all custom posts display features. Plus, Pagination, QR code, Share button, reading time, wordcount, filters,popup, lightbox and more 🔥', 'magical-addons-for-elementor'), esc_html($addons_name)); ?></div>42 <div class="mge-offer"><?php printf(esc_html__(' Upgrade to Magical Posts Display Pro today and Display your posts the way you want just $21! 🚀', 'magical-addons-for-elementor'), esc_html($addons_name)); ?></div>45 <div><?php printf(esc_html__('Ready to SUPERCHARGE your content display? 🚀 Our PRO version transforms your website with advanced post layouts, lightning-fast AJAX filters, social sharing, reading time, and 50+ premium features that drive MORE engagement! ⚡', 'magical-posts-display'), esc_html($addons_name)); ?></div> 46 <div class="mge-offer"><?php printf(esc_html__('💥 LIMITED TIME: Get PRO for just $21 and unlock UNLIMITED possibilities! Join 10,000+ happy customers! �', 'magical-posts-display'), esc_html($addons_name)); ?></div> 43 47 </div> 44 48 <div class="mge-info-actions"> 45 49 <a href="<?php echo esc_url($pro_link); ?>" target="_blank" class="button button-primary upgrade-btn"> 46 <?php esc_html_e(' Upgrade Now', 'magical-addons-for-elementor'); ?>50 <?php esc_html_e('🚀 GET PRO NOW - $21', 'magical-posts-display'); ?> 47 51 </a> 48 52 <a href="<?php echo esc_url($pricing_link); ?>" target="_blank" class="button button-primary demo-btn"> 49 <?php esc_html_e(' View Details', 'magical-addons-for-elementor'); ?>53 <?php esc_html_e('💎 See All Features', 'magical-posts-display'); ?> 50 54 </a> 51 <button class="button button-info mgad-dismiss mgade-notice-hide"><?php esc_html_e(' Dismiss this notice', 'magical-addons-for-elementor') ?></button>55 <button class="button button-info mgad-dismiss mgade-notice-hide"><?php esc_html_e('Maybe Later', 'magical-posts-display') ?></button> 52 56 </div> 53 57 </div> … … 58 62 59 63 60 64 /** 65 * Show update notice for new features 66 * 67 * @since 1.2.53 68 * @access public 69 */ 70 public static function admin_notice_update_info() 71 { 72 $hide_notice_update = get_option('mgpd_update_notice_1_2_53'); 73 if (!empty($hide_notice_update)) { 74 return; 75 } 76 77 $dismiss_url = wp_nonce_url( 78 add_query_arg('mgpd_update_hide', '1'), 79 'mgpd_update_notice', 80 '_wpnonce' 81 ); 82 ?> 83 <div class="notice notice-info is-dismissible mgpd-update-notice" style="border-left-color: #00a0d2; padding: 15px;"> 84 <h3 style="margin: 0 0 10px 0;"><?php echo esc_html__('🎉 Magical Posts Display v1.2.53 - Major Update!', 'magical-posts-display'); ?></h3> 85 <p><strong><?php echo esc_html__('What\'s New:', 'magical-posts-display'); ?></strong></p> 86 <ul style="list-style: disc; margin-left: 20px;"> 87 <li><?php echo esc_html__('✨ Premium Features: Reading Time, View Count, and Social Share Buttons', 'magical-posts-display'); ?></li> 88 <li><?php echo esc_html__('🎨 Three Display Styles: Default, Image Top, and Image Overlay positions', 'magical-posts-display'); ?></li> 89 <li><?php echo esc_html__('📹 Advanced Media Support: Video, Gallery with priority fallback system', 'magical-posts-display'); ?></li> 90 <li><?php echo esc_html__('🎭 Hover Effects: Zoom, Lift, Tilt animations for cards', 'magical-posts-display'); ?></li> 91 <li><?php echo esc_html__('🔧 AJAX Optimization: Category filtering and infinite scroll improvements', 'magical-posts-display'); ?></li> 92 <li><?php echo esc_html__('🎯 Filter Buttons: Complete styling controls in Style tab', 'magical-posts-display'); ?></li> 93 <li><?php echo esc_html__('🔒 Security: Enhanced nonce verification and sanitization', 'magical-posts-display'); ?></li> 94 <li><?php echo esc_html__('♻️ Code Quality: Refactored for better performance and maintainability', 'magical-posts-display'); ?></li> 95 </ul> 96 <p> 97 <a href="<?php echo esc_url($dismiss_url); ?>" class="button button-primary"><?php echo esc_html__('Got it, thanks!', 'magical-posts-display'); ?></a> 98 <a href="https://wpthemespace.com/product/magical-posts-display-pro/" target="_blank" class="button button-secondary" style="margin-left: 10px;"><?php echo esc_html__('Upgrade to Pro', 'magical-posts-display'); ?></a> 99 </p> 100 </div> 101 <?php 102 } 61 103 62 104 public static function mp_display_admin_info() 63 105 { 64 106 65 $hide_date = get_option('mgpd_ info_protext');107 $hide_date = get_option('mgpd_pro_infotext'); 66 108 if (!empty($hide_date)) { 67 109 $clickhide = round((time() - strtotime($hide_date)) / 24 / 60 / 60); … … 90 132 public static function mp_display_admin_info_init() 91 133 { 92 if (isset($_GET['mgrecnot']) && $_GET['mgrecnot'] == 1) { 93 update_option('mgpd_info_protext', current_time('mysql')); 94 } 134 if (isset($_GET['mgrecnot']) && absint($_GET['mgrecnot']) === 1) { 135 update_option('mgpd_pro_infotext', current_time('mysql')); 136 } 137 138 // Hide update notice 139 if (isset($_GET['mgpd_update_hide']) && absint($_GET['mgpd_update_hide']) === 1 && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'mgpd_update_notice')) { 140 update_option('mgpd_update_notice_1_2_53', 1); 141 } 142 } 143 144 /** 145 * Hide Elementor notice options handler 146 */ 147 public static function elementor_notice_hide_options() 148 { 149 // Security check with nonce verification 150 if (isset($_GET['mgelhide']) && absint($_GET['mgelhide']) === 1 && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'mgpd_hide_notice')) { 151 update_option('mgelhide9', 1); 152 } 153 } 154 155 /** 156 * Admin notice for minimum PHP version 157 * Warning when the site doesn't have a minimum required PHP version. 158 */ 159 public static function admin_notice_minimum_php_version() 160 { 161 // Check if we should show this notice 162 if (version_compare(PHP_VERSION, '5.6', '>=')) { 163 return; 164 } 165 166 if (isset($_GET['activate'])) unset($_GET['activate']); 167 168 $message = sprintf( 169 /* translators: 1: Plugin name 2: PHP 3: Required PHP version */ 170 esc_html__('"%1$s" requires "%2$s" version %3$s or greater.', 'magical-posts-display'), 171 '<strong>' . esc_html__('Magical Posts Display', 'magical-posts-display') . '</strong>', 172 '<strong>' . esc_html__('PHP', 'magical-posts-display') . '</strong>', 173 '5.6' 174 ); 175 176 printf( 177 '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', 178 wp_kses_post($message) 179 ); 180 } 181 182 /** 183 * Admin notice for missing Elementor plugin 184 * Warning when the site doesn't have Elementor installed or activated. 185 */ 186 public static function admin_notice_missing_main_plugin() 187 { 188 if (get_option('mgelhide9')) { 189 return; 190 } 191 192 // Only show on specific pages 193 global $pagenow; 194 if (!in_array($pagenow, array('plugins.php', 'admin.php'))) { 195 return; 196 } 197 198 // Don't show if Elementor is loaded 199 if (did_action('elementor/loaded')) { 200 return; 201 } 202 203 if (isset($_GET['activate'])) unset($_GET['activate']); 204 205 if (file_exists(WP_PLUGIN_DIR . '/elementor/elementor.php')) { 206 $magial_eactive_url = wp_nonce_url('plugins.php?action=activate&plugin=elementor/elementor.php&plugin_status=all&paged=1', 'activate-plugin_elementor/elementor.php'); 207 $message = sprintf( 208 /* translators: 1: Plugin name 2: Elementor 3: Elementor installation link */ 209 esc_html__('%1$s Recommended %2$s plugin, which is currently NOT RUNNING %3$s', 'magical-posts-display'), 210 '<strong>' . esc_html__('Magical Posts Display', 'magical-posts-display') . '</strong>', 211 '<strong>' . esc_html__('Elementor', 'magical-posts-display') . '</strong>', 212 '<a class="button button-primary" style="margin-left:20px" href="' . $magial_eactive_url . '">' . __('Activate Elementor', 'magical-posts-display') . '</a>' 213 ); 214 } else { 215 $magial_einstall_url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=elementor'), 'install-plugin_elementor'); 216 $message = sprintf( 217 /* translators: 1: Plugin name 2: Elementor 3: Elementor installation link */ 218 esc_html__('%1$s Recommended %2$s plugin for use all Elementor addons, which is currently NOT RUNNING %3$s', 'magical-posts-display'), 219 '<strong>' . esc_html__('Magical Posts Display', 'magical-posts-display') . '</strong>', 220 '<strong>' . esc_html__('Elementor', 'magical-posts-display') . '</strong>', 221 '<a class="button button-primary" style="margin-left:20px" href="' . $magial_einstall_url . '">' . __('Install Elementor', 'magical-posts-display') . '</a>' 222 ); 223 } 224 225 printf('<div class="notice notice-warning is-dismissible mgpd-notice"><p style="padding: 13px 0">%1$s</p></div>', wp_kses_post($message)); 95 226 } 96 227 } 97 mgpAdminInfo::init(); 228 229 // Initialize only if we're in admin and not in pro version 230 if (is_admin() && !mpd_check_plugin_active('magical-posts-display-pro/magical-posts-display-pro.php')) { 231 mgpAdminInfo::init(); 232 } -
magical-posts-display/trunk/admin/admin-page/admin-page.php
r3116993 r3380394 37 37 add_menu_page($menu_text, $menu_text, 'manage_options', 'mgpd-page', array($this, 'plugin_page'), 'dashicons-tickets-alt', 20); 38 38 39 add_submenu_page('mgpd-page', esc_html__("WelCome Page", ' gbox'), esc_html__("WelCome Page", 'gbox'), "manage_options", 'mgpd-page', array($this, 'plugin_page'));39 add_submenu_page('mgpd-page', esc_html__("WelCome Page", 'magical-posts-display' ), esc_html__("WelCome Page", 'magical-posts-display' ), "manage_options", 'mgpd-page', array($this, 'plugin_page')); 40 40 } 41 41 … … 46 46 array( 47 47 'id' => 'magical_ptab_home', 48 'title' => __('Home', 'magical- addons-for-elementor')48 'title' => __('Home', 'magical-posts-display') 49 49 ), 50 50 /*array( 51 51 'id' => 'magical_addons', 52 'title' => __( 'Addons', 'magical- addons-for-elementor')52 'title' => __( 'Addons', 'magical-posts-display' ) 53 53 )*/ 54 54 ); -
magical-posts-display/trunk/admin/admin-page/welcome-page.php
r3170252 r3380394 10 10 <div id="mgpdp1" class="magical-post-display mgpdp1"> 11 11 <div class="mg-cols"> 12 <section class="sec-wel" <?php if (!class_exists('magicalPostDisplayPro')) : ?> style="background-image: url(<?php echo esc_url(MAGICAL_POSTS_DISPLAY_ASSETS . 'img/blue.svg'); ?>);" <?php else : ?>style="background-image: url(<?php echo esc_url(MAGICAL_POSTS_DISPLAY_ASSETS . ' mg/purple.svg'); ?>);" <?php endif; ?>>12 <section class="sec-wel" <?php if (!class_exists('magicalPostDisplayPro')) : ?> style="background-image: url(<?php echo esc_url(MAGICAL_POSTS_DISPLAY_ASSETS . 'img/blue.svg'); ?>);" <?php else : ?>style="background-image: url(<?php echo esc_url(MAGICAL_POSTS_DISPLAY_ASSETS . 'img/purple.svg'); ?>);" <?php endif; ?>> 13 13 <div class="wel-center-text"> 14 14 <div class="welsec-icon"> … … 21 21 <?php esc_html_e('See Short Video', 'magical-posts-display'); ?> 22 22 </a> 23 24 23 <?php if (!class_exists('magicalPostDisplayPro')) : ?> 25 <a href="https://wpthemespace.com/product/magical-posts-display-pro/" class="button button-mgp1 button-mgp2"><?php esc_html_e(' Buy Pro Now', 'magical-posts-display'); ?></a>24 <a href="https://wpthemespace.com/product/magical-posts-display-pro/" class="button button-mgp1 button-mgp2"><?php esc_html_e('View Pro Version', 'magical-posts-display'); ?></a> 26 25 <?php endif; ?> 27 26 </div> -
magical-posts-display/trunk/admin/extra-function.php
r3170252 r3380394 61 61 $url1 = esc_url('https://wpthemespace.com/product-category/pro-theme/'); 62 62 63 $message = __('<strong><span style="color:red;">Latest WordPress Theme:</span> <span style="color:green"> If you find a Secure, SEO friendly, full functional premium WordPress theme for your site then </span> </strong>', ' niso');63 $message = __('<strong><span style="color:red;">Latest WordPress Theme:</span> <span style="color:green"> If you find a Secure, SEO friendly, full functional premium WordPress theme for your site then </span> </strong>', 'magical-posts-display'); 64 64 65 65 printf( -
magical-posts-display/trunk/admin/src/cmb2/includes/CMB2.php
r2892423 r3380394 1 1 <?php 2 2 3 /** 3 4 * CMB2 - The core metabox object … … 19 20 * The main CMB2 object for storing box data/properties. 20 21 */ 21 class CMB2 extends CMB2_Base { 22 class CMB2 extends CMB2_Base 23 { 22 24 23 25 /** … … 194 196 * @param integer $object_id Optional object id. 195 197 */ 196 public function __construct( $config, $object_id = 0 ) { 197 198 if ( empty( $config['id'] ) ) { 199 wp_die( esc_html__( 'Metabox configuration is required to have an ID parameter.', 'cmb2' ) ); 198 public function __construct($config, $object_id = 0) 199 { 200 201 if (empty($config['id'])) { 202 wp_die(esc_html__('Metabox configuration is required to have an ID parameter.', 'cmb2')); 200 203 } 201 204 202 205 $this->cmb_id = $config['id']; 203 $this->meta_box = wp_parse_args( $config, $this->mb_defaults);206 $this->meta_box = wp_parse_args($config, $this->mb_defaults); 204 207 $this->meta_box['fields'] = array(); 205 208 206 209 // Ensures object_types is an array. 207 $this->set_prop( 'object_types', $this->box_types());208 $this->object_id( $object_id);209 210 if ( $this->is_options_page_mb()) {210 $this->set_prop('object_types', $this->box_types()); 211 $this->object_id($object_id); 212 213 if ($this->is_options_page_mb()) { 211 214 $this->init_options_mb(); 212 215 } … … 214 217 $this->mb_object_type(); 215 218 216 if ( ! empty( $config['fields'] ) && is_array( $config['fields'] )) {217 $this->add_fields( $config['fields']);218 } 219 220 CMB2_Boxes::add( $this);219 if (! empty($config['fields']) && is_array($config['fields'])) { 220 $this->add_fields($config['fields']); 221 } 222 223 CMB2_Boxes::add($this); 221 224 222 225 /** … … 227 230 * @param array $cmb This CMB2 object 228 231 */ 229 do_action( "cmb2_init_{$this->cmb_id}", $this);232 do_action("cmb2_init_{$this->cmb_id}", $this); 230 233 231 234 // Hook in the hookup... how meta. 232 add_action( "cmb2_init_hookup_{$this->cmb_id}", array( 'CMB2_hookup', 'maybe_init_and_hookup' ));235 add_action("cmb2_init_hookup_{$this->cmb_id}", array('CMB2_hookup', 'maybe_init_and_hookup')); 233 236 234 237 // Hook in the rest api functionality. 235 add_action( "cmb2_init_hookup_{$this->cmb_id}", array( 'CMB2_REST', 'maybe_init_and_hookup' ));238 add_action("cmb2_init_hookup_{$this->cmb_id}", array('CMB2_REST', 'maybe_init_and_hookup')); 236 239 } 237 240 … … 245 248 * @return CMB2 246 249 */ 247 public function show_form( $object_id = 0, $object_type = '' ) { 248 $this->render_form_open( $object_id, $object_type ); 249 250 foreach ( $this->prop( 'fields' ) as $field_args ) { 251 $this->render_field( $field_args ); 252 } 253 254 return $this->render_form_close( $object_id, $object_type ); 250 public function show_form($object_id = 0, $object_type = '') 251 { 252 $this->render_form_open($object_id, $object_type); 253 254 foreach ($this->prop('fields') as $field_args) { 255 $this->render_field($field_args); 256 } 257 258 return $this->render_form_close($object_id, $object_type); 255 259 } 256 260 … … 265 269 * @return CMB2 266 270 */ 267 public function render_form_open( $object_id = 0, $object_type = '' ) { 268 $object_type = $this->object_type( $object_type ); 269 $object_id = $this->object_id( $object_id ); 271 public function render_form_open($object_id = 0, $object_type = '') 272 { 273 $object_type = $this->object_type($object_type); 274 $object_id = $this->object_id($object_id); 270 275 271 276 echo "\n<!-- Begin CMB2 Fields -->\n"; … … 283 288 * @param array $cmb This CMB2 object. 284 289 */ 285 do_action( 'cmb2_before_form', $this->cmb_id, $object_id, $object_type, $this);290 do_action('cmb2_before_form', $this->cmb_id, $object_id, $object_type, $this); 286 291 287 292 /** … … 298 303 * @param array $cmb This CMB2 object 299 304 */ 300 do_action( "cmb2_before_{$object_type}_form_{$this->cmb_id}", $object_id, $this);301 302 echo '<div class="', esc_attr( $this->box_classes() ), '"><div id="cmb2-metabox-', sanitize_html_class( $this->cmb_id), '" class="cmb2-metabox cmb-field-list">';305 do_action("cmb2_before_{$object_type}_form_{$this->cmb_id}", $object_id, $this); 306 307 echo '<div class="', esc_attr($this->box_classes()), '"><div id="cmb2-metabox-', sanitize_html_class($this->cmb_id), '" class="cmb2-metabox cmb-field-list">'; 303 308 304 309 return $this; … … 311 316 * @return string Space concatenated list of classes 312 317 */ 313 public function box_classes() { 314 315 $classes = array( 'cmb2-wrap', 'form-table' ); 318 public function box_classes() 319 { 320 321 $classes = array('cmb2-wrap', 'form-table'); 316 322 317 323 // Use the callback to fetch classes. 318 if ( $added_classes = $this->get_param_callback_result( 'classes_cb' )) {319 $added_classes = is_array( $added_classes ) ? $added_classes : array( $added_classes);320 $classes = array_merge( $classes, $added_classes);321 } 322 323 if ( $added_classes = $this->prop( 'classes' )) {324 $added_classes = is_array( $added_classes ) ? $added_classes : array( $added_classes);325 $classes = array_merge( $classes, $added_classes);324 if ($added_classes = $this->get_param_callback_result('classes_cb')) { 325 $added_classes = is_array($added_classes) ? $added_classes : array($added_classes); 326 $classes = array_merge($classes, $added_classes); 327 } 328 329 if ($added_classes = $this->prop('classes')) { 330 $added_classes = is_array($added_classes) ? $added_classes : array($added_classes); 331 $classes = array_merge($classes, $added_classes); 326 332 } 327 333 … … 331 337 * @since 2.2.4 332 338 */ 333 if ( $this->is_alternate_context_box()) {339 if ($this->is_alternate_context_box()) { 334 340 $context = array(); 335 341 336 342 // Include custom class if requesting no title. 337 if ( ! $this->prop( 'title' ) && ! $this->prop( 'remove_box_wrap' )) {343 if (! $this->prop('title') && ! $this->prop('remove_box_wrap')) { 338 344 $context[] = 'cmb2-context-wrap-no-title'; 339 345 } … … 343 349 344 350 // Include a context-type based context wrapper. 345 $context[] = 'cmb2-context-wrap-' . $this->prop( 'context');351 $context[] = 'cmb2-context-wrap-' . $this->prop('context'); 346 352 347 353 // Include an ID based context wrapper as well. 348 $context[] = 'cmb2-context-wrap-' . $this->prop( 'id');354 $context[] = 'cmb2-context-wrap-' . $this->prop('id'); 349 355 350 356 // And merge all the classes back into the array. 351 $classes = array_merge( $classes, $context);357 $classes = array_merge($classes, $context); 352 358 } 353 359 … … 360 366 * @param CMB2 $cmb This CMB2 object. 361 367 */ 362 $classes = apply_filters( 'cmb2_wrap_classes', $classes, $this);368 $classes = apply_filters('cmb2_wrap_classes', $classes, $this); 363 369 364 370 // Clean up. 365 $classes = array_map( 'strip_tags', array_filter( $classes ));371 $classes = array_map('wp_strip_all_tags', array_filter($classes)); 366 372 367 373 // Remove any duplicates. 368 $classes = array_unique( $classes);374 $classes = array_unique($classes); 369 375 370 376 // Make a string. 371 return implode( ' ', $classes);377 return implode(' ', $classes); 372 378 } 373 379 … … 382 388 * @return CMB2 383 389 */ 384 public function render_form_close( $object_id = 0, $object_type = '' ) { 385 $object_type = $this->object_type( $object_type ); 386 $object_id = $this->object_id( $object_id ); 390 public function render_form_close($object_id = 0, $object_type = '') 391 { 392 $object_type = $this->object_type($object_type); 393 $object_id = $this->object_id($object_id); 387 394 388 395 echo '</div></div>'; … … 402 409 * @param array $cmb This CMB2 object 403 410 */ 404 do_action( "cmb2_after_{$object_type}_form_{$this->cmb_id}", $object_id, $this);411 do_action("cmb2_after_{$object_type}_form_{$this->cmb_id}", $object_id, $this); 405 412 406 413 /** … … 414 421 * @param array $cmb This CMB2 object. 415 422 */ 416 do_action( 'cmb2_after_form', $this->cmb_id, $object_id, $object_type, $this);423 do_action('cmb2_after_form', $this->cmb_id, $object_id, $object_type, $this); 417 424 418 425 echo "\n<!-- End CMB2 Fields -->\n"; … … 428 435 * @return mixed CMB2_Field object if successful. 429 436 */ 430 public function render_field( $field_args ) { 431 $field_args['context'] = $this->prop( 'context' ); 432 433 if ( 'group' === $field_args['type'] ) { 434 435 if ( ! isset( $field_args['show_names'] ) ) { 436 $field_args['show_names'] = $this->prop( 'show_names' ); 437 public function render_field($field_args) 438 { 439 $field_args['context'] = $this->prop('context'); 440 441 if ('group' === $field_args['type']) { 442 443 if (! isset($field_args['show_names'])) { 444 $field_args['show_names'] = $this->prop('show_names'); 437 445 } 438 $field = $this->render_group( $field_args ); 439 440 } elseif ( 'hidden' === $field_args['type'] && $this->get_field( $field_args )->should_show() ) { 446 $field = $this->render_group($field_args); 447 } elseif ('hidden' === $field_args['type'] && $this->get_field($field_args)->should_show()) { 441 448 // Save rendering for after the metabox. 442 $field = $this->add_hidden_field( $field_args ); 443 449 $field = $this->add_hidden_field($field_args); 444 450 } else { 445 451 446 $field_args['show_names'] = $this->prop( 'show_names');452 $field_args['show_names'] = $this->prop('show_names'); 447 453 448 454 // Render default fields. 449 $field = $this->get_field( $field_args)->render_field();455 $field = $this->get_field($field_args)->render_field(); 450 456 } 451 457 … … 459 465 * @return CMB2_Field|null Group field object. 460 466 */ 461 public function render_group( $args ) { 467 public function render_group($args) 468 { 462 469 $field_group = false; 463 470 464 if ( $args instanceof CMB2_Field) {471 if ($args instanceof CMB2_Field) { 465 472 $field_group = 'group' === $args->type() ? $args : false; 466 } elseif ( isset( $args['id'], $args['fields'] ) && is_array( $args['fields'] )) {467 $field_group = $this->get_field( $args);468 } 469 470 if ( ! $field_group) {473 } elseif (isset($args['id'], $args['fields']) && is_array($args['fields'])) { 474 $field_group = $this->get_field($args); 475 } 476 477 if (! $field_group) { 471 478 return; 472 479 } 473 480 474 481 $field_group->render_context = 'edit'; 475 $field_group->peform_param_callback( 'render_row_cb');482 $field_group->peform_param_callback('render_row_cb'); 476 483 477 484 return $field_group; … … 488 495 * @return CMB2_Field|null Group field object. 489 496 */ 490 public function render_group_callback( $field_args, $field_group ) { 497 public function render_group_callback($field_args, $field_group) 498 { 491 499 492 500 // If field is requesting to be conditionally shown. 493 if ( ! $field_group || ! $field_group->should_show()) {501 if (! $field_group || ! $field_group->should_show()) { 494 502 return; 495 503 } … … 497 505 $field_group->index = 0; 498 506 499 $field_group->peform_param_callback( 'before_group');500 501 $desc = $field_group->args( 'description');502 $label = $field_group->args( 'name');507 $field_group->peform_param_callback('before_group'); 508 509 $desc = $field_group->args('description'); 510 $label = $field_group->args('name'); 503 511 $group_val = (array) $field_group->value(); 504 512 505 echo '<div class="cmb-row cmb-repeat-group-wrap ', esc_attr( $field_group->row_classes() ), '" data-fieldtype="group"><div class="cmb-td"><div data-groupid="', esc_attr( $field_group->id() ), '" id="', esc_attr( $field_group->id() ), '_repeat" ', $this->group_wrap_attributes( $field_group), '>';506 507 if ( $desc || $label) {513 echo '<div class="cmb-row cmb-repeat-group-wrap ', esc_attr($field_group->row_classes()), '" data-fieldtype="group"><div class="cmb-td"><div data-groupid="', esc_attr($field_group->id()), '" id="', esc_attr($field_group->id()), '_repeat" ', $this->group_wrap_attributes($field_group), '>'; 514 515 if ($desc || $label) { 508 516 $class = $desc ? ' cmb-group-description' : ''; 509 517 echo '<div class="cmb-row', $class, '"><div class="cmb-th">'; 510 if ( $label) {518 if ($label) { 511 519 echo '<h2 class="cmb-group-name">', $label, '</h2>'; 512 520 } 513 if ( $desc) {521 if ($desc) { 514 522 echo '<p class="cmb2-metabox-description">', $desc, '</p>'; 515 523 } … … 517 525 } 518 526 519 if ( ! empty( $group_val )) {520 foreach ( $group_val as $group_key => $field_id) {521 $this->render_group_row( $field_group);527 if (! empty($group_val)) { 528 foreach ($group_val as $group_key => $field_id) { 529 $this->render_group_row($field_group); 522 530 $field_group->index++; 523 531 } 524 532 } else { 525 $this->render_group_row( $field_group);526 } 527 528 if ( $field_group->args( 'repeatable' )) {529 echo '<div class="cmb-row"><div class="cmb-td"><p class="cmb-add-row"><button type="button" data-selector="', esc_attr( $field_group->id() ), '_repeat" data-grouptitle="', esc_attr( $field_group->options( 'group_title' ) ), '" class="cmb-add-group-row button-secondary">', $field_group->options( 'add_button'), '</button></p></div></div>';533 $this->render_group_row($field_group); 534 } 535 536 if ($field_group->args('repeatable')) { 537 echo '<div class="cmb-row"><div class="cmb-td"><p class="cmb-add-row"><button type="button" data-selector="', esc_attr($field_group->id()), '_repeat" data-grouptitle="', esc_attr($field_group->options('group_title')), '" class="cmb-add-group-row button-secondary">', $field_group->options('add_button'), '</button></p></div></div>'; 530 538 } 531 539 532 540 echo '</div></div></div>'; 533 541 534 $field_group->peform_param_callback( 'after_group');542 $field_group->peform_param_callback('after_group'); 535 543 536 544 return $field_group; … … 544 552 * @return string The attributes string. 545 553 */ 546 public function group_wrap_attributes( $field_group ) { 554 public function group_wrap_attributes($field_group) 555 { 547 556 $classes = 'cmb-nested cmb-field-list cmb-repeatable-group'; 548 $classes .= $field_group->options( 'sortable') ? ' sortable' : ' non-sortable';549 $classes .= $field_group->args( 'repeatable') ? ' repeatable' : ' non-repeatable';557 $classes .= $field_group->options('sortable') ? ' sortable' : ' non-sortable'; 558 $classes .= $field_group->args('repeatable') ? ' repeatable' : ' non-repeatable'; 550 559 551 560 $group_wrap_attributes = array( … … 564 573 * @param CMB2_Field $field_group The group CMB2_Field object. 565 574 */ 566 $group_wrap_attributes = apply_filters( 'cmb2_group_wrap_attributes', $group_wrap_attributes, $field_group);575 $group_wrap_attributes = apply_filters('cmb2_group_wrap_attributes', $group_wrap_attributes, $field_group); 567 576 568 577 $atts = array(); 569 foreach ( $group_wrap_attributes as $att => $att_value) {570 if ( ! CMB2_Utils::is_data_attribute( $att )) {571 $att_value = htmlspecialchars( $att_value);578 foreach ($group_wrap_attributes as $att => $att_value) { 579 if (! CMB2_Utils::is_data_attribute($att)) { 580 $att_value = htmlspecialchars($att_value); 572 581 } 573 582 574 $atts[ sanitize_html_class( $att ) ] = sanitize_text_field( strip_tags( $att_value ));575 } 576 577 return CMB2_Utils::concat_attrs( $atts);583 $atts[sanitize_html_class($att)] = sanitize_text_field(wp_strip_all_tags($att_value)); 584 } 585 586 return CMB2_Utils::concat_attrs($atts); 578 587 } 579 588 … … 586 595 * @return CMB2 587 596 */ 588 public function render_group_row( $field_group ) { 589 590 $field_group->peform_param_callback( 'before_group_row' ); 591 $closed_class = $field_group->options( 'closed' ) ? ' closed' : ''; 592 $confirm_deletion = $field_group->options( 'remove_confirm' ); 593 $confirm_deletion = ! empty( $confirm_deletion ) ? $confirm_deletion : ''; 597 public function render_group_row($field_group) 598 { 599 600 $field_group->peform_param_callback('before_group_row'); 601 $closed_class = $field_group->options('closed') ? ' closed' : ''; 602 $confirm_deletion = $field_group->options('remove_confirm'); 603 $confirm_deletion = ! empty($confirm_deletion) ? $confirm_deletion : ''; 594 604 595 605 echo ' 596 606 <div id="cmb-group-', $field_group->id(), '-', $field_group->index, '" class="postbox cmb-row cmb-repeatable-grouping', $closed_class, '" data-iterator="', $field_group->index, '">'; 597 607 598 if ( $field_group->args( 'repeatable' )) {599 echo '<button type="button" data-selector="', $field_group->id(), '_repeat" data-confirm="', esc_attr( $confirm_deletion ), '" class="dashicons-before dashicons-no-alt cmb-remove-group-row" title="', esc_attr( $field_group->options( 'remove_button' )), '"></button>';600 } 601 602 echo '603 <div class="cmbhandle" title="' , esc_attr__( 'Click to toggle', 'cmb2'), '"><br></div>604 <h3 class="cmb-group-title cmbhandle-title"><span>', $field_group->replace_hash( $field_group->options( 'group_title' )), '</span></h3>608 if ($field_group->args('repeatable')) { 609 echo '<button type="button" data-selector="', $field_group->id(), '_repeat" data-confirm="', esc_attr($confirm_deletion), '" class="dashicons-before dashicons-no-alt cmb-remove-group-row" title="', esc_attr($field_group->options('remove_button')), '"></button>'; 610 } 611 612 echo ' 613 <div class="cmbhandle" title="', esc_attr__('Click to toggle', 'cmb2'), '"><br></div> 614 <h3 class="cmb-group-title cmbhandle-title"><span>', $field_group->replace_hash($field_group->options('group_title')), '</span></h3> 605 615 606 616 <div class="inside cmb-td cmb-nested cmb-field-list">'; 607 // Loop and render repeatable group fields.608 foreach ( array_values( $field_group->args( 'fields' ) ) as $field_args) {609 if ( 'hidden' === $field_args['type']) {617 // Loop and render repeatable group fields. 618 foreach (array_values($field_group->args('fields')) as $field_args) { 619 if ('hidden' === $field_args['type']) { 610 620 611 621 // Save rendering for after the metabox. 612 $this->add_hidden_field( $field_args, $field_group ); 613 622 $this->add_hidden_field($field_args, $field_group); 614 623 } else { 615 624 616 $field_args['show_names'] = $field_group->args( 'show_names');617 $field_args['context'] = $field_group->args( 'context');618 619 $this->get_field( $field_args, $field_group)->render_field();625 $field_args['show_names'] = $field_group->args('show_names'); 626 $field_args['context'] = $field_group->args('context'); 627 628 $this->get_field($field_args, $field_group)->render_field(); 620 629 } 621 630 } 622 631 623 if ( $field_group->args( 'repeatable' )) {632 if ($field_group->args('repeatable')) { 624 633 echo ' 625 634 <div class="cmb-row cmb-remove-field-row"> 626 635 <div class="cmb-remove-row"> 627 <button type="button" data-selector="', $field_group->id(), '_repeat" data-confirm="', esc_attr( $confirm_deletion ), '" class="cmb-remove-group-row cmb-remove-group-row-button alignright button-secondary">', $field_group->options( 'remove_button'), '</button>636 <button type="button" data-selector="', $field_group->id(), '_repeat" data-confirm="', esc_attr($confirm_deletion), '" class="cmb-remove-group-row cmb-remove-group-row-button alignright button-secondary">', $field_group->options('remove_button'), '</button> 628 637 </div> 629 638 </div> 630 639 '; 631 640 } 632 echo '641 echo ' 633 642 </div> 634 643 </div> 635 644 '; 636 645 637 $field_group->peform_param_callback( 'after_group_row');646 $field_group->peform_param_callback('after_group_row'); 638 647 639 648 return $this; … … 649 658 * @return CMB2_Field 650 659 */ 651 public function add_hidden_field( $field_args, $field_group = null ) { 652 if ( isset( $field_args['field_args'] ) ) { 660 public function add_hidden_field($field_args, $field_group = null) 661 { 662 if (isset($field_args['field_args'])) { 653 663 // For back-compatibility. 654 $field = new CMB2_Field( $field_args);664 $field = new CMB2_Field($field_args); 655 665 } else { 656 $field = $this->get_new_field( $field_args, $field_group);657 } 658 659 $types = new CMB2_Types( $field);660 661 if ( $field_group) {666 $field = $this->get_new_field($field_args, $field_group); 667 } 668 669 $types = new CMB2_Types($field); 670 671 if ($field_group) { 662 672 $types->iterator = $field_group->index; 663 673 } … … 675 685 * @return CMB2 676 686 */ 677 public function render_hidden_fields() { 678 if ( ! empty( $this->hidden_fields ) ) { 679 foreach ( $this->hidden_fields as $hidden ) { 687 public function render_hidden_fields() 688 { 689 if (! empty($this->hidden_fields)) { 690 foreach ($this->hidden_fields as $hidden) { 680 691 $hidden->render(); 681 692 } … … 692 703 * @return mixed 693 704 */ 694 public function get_sanitized_values( array $data_to_sanitize ) { 705 public function get_sanitized_values(array $data_to_sanitize) 706 { 695 707 $this->data_to_save = $data_to_sanitize; 696 708 $stored_id = $this->object_id(); 697 709 698 710 // We do this So CMB will sanitize our data for us, but not save it. 699 $this->object_id( '_');711 $this->object_id('_'); 700 712 701 713 // Ensure temp. data store is empty. 702 cmb2_options( 0)->set();714 cmb2_options(0)->set(); 703 715 704 716 // We want to get any taxonomy values back. 705 add_filter( "cmb2_return_taxonomy_values_{$this->cmb_id}", '__return_true');717 add_filter("cmb2_return_taxonomy_values_{$this->cmb_id}", '__return_true'); 706 718 707 719 // Process/save fields. … … 709 721 710 722 // Put things back the way they were. 711 remove_filter( "cmb2_return_taxonomy_values_{$this->cmb_id}", '__return_true');723 remove_filter("cmb2_return_taxonomy_values_{$this->cmb_id}", '__return_true'); 712 724 713 725 // Get data from temp. data store. 714 $sanitized_values = cmb2_options( 0)->get_options();726 $sanitized_values = cmb2_options(0)->get_options(); 715 727 716 728 // Empty out temp. data store again. 717 cmb2_options( 0)->set();729 cmb2_options(0)->set(); 718 730 719 731 // Reset the object id. 720 $this->object_id( $stored_id);732 $this->object_id($stored_id); 721 733 722 734 return $sanitized_values; … … 733 745 * @return CMB2 734 746 */ 735 public function save_fields( $object_id = 0, $object_type = '', $data_to_save = array() ) { 747 public function save_fields($object_id = 0, $object_type = '', $data_to_save = array()) 748 { 736 749 737 750 // Fall-back to $_POST data. 738 $this->data_to_save = ! empty( $data_to_save) ? $data_to_save : $_POST;739 $object_id = $this->object_id( $object_id);740 $object_type = $this->object_type( $object_type);751 $this->data_to_save = ! empty($data_to_save) ? $data_to_save : $_POST; 752 $object_id = $this->object_id($object_id); 753 $object_type = $this->object_type($object_type); 741 754 742 755 $this->process_fields(); 743 756 744 757 // If options page, save the updated options. 745 if ( 'options-page' === $object_type) {746 cmb2_options( $object_id)->set();758 if ('options-page' === $object_type) { 759 cmb2_options($object_id)->set(); 747 760 } 748 761 … … 757 770 * @return CMB2 758 771 */ 759 public function process_fields() { 772 public function process_fields() 773 { 760 774 761 775 $this->pre_process(); 762 776 763 777 // Remove the show_on properties so saving works. 764 $this->prop( 'show_on', array());778 $this->prop('show_on', array()); 765 779 766 780 // save field ids of those that are updated. 767 781 $this->updated = array(); 768 782 769 foreach ( $this->prop( 'fields' ) as $field_args) {770 $this->process_field( $field_args);783 foreach ($this->prop('fields') as $field_args) { 784 $this->process_field($field_args); 771 785 } 772 786 … … 782 796 * @return CMB2 783 797 */ 784 public function process_field( $field_args ) { 785 786 switch ( $field_args['type'] ) { 798 public function process_field($field_args) 799 { 800 801 switch ($field_args['type']) { 787 802 788 803 case 'group': 789 if ( $this->save_group( $field_args )) {804 if ($this->save_group($field_args)) { 790 805 $this->updated[] = $field_args['id']; 791 806 } … … 798 813 799 814 default: 800 $field = $this->get_new_field( $field_args);801 802 if ( $field->save_field_from_data( $this->data_to_save )) {815 $field = $this->get_new_field($field_args); 816 817 if ($field->save_field_from_data($this->data_to_save)) { 803 818 $this->updated[] = $field->id(); 804 819 } … … 817 832 * @return CMB2 818 833 */ 819 public function pre_process() { 834 public function pre_process() 835 { 820 836 $object_type = $this->object_type(); 821 837 … … 833 849 * @param int $object_id The ID of the current object 834 850 */ 835 do_action( "cmb2_{$object_type}_process_fields_{$this->cmb_id}", $this, $this->object_id());851 do_action("cmb2_{$object_type}_process_fields_{$this->cmb_id}", $this, $this->object_id()); 836 852 837 853 return $this; … … 846 862 * @return CMB2 847 863 */ 848 public function after_save() { 864 public function after_save() 865 { 849 866 $object_type = $this->object_type(); 850 867 $object_id = $this->object_id(); … … 863 880 * @param array $cmb This CMB2 object 864 881 */ 865 do_action( "cmb2_save_{$object_type}_fields", $object_id, $this->cmb_id, $this->updated, $this);882 do_action("cmb2_save_{$object_type}_fields", $object_id, $this->cmb_id, $this->updated, $this); 866 883 867 884 /** … … 879 896 * @param array $cmb This CMB2 object 880 897 */ 881 do_action( "cmb2_save_{$object_type}_fields_{$this->cmb_id}", $object_id, $this->updated, $this);898 do_action("cmb2_save_{$object_type}_fields_{$this->cmb_id}", $object_id, $this->updated, $this); 882 899 883 900 return $this; … … 891 908 * @return mixed Return of CMB2_Field::update_data(). 892 909 */ 893 public function save_group( $args ) { 894 if ( ! isset( $args['id'], $args['fields'] ) || ! is_array( $args['fields'] ) ) { 910 public function save_group($args) 911 { 912 if (! isset($args['id'], $args['fields']) || ! is_array($args['fields'])) { 895 913 return; 896 914 } 897 915 898 return $this->save_group_field( $this->get_new_field( $args ));916 return $this->save_group_field($this->get_new_field($args)); 899 917 } 900 918 … … 906 924 * @return mixed Return of CMB2_Field::update_data(). 907 925 */ 908 public function save_group_field( $field_group ) { 926 public function save_group_field($field_group) 927 { 909 928 $base_id = $field_group->id(); 910 929 911 if ( ! isset( $this->data_to_save[ $base_id ] )) {930 if (! isset($this->data_to_save[$base_id])) { 912 931 return; 913 932 } … … 915 934 $old = $field_group->get_data(); 916 935 // Check if group field has sanitization_cb. 917 $group_vals = $field_group->sanitization_cb( $this->data_to_save[ $base_id ]);936 $group_vals = $field_group->sanitization_cb($this->data_to_save[$base_id]); 918 937 $saved = array(); 919 938 … … 921 940 $field_group->data_to_save = $this->data_to_save; 922 941 923 foreach ( array_values( $field_group->fields() ) as $field_args) {924 if ( 'title' === $field_args['type']) {942 foreach (array_values($field_group->fields()) as $field_args) { 943 if ('title' === $field_args['type']) { 925 944 // Don't process title fields. 926 945 continue; 927 946 } 928 947 929 $field = $this->get_new_field( $field_args, $field_group);930 $sub_id = $field->id( true);931 if ( empty( $saved[ $field_group->index ] )) {932 $saved[ $field_group->index] = array();948 $field = $this->get_new_field($field_args, $field_group); 949 $sub_id = $field->id(true); 950 if (empty($saved[$field_group->index])) { 951 $saved[$field_group->index] = array(); 933 952 } 934 953 935 foreach ( (array) $group_vals as $field_group->index => $post_vals) {954 foreach ((array) $group_vals as $field_group->index => $post_vals) { 936 955 937 956 // Get value. 938 $new_val = isset( $group_vals[ $field_group->index ][ $sub_id ])939 ? $group_vals[ $field_group->index ][ $sub_id]957 $new_val = isset($group_vals[$field_group->index][$sub_id]) 958 ? $group_vals[$field_group->index][$sub_id] 940 959 : false; 941 960 942 961 // Sanitize. 943 $new_val = $field->sanitization_cb( $new_val);944 945 if ( is_array( $new_val ) && $field->args( 'has_supporting_data' )) {946 if ( $field->args( 'repeatable' )) {962 $new_val = $field->sanitization_cb($new_val); 963 964 if (is_array($new_val) && $field->args('has_supporting_data')) { 965 if ($field->args('repeatable')) { 947 966 $_new_val = array(); 948 foreach ( $new_val as $group_index => $grouped_data) {967 foreach ($new_val as $group_index => $grouped_data) { 949 968 // Add the supporting data to the $saved array stack. 950 $saved[ $field_group->index ][ $grouped_data['supporting_field_id']][] = $grouped_data['supporting_field_value'];969 $saved[$field_group->index][$grouped_data['supporting_field_id']][] = $grouped_data['supporting_field_value']; 951 970 // Reset var to the actual value. 952 $_new_val[ $group_index] = $grouped_data['value'];971 $_new_val[$group_index] = $grouped_data['value']; 953 972 } 954 973 $new_val = $_new_val; 955 974 } else { 956 975 // Add the supporting data to the $saved array stack. 957 $saved[ $field_group->index ][ $new_val['supporting_field_id']] = $new_val['supporting_field_value'];976 $saved[$field_group->index][$new_val['supporting_field_id']] = $new_val['supporting_field_value']; 958 977 // Reset var to the actual value. 959 978 $new_val = $new_val['value']; … … 962 981 963 982 // Get old value. 964 $old_val = is_array( $old ) && isset( $old[ $field_group->index ][ $sub_id ])965 ? $old[ $field_group->index ][ $sub_id]983 $old_val = is_array($old) && isset($old[$field_group->index][$sub_id]) 984 ? $old[$field_group->index][$sub_id] 966 985 : false; 967 986 968 $is_updated = ( ! CMB2_Utils::isempty( $new_val ) && $new_val !== $old_val);969 $is_removed = ( CMB2_Utils::isempty( $new_val ) && ! CMB2_Utils::isempty( $old_val ));987 $is_updated = (! CMB2_Utils::isempty($new_val) && $new_val !== $old_val); 988 $is_removed = (CMB2_Utils::isempty($new_val) && ! CMB2_Utils::isempty($old_val)); 970 989 971 990 // Compare values and add to `$updated` array. 972 if ( $is_updated || $is_removed) {991 if ($is_updated || $is_removed) { 973 992 $this->updated[] = $base_id . '::' . $field_group->index . '::' . $sub_id; 974 993 } 975 994 976 995 // Add to `$saved` array. 977 $saved[ $field_group->index ][ $sub_id ] = $new_val; 978 979 }// End foreach. 980 981 $saved[ $field_group->index ] = CMB2_Utils::filter_empty( $saved[ $field_group->index ] ); 982 }// End foreach. 983 984 $saved = CMB2_Utils::filter_empty( $saved ); 985 986 return $field_group->update_data( $saved, true ); 996 $saved[$field_group->index][$sub_id] = $new_val; 997 } // End foreach. 998 999 $saved[$field_group->index] = CMB2_Utils::filter_empty($saved[$field_group->index]); 1000 } // End foreach. 1001 1002 $saved = CMB2_Utils::filter_empty($saved); 1003 1004 return $field_group->update_data($saved, true); 987 1005 } 988 1006 … … 994 1012 * @return integer|string $object_id Object ID. 995 1013 */ 996 public function object_id( $object_id = 0 ) { 1014 public function object_id($object_id = 0) 1015 { 997 1016 global $pagenow; 998 1017 999 if ( $object_id) {1018 if ($object_id) { 1000 1019 $this->object_id = $object_id; 1001 1020 return $this->object_id; 1002 1021 } 1003 1022 1004 if ( $this->object_id) {1023 if ($this->object_id) { 1005 1024 return $this->object_id; 1006 1025 } 1007 1026 1008 1027 // Try to get our object ID from the global space. 1009 switch ( $this->object_type()) {1028 switch ($this->object_type()) { 1010 1029 case 'user': 1011 $object_id = isset( $_REQUEST['user_id'] ) ? wp_unslash( $_REQUEST['user_id']) : $object_id;1012 $object_id = ! $object_id && 'user-new.php' !== $pagenow && isset( $GLOBALS['user_ID']) ? $GLOBALS['user_ID'] : $object_id;1030 $object_id = isset($_REQUEST['user_id']) ? wp_unslash($_REQUEST['user_id']) : $object_id; 1031 $object_id = ! $object_id && 'user-new.php' !== $pagenow && isset($GLOBALS['user_ID']) ? $GLOBALS['user_ID'] : $object_id; 1013 1032 break; 1014 1033 1015 1034 case 'comment': 1016 $object_id = isset( $_REQUEST['c'] ) ? wp_unslash( $_REQUEST['c']) : $object_id;1017 $object_id = ! $object_id && isset( $GLOBALS['comments']->comment_ID) ? $GLOBALS['comments']->comment_ID : $object_id;1035 $object_id = isset($_REQUEST['c']) ? wp_unslash($_REQUEST['c']) : $object_id; 1036 $object_id = ! $object_id && isset($GLOBALS['comments']->comment_ID) ? $GLOBALS['comments']->comment_ID : $object_id; 1018 1037 break; 1019 1038 1020 1039 case 'term': 1021 $object_id = isset( $_REQUEST['tag_ID'] ) ? wp_unslash( $_REQUEST['tag_ID']) : $object_id;1040 $object_id = isset($_REQUEST['tag_ID']) ? wp_unslash($_REQUEST['tag_ID']) : $object_id; 1022 1041 break; 1023 1042 1024 1043 case 'options-page': 1025 1044 $key = $this->doing_options_page(); 1026 if ( ! empty( $key )) {1045 if (! empty($key)) { 1027 1046 $object_id = $key; 1028 1047 } … … 1030 1049 1031 1050 default: 1032 $object_id = isset( $GLOBALS['post']->ID) ? $GLOBALS['post']->ID : $object_id;1033 $object_id = isset( $_REQUEST['post'] ) ? wp_unslash( $_REQUEST['post']) : $object_id;1051 $object_id = isset($GLOBALS['post']->ID) ? $GLOBALS['post']->ID : $object_id; 1052 $object_id = isset($_REQUEST['post']) ? wp_unslash($_REQUEST['post']) : $object_id; 1034 1053 break; 1035 1054 } … … 1047 1066 * @return string Object type. 1048 1067 */ 1049 public function mb_object_type() { 1050 if ( null !== $this->mb_object_type ) { 1068 public function mb_object_type() 1069 { 1070 if (null !== $this->mb_object_type) { 1051 1071 return $this->mb_object_type; 1052 1072 } 1053 1073 1054 if ( $this->is_options_page_mb()) {1074 if ($this->is_options_page_mb()) { 1055 1075 $this->mb_object_type = 'options-page'; 1056 1076 return $this->mb_object_type; … … 1062 1082 1063 1083 // if it's an array of one, extract it. 1064 if ( 1 === count( $registered_types )) {1065 $last = end( $registered_types);1066 if ( is_string( $last )) {1084 if (1 === count($registered_types)) { 1085 $last = end($registered_types); 1086 if (is_string($last)) { 1067 1087 $type = $last; 1068 1088 } 1069 } elseif ( ( $curr_type = $this->current_object_type() ) && in_array( $curr_type, $registered_types, true )) {1089 } elseif (($curr_type = $this->current_object_type()) && in_array($curr_type, $registered_types, true)) { 1070 1090 $type = $curr_type; 1071 1091 } 1072 1092 1073 1093 // Get our object type. 1074 switch ( $type) {1094 switch ($type) { 1075 1095 1076 1096 case 'user': … … 1096 1116 * @return array Object types. 1097 1117 */ 1098 public function box_types( $fallback = array() ) { 1099 return CMB2_Utils::ensure_array( $this->prop( 'object_types' ), $fallback ); 1118 public function box_types($fallback = array()) 1119 { 1120 return CMB2_Utils::ensure_array($this->prop('object_types'), $fallback); 1100 1121 } 1101 1122 … … 1107 1128 * @return void 1108 1129 */ 1109 public function init_options_mb() { 1130 public function init_options_mb() 1131 { 1110 1132 $keys = $this->options_page_keys(); 1111 1133 $types = $this->box_types(); 1112 1134 1113 if ( empty( $keys )) {1135 if (empty($keys)) { 1114 1136 $keys = ''; 1115 $types = $this->deinit_options_mb( $types);1137 $types = $this->deinit_options_mb($types); 1116 1138 } else { 1117 1139 … … 1121 1143 1122 1144 // Set/Reset the option_key property. 1123 $this->set_prop( 'option_key', $keys);1145 $this->set_prop('option_key', $keys); 1124 1146 1125 1147 // Reset the object types. 1126 $this->set_prop( 'object_types', array_unique( $types ));1148 $this->set_prop('object_types', array_unique($types)); 1127 1149 } 1128 1150 … … 1135 1157 * @return array 1136 1158 */ 1137 protected function deinit_options_mb( $types ) { 1138 if ( isset( $this->meta_box['show_on']['key'] ) && 'options-page' === $this->meta_box['show_on']['key'] ) { 1139 unset( $this->meta_box['show_on']['key'] ); 1140 } 1141 1142 if ( array_key_exists( 'options-page', $this->meta_box['show_on'] ) ) { 1143 unset( $this->meta_box['show_on']['options-page'] ); 1144 } 1145 1146 $index = array_search( 'options-page', $types ); 1147 1148 if ( false !== $index ) { 1149 unset( $types[ $index ] ); 1159 protected function deinit_options_mb($types) 1160 { 1161 if (isset($this->meta_box['show_on']['key']) && 'options-page' === $this->meta_box['show_on']['key']) { 1162 unset($this->meta_box['show_on']['key']); 1163 } 1164 1165 if (array_key_exists('options-page', $this->meta_box['show_on'])) { 1166 unset($this->meta_box['show_on']['options-page']); 1167 } 1168 1169 $index = array_search('options-page', $types); 1170 1171 if (false !== $index) { 1172 unset($types[$index]); 1150 1173 } 1151 1174 … … 1159 1182 * @return boolean True/False. 1160 1183 */ 1161 public function is_options_page_mb() { 1184 public function is_options_page_mb() 1185 { 1162 1186 return ( 1163 1187 // 'show_on' values checked for back-compatibility. 1164 1188 $this->is_old_school_options_page_mb() 1165 || in_array( 'options-page', $this->box_types())1189 || in_array('options-page', $this->box_types()) 1166 1190 ); 1167 1191 } … … 1173 1197 * @return boolean True/False. 1174 1198 */ 1175 public function is_old_school_options_page_mb() { 1199 public function is_old_school_options_page_mb() 1200 { 1176 1201 return ( 1177 1202 // 'show_on' values checked for back-compatibility. 1178 isset( $this->meta_box['show_on']['key']) && 'options-page' === $this->meta_box['show_on']['key']1179 || array_key_exists( 'options-page', $this->meta_box['show_on'])1203 isset($this->meta_box['show_on']['key']) && 'options-page' === $this->meta_box['show_on']['key'] 1204 || array_key_exists('options-page', $this->meta_box['show_on']) 1180 1205 ); 1181 1206 } … … 1188 1213 * @return bool 1189 1214 */ 1190 public function doing_options_page() { 1215 public function doing_options_page() 1216 { 1191 1217 $found_key = false; 1192 1218 $keys = $this->options_page_keys(); 1193 1219 1194 if ( empty( $keys )) {1220 if (empty($keys)) { 1195 1221 return $found_key; 1196 1222 } 1197 1223 1198 if ( ! empty( $_GET['page'] ) && in_array( $_GET['page'], $keys )) {1224 if (! empty($_GET['page']) && in_array($_GET['page'], $keys)) { 1199 1225 $found_key = $_GET['page']; 1200 1226 } 1201 1227 1202 if ( ! empty( $_POST['action'] ) && in_array( $_POST['action'], $keys )) {1228 if (! empty($_POST['action']) && in_array($_POST['action'], $keys)) { 1203 1229 $found_key = $_POST['action']; 1204 1230 } … … 1213 1239 * @return string|array 1214 1240 */ 1215 public function options_page_keys() { 1241 public function options_page_keys() 1242 { 1216 1243 $key = ''; 1217 if ( ! $this->is_options_page_mb()) {1244 if (! $this->is_options_page_mb()) { 1218 1245 return $key; 1219 1246 } 1220 1247 1221 1248 $values = null; 1222 if ( ! empty( $this->meta_box['show_on']['value'] )) {1249 if (! empty($this->meta_box['show_on']['value'])) { 1223 1250 $values = $this->meta_box['show_on']['value']; 1224 } elseif ( ! empty( $this->meta_box['show_on']['options-page'] )) {1251 } elseif (! empty($this->meta_box['show_on']['options-page'])) { 1225 1252 $values = $this->meta_box['show_on']['options-page']; 1226 } elseif ( $this->prop( 'option_key' )) {1227 $values = $this->prop( 'option_key');1228 } 1229 1230 if ( $values) {1253 } elseif ($this->prop('option_key')) { 1254 $values = $this->prop('option_key'); 1255 } 1256 1257 if ($values) { 1231 1258 $key = $values; 1232 1259 } 1233 1260 1234 if ( ! is_array( $key )) {1235 $key = array( $key);1261 if (! is_array($key)) { 1262 $key = array($key); 1236 1263 } 1237 1264 … … 1246 1273 * @return string Object type. 1247 1274 */ 1248 public function object_type( $object_type = '' ) { 1249 if ( $object_type ) { 1275 public function object_type($object_type = '') 1276 { 1277 if ($object_type) { 1250 1278 $this->object_type = $object_type; 1251 1279 return $this->object_type; 1252 1280 } 1253 1281 1254 if ( $this->object_type) {1282 if ($this->object_type) { 1255 1283 return $this->object_type; 1256 1284 } … … 1267 1295 * @return string Page object type name. 1268 1296 */ 1269 public function current_object_type() { 1297 public function current_object_type() 1298 { 1270 1299 global $pagenow; 1271 1300 $type = 'post'; 1272 1301 1273 if ( in_array( $pagenow, array( 'user-edit.php', 'profile.php', 'user-new.php' ), true )) {1302 if (in_array($pagenow, array('user-edit.php', 'profile.php', 'user-new.php'), true)) { 1274 1303 $type = 'user'; 1275 1304 } 1276 1305 1277 if ( in_array( $pagenow, array( 'edit-comments.php', 'comment.php' ), true )) {1306 if (in_array($pagenow, array('edit-comments.php', 'comment.php'), true)) { 1278 1307 $type = 'comment'; 1279 1308 } 1280 1309 1281 if ( in_array( $pagenow, array( 'edit-tags.php', 'term.php' ), true )) {1310 if (in_array($pagenow, array('edit-tags.php', 'term.php'), true)) { 1282 1311 $type = 'term'; 1283 1312 } 1284 1313 1285 if ( defined( 'DOING_AJAX' ) && isset( $_POST['action'] ) && 'add-tag' === $_POST['action']) {1314 if (defined('DOING_AJAX') && isset($_POST['action']) && 'add-tag' === $_POST['action']) { 1286 1315 $type = 'term'; 1287 1316 } 1288 1317 1289 1318 if ( 1290 in_array( $pagenow, array( 'admin.php', 'admin-post.php' ), true)1319 in_array($pagenow, array('admin.php', 'admin-post.php'), true) 1291 1320 && $this->doing_options_page() 1292 1321 ) { … … 1305 1334 * @return mixed Metabox config property value or false. 1306 1335 */ 1307 public function set_prop( $property, $value ) { 1308 $this->meta_box[ $property ] = $value; 1309 1310 return $this->prop( $property ); 1336 public function set_prop($property, $value) 1337 { 1338 $this->meta_box[$property] = $value; 1339 1340 return $this->prop($property); 1311 1341 } 1312 1342 … … 1319 1349 * @return mixed Metabox config property value or false. 1320 1350 */ 1321 public function prop( $property, $fallback = null ) { 1322 if ( array_key_exists( $property, $this->meta_box ) ) { 1323 return $this->meta_box[ $property ]; 1324 } elseif ( $fallback ) { 1325 return $this->meta_box[ $property ] = $fallback; 1351 public function prop($property, $fallback = null) 1352 { 1353 if (array_key_exists($property, $this->meta_box)) { 1354 return $this->meta_box[$property]; 1355 } elseif ($fallback) { 1356 return $this->meta_box[$property] = $fallback; 1326 1357 } 1327 1358 } … … 1338 1369 * @return CMB2_Field|false CMB2_Field object (or false). 1339 1370 */ 1340 public function get_field( $field, $field_group = null, $reset_cached = false ) { 1341 if ( $field instanceof CMB2_Field ) { 1371 public function get_field($field, $field_group = null, $reset_cached = false) 1372 { 1373 if ($field instanceof CMB2_Field) { 1342 1374 return $field; 1343 1375 } 1344 1376 1345 $field_id = is_string( $field) ? $field : $field['id'];1346 1347 $parent_field_id = ! empty( $field_group) ? $field_group->id() : '';1348 $ids = $this->get_field_ids( $field_id, $parent_field_id);1349 1350 if ( ! $ids) {1377 $field_id = is_string($field) ? $field : $field['id']; 1378 1379 $parent_field_id = ! empty($field_group) ? $field_group->id() : ''; 1380 $ids = $this->get_field_ids($field_id, $parent_field_id); 1381 1382 if (! $ids) { 1351 1383 return false; 1352 1384 } 1353 1385 1354 list( $field_id, $sub_field_id) = $ids;1355 1356 $index = implode( '', $ids ) . ( $field_group ? $field_group->index : '');1357 1358 if ( array_key_exists( $index, $this->fields ) && ! $reset_cached) {1359 return $this->fields[ $index];1360 } 1361 1362 $this->fields[ $index ] = new CMB2_Field( $this->get_field_args( $field_id, $field, $sub_field_id, $field_group ));1363 1364 return $this->fields[ $index];1386 list($field_id, $sub_field_id) = $ids; 1387 1388 $index = implode('', $ids) . ($field_group ? $field_group->index : ''); 1389 1390 if (array_key_exists($index, $this->fields) && ! $reset_cached) { 1391 return $this->fields[$index]; 1392 } 1393 1394 $this->fields[$index] = new CMB2_Field($this->get_field_args($field_id, $field, $sub_field_id, $field_group)); 1395 1396 return $this->fields[$index]; 1365 1397 } 1366 1398 … … 1375 1407 * @return array Array of CMB2_Field arguments. 1376 1408 */ 1377 public function get_field_args( $field_id, $field_args, $sub_field_id, $field_group ) { 1409 public function get_field_args($field_id, $field_args, $sub_field_id, $field_group) 1410 { 1378 1411 1379 1412 // Check if group is passed and if fields were added in the old-school fields array. 1380 if ( $field_group && ( $sub_field_id || 0 === $sub_field_id )) {1413 if ($field_group && ($sub_field_id || 0 === $sub_field_id)) { 1381 1414 1382 1415 // Update the fields array w/ any modified properties inherited from the group field. 1383 $this->meta_box['fields'][ $field_id ]['fields'][ $sub_field_id] = $field_args;1384 1385 return $this->get_default_args( $field_args, $field_group);1386 } 1387 1388 if ( is_array( $field_args )) {1389 $this->meta_box['fields'][ $field_id ] = array_merge( $field_args, $this->meta_box['fields'][ $field_id ]);1390 } 1391 1392 return $this->get_default_args( $this->meta_box['fields'][ $field_id ]);1416 $this->meta_box['fields'][$field_id]['fields'][$sub_field_id] = $field_args; 1417 1418 return $this->get_default_args($field_args, $field_group); 1419 } 1420 1421 if (is_array($field_args)) { 1422 $this->meta_box['fields'][$field_id] = array_merge($field_args, $this->meta_box['fields'][$field_id]); 1423 } 1424 1425 return $this->get_default_args($this->meta_box['fields'][$field_id]); 1393 1426 } 1394 1427 … … 1401 1434 * @return array Array of field arguments. 1402 1435 */ 1403 protected function get_default_args( $field_args, $field_group = null ) { 1404 if ( $field_group ) { 1436 protected function get_default_args($field_args, $field_group = null) 1437 { 1438 if ($field_group) { 1405 1439 $args = array( 1406 1440 'field_args' => $field_args, … … 1428 1462 * @return CMB2 1429 1463 */ 1430 protected function add_fields( $fields, $parent_field_id = null ) { 1431 foreach ( $fields as $field ) { 1464 protected function add_fields($fields, $parent_field_id = null) 1465 { 1466 foreach ($fields as $field) { 1432 1467 1433 1468 $sub_fields = false; 1434 if ( array_key_exists( 'fields', $field )) {1469 if (array_key_exists('fields', $field)) { 1435 1470 $sub_fields = $field['fields']; 1436 unset( $field['fields']);1471 unset($field['fields']); 1437 1472 } 1438 1473 1439 1474 $field_id = $parent_field_id 1440 ? $this->add_group_field( $parent_field_id, $field)1441 : $this->add_field( $field);1442 1443 if ( $sub_fields) {1444 $this->add_fields( $sub_fields, $field_id);1475 ? $this->add_group_field($parent_field_id, $field) 1476 : $this->add_field($field); 1477 1478 if ($sub_fields) { 1479 $this->add_fields($sub_fields, $field_id); 1445 1480 } 1446 1481 } … … 1457 1492 * @return string|false Field id or false. 1458 1493 */ 1459 public function add_field( array $field, $position = 0 ) { 1460 if ( ! array_key_exists( 'id', $field ) ) { 1494 public function add_field(array $field, $position = 0) 1495 { 1496 if (! array_key_exists('id', $field)) { 1461 1497 return false; 1462 1498 } 1463 1499 1464 1500 // Perform some field-type-specific initiation actions. 1465 switch ( $field['type']) {1501 switch ($field['type']) { 1466 1502 case 'file': 1467 1503 case 'file_list': 1468 1504 // Initiate attachment JS hooks. 1469 add_filter( 'wp_prepare_attachment_for_js', array( 'CMB2_Type_File_Base', 'prepare_image_sizes_for_js' ), 10, 3);1505 add_filter('wp_prepare_attachment_for_js', array('CMB2_Type_File_Base', 'prepare_image_sizes_for_js'), 10, 3); 1470 1506 break; 1471 1507 … … 1476 1512 1477 1513 case 'group': 1478 if ( empty( $field['render_row_cb'] )) {1479 $field['render_row_cb'] = array( $this, 'render_group_callback');1514 if (empty($field['render_row_cb'])) { 1515 $field['render_row_cb'] = array($this, 'render_group_callback'); 1480 1516 } 1481 1517 break; … … 1484 1520 // Dequeue the rgba_colorpicker custom field script if it is used, 1485 1521 // since we now enqueue our own more current version. 1486 add_action( 'admin_enqueue_scripts', array( 'CMB2_Type_Colorpicker', 'dequeue_rgba_colorpicker_script' ), 99);1522 add_action('admin_enqueue_scripts', array('CMB2_Type_Colorpicker', 'dequeue_rgba_colorpicker_script'), 99); 1487 1523 break; 1488 1524 } 1489 1525 1490 if ( isset( $field['column'] ) && false !== $field['column']) {1491 $field = $this->define_field_column( $field);1492 } 1493 1494 if ( isset( $field['taxonomy'] ) && ! empty( $field['remove_default'] )) {1495 $this->tax_metaboxes_to_remove[ $field['taxonomy']] = $field['taxonomy'];1526 if (isset($field['column']) && false !== $field['column']) { 1527 $field = $this->define_field_column($field); 1528 } 1529 1530 if (isset($field['taxonomy']) && ! empty($field['remove_default'])) { 1531 $this->tax_metaboxes_to_remove[$field['taxonomy']] = $field['taxonomy']; 1496 1532 } 1497 1533 … … 1512 1548 * @return array Modified metabox field config array. 1513 1549 */ 1514 protected function define_field_column( array $field ) { 1550 protected function define_field_column(array $field) 1551 { 1515 1552 $this->has_columns = true; 1516 1553 1517 $column = is_array( $field['column']) ? $field['column'] : array();1518 1519 $field['column'] = wp_parse_args( $column, array(1520 'name' => isset( $field['name']) ? $field['name'] : '',1554 $column = is_array($field['column']) ? $field['column'] : array(); 1555 1556 $field['column'] = wp_parse_args($column, array( 1557 'name' => isset($field['name']) ? $field['name'] : '', 1521 1558 'position' => false, 1522 ) );1559 )); 1523 1560 1524 1561 return $field; … … 1534 1571 * @return mixed Array of parent/field ids or false. 1535 1572 */ 1536 public function add_group_field( $parent_field_id, array $field, $position = 0 ) { 1537 if ( ! array_key_exists( $parent_field_id, $this->meta_box['fields'] ) ) { 1573 public function add_group_field($parent_field_id, array $field, $position = 0) 1574 { 1575 if (! array_key_exists($parent_field_id, $this->meta_box['fields'])) { 1538 1576 return false; 1539 1577 } 1540 1578 1541 $parent_field = $this->meta_box['fields'][ $parent_field_id];1542 1543 if ( 'group' !== $parent_field['type']) {1579 $parent_field = $this->meta_box['fields'][$parent_field_id]; 1580 1581 if ('group' !== $parent_field['type']) { 1544 1582 return false; 1545 1583 } 1546 1584 1547 if ( ! isset( $parent_field['fields'] )) {1548 $this->meta_box['fields'][ $parent_field_id]['fields'] = array();1585 if (! isset($parent_field['fields'])) { 1586 $this->meta_box['fields'][$parent_field_id]['fields'] = array(); 1549 1587 } 1550 1588 1551 1589 $this->_add_field_to_array( 1552 1590 $field, 1553 $this->meta_box['fields'][ $parent_field_id]['fields'],1591 $this->meta_box['fields'][$parent_field_id]['fields'], 1554 1592 $position 1555 1593 ); 1556 1594 1557 return array( $parent_field_id, $field['id']);1595 return array($parent_field_id, $field['id']); 1558 1596 } 1559 1597 … … 1566 1604 * @param integer $position Optionally specify a position in the array to be inserted. 1567 1605 */ 1568 protected function _add_field_to_array( $field, &$fields, $position = 0 ) { 1569 if ( $position ) { 1570 CMB2_Utils::array_insert( $fields, array( $field['id'] => $field ), $position ); 1606 protected function _add_field_to_array($field, &$fields, $position = 0) 1607 { 1608 if ($position) { 1609 CMB2_Utils::array_insert($fields, array($field['id'] => $field), $position); 1571 1610 } else { 1572 $fields[ $field['id']] = $field;1611 $fields[$field['id']] = $field; 1573 1612 } 1574 1613 } … … 1582 1621 * @return bool True if field was removed. 1583 1622 */ 1584 public function remove_field( $field_id, $parent_field_id = '' ) { 1585 $ids = $this->get_field_ids( $field_id, $parent_field_id ); 1586 1587 if ( ! $ids ) { 1623 public function remove_field($field_id, $parent_field_id = '') 1624 { 1625 $ids = $this->get_field_ids($field_id, $parent_field_id); 1626 1627 if (! $ids) { 1588 1628 return false; 1589 1629 } 1590 1630 1591 list( $field_id, $sub_field_id) = $ids;1592 1593 unset( $this->fields[ implode( '', $ids ) ]);1594 1595 if ( ! $sub_field_id) {1596 unset( $this->meta_box['fields'][ $field_id ]);1631 list($field_id, $sub_field_id) = $ids; 1632 1633 unset($this->fields[implode('', $ids)]); 1634 1635 if (! $sub_field_id) { 1636 unset($this->meta_box['fields'][$field_id]); 1597 1637 return true; 1598 1638 } 1599 1639 1600 if ( isset( $this->fields[ $field_id ]->args['fields'][ $sub_field_id ] )) {1601 unset( $this->fields[ $field_id ]->args['fields'][ $sub_field_id ]);1602 } 1603 if ( isset( $this->meta_box['fields'][ $field_id ]['fields'][ $sub_field_id ] )) {1604 unset( $this->meta_box['fields'][ $field_id ]['fields'][ $sub_field_id ]);1640 if (isset($this->fields[$field_id]->args['fields'][$sub_field_id])) { 1641 unset($this->fields[$field_id]->args['fields'][$sub_field_id]); 1642 } 1643 if (isset($this->meta_box['fields'][$field_id]['fields'][$sub_field_id])) { 1644 unset($this->meta_box['fields'][$field_id]['fields'][$sub_field_id]); 1605 1645 } 1606 1646 … … 1618 1658 * @return mixed Field id. Strict compare to false, as success can return a falsey value (like 0). 1619 1659 */ 1620 public function update_field_property( $field_id, $property, $value, $parent_field_id = '' ) { 1621 $ids = $this->get_field_ids( $field_id, $parent_field_id ); 1622 1623 if ( ! $ids ) { 1660 public function update_field_property($field_id, $property, $value, $parent_field_id = '') 1661 { 1662 $ids = $this->get_field_ids($field_id, $parent_field_id); 1663 1664 if (! $ids) { 1624 1665 return false; 1625 1666 } 1626 1667 1627 list( $field_id, $sub_field_id) = $ids;1628 1629 if ( ! $sub_field_id) {1630 $this->meta_box['fields'][ $field_id ][ $property] = $value;1668 list($field_id, $sub_field_id) = $ids; 1669 1670 if (! $sub_field_id) { 1671 $this->meta_box['fields'][$field_id][$property] = $value; 1631 1672 return $field_id; 1632 1673 } 1633 1674 1634 $this->meta_box['fields'][ $field_id ]['fields'][ $sub_field_id ][ $property] = $value;1675 $this->meta_box['fields'][$field_id]['fields'][$sub_field_id][$property] = $value; 1635 1676 return $field_id; 1636 1677 } … … 1644 1685 * @return mixed Array of field/parent ids, or false. 1645 1686 */ 1646 public function get_field_ids( $field_id, $parent_field_id = '' ) { 1687 public function get_field_ids($field_id, $parent_field_id = '') 1688 { 1647 1689 $sub_field_id = $parent_field_id ? $field_id : ''; 1648 1690 $field_id = $parent_field_id ? $parent_field_id : $field_id; 1649 $fields = &$this->meta_box['fields'];1650 1651 if ( ! array_key_exists( $field_id, $fields )) {1652 $field_id = $this->search_old_school_array( $field_id, $fields);1653 } 1654 1655 if ( false === $field_id) {1691 $fields = &$this->meta_box['fields']; 1692 1693 if (! array_key_exists($field_id, $fields)) { 1694 $field_id = $this->search_old_school_array($field_id, $fields); 1695 } 1696 1697 if (false === $field_id) { 1656 1698 return false; 1657 1699 } 1658 1700 1659 if ( ! $sub_field_id) {1660 return array( $field_id, $sub_field_id);1661 } 1662 1663 if ( 'group' !== $fields[ $field_id ]['type']) {1701 if (! $sub_field_id) { 1702 return array($field_id, $sub_field_id); 1703 } 1704 1705 if ('group' !== $fields[$field_id]['type']) { 1664 1706 return false; 1665 1707 } 1666 1708 1667 if ( ! array_key_exists( $sub_field_id, $fields[ $field_id ]['fields'] )) {1668 $sub_field_id = $this->search_old_school_array( $sub_field_id, $fields[ $field_id ]['fields']);1669 } 1670 1671 return false === $sub_field_id ? false : array( $field_id, $sub_field_id);1709 if (! array_key_exists($sub_field_id, $fields[$field_id]['fields'])) { 1710 $sub_field_id = $this->search_old_school_array($sub_field_id, $fields[$field_id]['fields']); 1711 } 1712 1713 return false === $sub_field_id ? false : array($field_id, $sub_field_id); 1672 1714 } 1673 1715 … … 1680 1722 * @return mixed Field index or false. 1681 1723 */ 1682 public function search_old_school_array( $field_id, $fields ) { 1683 $ids = wp_list_pluck( $fields, 'id' ); 1684 $index = array_search( $field_id, $ids ); 1724 public function search_old_school_array($field_id, $fields) 1725 { 1726 $ids = wp_list_pluck($fields, 'id'); 1727 $index = array_search($field_id, $ids); 1685 1728 return false !== $index ? $index : false; 1686 1729 } … … 1694 1737 * @return mixed Return of the callback function. 1695 1738 */ 1696 public function do_callback( $cb, $additional_params = null ) { 1697 return call_user_func( $cb, $this, $additional_params ); 1739 public function do_callback($cb, $additional_params = null) 1740 { 1741 return call_user_func($cb, $this, $additional_params); 1698 1742 } 1699 1743 … … 1704 1748 * @return void 1705 1749 */ 1706 public function nonce_field() { 1707 wp_nonce_field( $this->nonce(), $this->nonce(), false, true ); 1750 public function nonce_field() 1751 { 1752 wp_nonce_field($this->nonce(), $this->nonce(), false, true); 1708 1753 } 1709 1754 … … 1714 1759 * @return string unique nonce string. 1715 1760 */ 1716 public function nonce() { 1717 if ( ! $this->generated_nonce ) { 1718 $this->generated_nonce = sanitize_html_class( 'nonce_' . basename( __FILE__ ) . $this->cmb_id ); 1761 public function nonce() 1762 { 1763 if (! $this->generated_nonce) { 1764 $this->generated_nonce = sanitize_html_class('nonce_' . basename(__FILE__) . $this->cmb_id); 1719 1765 } 1720 1766 … … 1729 1775 * @return bool 1730 1776 */ 1731 public function was_updated() { 1732 return ! empty( $this->updated ); 1777 public function was_updated() 1778 { 1779 return ! empty($this->updated); 1733 1780 } 1734 1781 … … 1740 1787 * @return bool 1741 1788 */ 1742 public function is_alternate_context_box() { 1743 return $this->prop( 'context' ) && in_array( $this->prop( 'context' ), array( 'form_top', 'before_permalink', 'after_title', 'after_editor' ), true ); 1789 public function is_alternate_context_box() 1790 { 1791 return $this->prop('context') && in_array($this->prop('context'), array('form_top', 'before_permalink', 'after_title', 'after_editor'), true); 1744 1792 } 1745 1793 … … 1751 1799 * @return mixed 1752 1800 */ 1753 public function __get( $property ) { 1754 switch ( $property ) { 1801 public function __get($property) 1802 { 1803 switch ($property) { 1755 1804 case 'updated': 1756 1805 case 'has_columns': … … 1758 1807 return $this->{$property}; 1759 1808 default: 1760 return parent::__get( $property ); 1761 } 1762 } 1763 1809 return parent::__get($property); 1810 } 1811 } 1764 1812 } -
magical-posts-display/trunk/assets/css/admin-style.css
r3235168 r3380394 53 53 } 54 54 55 55 /* Enhanced Admin Notice Styles with Animation */ 56 56 .mgadin-hero { 57 padding: 20px 10px; 57 background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); 58 border: 2px solid #e3f2fd; 59 border-radius: 12px; 60 padding: 25px; 61 margin: 20px 0; 58 62 display: flex; 59 63 align-items: center; 64 box-shadow: 0 8px 25px rgba(0, 123, 255, 0.1); 65 position: relative; 66 overflow: hidden; 67 animation: slideInFromTop 0.6s ease-out; 68 transition: all 0.3s ease; 69 } 70 71 .mgadin-hero:hover { 72 box-shadow: 0 12px 35px rgba(0, 123, 255, 0.15); 73 transform: translateY(-2px); 74 } 75 76 /* Animated Background Gradient */ 77 .mgadin-hero::before { 78 content: ''; 79 position: absolute; 80 top: 0; 81 left: -100%; 82 width: 100%; 83 height: 100%; 84 background: linear-gradient(90deg, transparent, rgba(0, 123, 255, 0.05), transparent); 85 animation: shimmer 3s infinite; 86 } 87 88 /* Content Container */ 89 .mge-info-content { 90 flex: 1; 91 z-index: 2; 92 position: relative; 60 93 } 61 94 62 95 .mge-info-hello { 63 96 font-weight: 700; 64 font-size: 16px; 97 font-size: 18px; 98 color: #2c3e50; 99 margin-bottom: 8px; 100 animation: fadeInUp 0.8s ease-out 0.2s both; 65 101 } 66 102 67 103 .mge-info-title { 68 font-size: 2 2px;104 font-size: 24px; 69 105 display: block; 70 line-height: 1.5; 71 font-weight: 500; 72 } 73 74 .mge-info-desc div { 75 margin-bottom: 10px; 106 line-height: 1.4; 107 font-weight: 600; 108 color: #1a202c; 109 animation: fadeInUp 0.8s ease-out 0.3s both; 76 110 } 77 111 78 112 .mge-info-desc { 79 113 font-size: 16px; 80 line-height: 1.3; 81 margin: 10px 0 20px; 114 line-height: 1.5; 115 margin: 15px 0 25px; 116 color: #4a5568; 117 } 118 119 .mge-info-desc div { 120 margin-bottom: 12px; 121 animation: fadeInUp 0.8s ease-out 0.4s both; 122 } 123 124 .mge-info-desc div.mge-offer { 125 background: linear-gradient(45deg, #ff6b6b, #ff8e53); 126 background-clip: text; 127 -webkit-background-clip: text; 128 -webkit-text-fill-color: transparent; 129 font-weight: 700; 130 font-size: 17px; 131 padding: 10px 15px; 132 border-left: 4px solid #ff6b6b; 133 background-color: rgba(255, 107, 107, 0.1); 134 border-radius: 6px; 135 animation: pulse 2s infinite, fadeInUp 0.8s ease-out 0.5s both; 82 136 } 83 137 … … 85 139 display: flex; 86 140 align-items: center; 141 gap: 15px; 142 animation: fadeInUp 0.8s ease-out 0.6s both; 87 143 } 88 144 … … 90 146 display: inline-flex; 91 147 align-items: center; 92 padding: 5px 20px;148 padding: 12px 24px; 93 149 font-size: 16px; 94 margin-right: 15px; 150 font-weight: 600; 151 border-radius: 8px; 152 text-decoration: none; 153 transition: all 0.3s ease; 154 position: relative; 155 overflow: hidden; 156 } 157 158 .mge-info-actions a.button::before { 159 content: ''; 160 position: absolute; 161 top: 50%; 162 left: 50%; 163 width: 0; 164 height: 0; 165 background: rgba(255, 255, 255, 0.2); 166 border-radius: 50%; 167 transform: translate(-50%, -50%); 168 transition: width 0.3s ease, height 0.3s ease; 169 } 170 171 .mge-info-actions a.button:hover::before { 172 width: 300px; 173 height: 300px; 174 } 175 176 .mge-info-actions .upgrade-btn { 177 background: linear-gradient(45deg, #007cba, #0096dc); 178 color: white; 179 border: none; 180 box-shadow: 0 4px 15px rgba(0, 124, 186, 0.3); 181 animation: buttonBounce 2s infinite; 182 } 183 184 .mge-info-actions .upgrade-btn:hover { 185 background: linear-gradient(45deg, #005a87, #007bb5); 186 box-shadow: 0 6px 20px rgba(0, 124, 186, 0.4); 187 transform: translateY(-2px); 188 } 189 190 .mge-info-actions .demo-btn { 191 background: linear-gradient(45deg, #28a745, #20c997); 192 color: white; 193 border: none; 194 box-shadow: 0 4px 15px rgba(40, 167, 69, 0.3); 195 } 196 197 .mge-info-actions .demo-btn:hover { 198 background: linear-gradient(45deg, #218838, #1ea379); 199 box-shadow: 0 6px 20px rgba(40, 167, 69, 0.4); 200 transform: translateY(-2px); 201 } 202 203 .mge-info-actions .mgad-dismiss { 204 background: transparent; 205 border: 2px solid #6c757d; 206 color: #6c757d; 207 padding: 10px 20px; 208 border-radius: 6px; 209 font-size: 14px; 210 transition: all 0.3s ease; 211 } 212 213 .mge-info-actions .mgad-dismiss:hover { 214 background: #6c757d; 215 color: white; 216 transform: translateY(-1px); 95 217 } 96 218 … … 99 221 } 100 222 223 /* Keyframe Animations */ 224 @keyframes slideInFromTop { 225 0% { 226 opacity: 0; 227 transform: translateY(-30px); 228 } 229 100% { 230 opacity: 1; 231 transform: translateY(0); 232 } 233 } 234 235 @keyframes fadeInUp { 236 0% { 237 opacity: 0; 238 transform: translateY(20px); 239 } 240 100% { 241 opacity: 1; 242 transform: translateY(0); 243 } 244 } 245 246 @keyframes shimmer { 247 0% { 248 left: -100%; 249 } 250 100% { 251 left: 100%; 252 } 253 } 254 255 @keyframes pulse { 256 0%, 100% { 257 transform: scale(1); 258 } 259 50% { 260 transform: scale(1.02); 261 } 262 } 263 264 @keyframes buttonBounce { 265 0%, 20%, 50%, 80%, 100% { 266 transform: translateY(0); 267 } 268 40% { 269 transform: translateY(-3px); 270 } 271 60% { 272 transform: translateY(-2px); 273 } 274 } 275 276 /* Responsive Design */ 277 @media (max-width: 768px) { 278 .mgadin-hero { 279 flex-direction: column; 280 text-align: center; 281 padding: 20px; 282 } 283 284 .mge-info-actions { 285 flex-direction: column; 286 width: 100%; 287 gap: 10px; 288 } 289 290 .mge-info-actions a.button { 291 width: 100%; 292 justify-content: center; 293 } 294 } 295 296 /* Additional Enhancement Elements */ 297 .mgadin-hero::after { 298 content: '🚀'; 299 position: absolute; 300 top: 20px; 301 right: 20px; 302 font-size: 24px; 303 animation: float 3s ease-in-out infinite; 304 } 305 306 @keyframes float { 307 0%, 100% { 308 transform: translateY(0); 309 } 310 50% { 311 transform: translateY(-10px); 312 } 313 } 314 315 /* Enhanced Image and Review Styles */ 101 316 .mge-info-image { 102 317 flex: 0 0 400px; 103 318 overflow: hidden; 319 border-radius: 8px; 320 animation: fadeInUp 0.8s ease-out 0.7s both; 104 321 } 105 322 … … 107 324 max-width: 100%; 108 325 min-width: 200px; 326 border-radius: 8px; 327 transition: transform 0.3s ease; 328 } 329 330 .mge-info-image img:hover { 331 transform: scale(1.05); 109 332 } 110 333 … … 113 336 display: block; 114 337 font-size: 15px; 338 color: #2c3e50; 339 font-weight: 600; 115 340 } 116 341 … … 118 343 display: flex; 119 344 align-items: center; 120 } 121 122 .mge-info-desc div.mge-offer { 123 color: #a30000; 124 font-weight: 700; 345 gap: 15px; 125 346 } 126 347 127 348 .mge-info-rev .button { 128 padding: 5px 20px !important;349 padding: 8px 20px !important; 129 350 display: inline-flex; 130 351 justify-content: center; 131 352 align-items: center; 132 353 height: 100%; 133 margin-right: 10px;134 354 font-size: 15px !important; 135 } 355 border-radius: 6px; 356 transition: all 0.3s ease; 357 } -
magical-posts-display/trunk/assets/css/mgadmin-page.css
r2608250 r3380394 84 84 } 85 85 a.button.button-mgp1 { 86 background: #000 ;87 color: #fff; 88 padding: 5px 25px;89 margin -top: 10px;86 background: #000000; 87 color: #fff; 88 padding: 12px 45px; 89 margin: 10px; 90 90 font-size: 1rem; 91 91 min-height: 38px; 92 92 display: inline-block; 93 border-radius: 5px; 94 transition: 0.5s; 95 border: none; 96 font-weight: 600; 97 } 98 a.button.button-mgp1.btnprohas { 99 background: #700000; 100 color: #fff; 101 } 102 a.button.button-mgp1.btnprohas:hover { 103 background: #460000; 104 color: #fff; 93 105 } 94 106 .mgftext { -
magical-posts-display/trunk/assets/css/mp-style.css
r3324281 r3380394 884 884 font-size: 18px; 885 885 color: #fff; 886 line-height: 20px;886 line-height: 1.5; 887 887 } 888 888 .mgs-btn { … … 920 920 padding: 3px 0px 4px; 921 921 font-size: 14px; 922 margin-bottom: 10px; 922 margin-bottom: 20px; 923 display: inline-block; 923 924 } 924 925 .mgs-content a.mp-post-btn.link1 { … … 1657 1658 } 1658 1659 } 1660 1661 /* Enhanced Masonry Layout Styles */ 1662 .mgpd-masonry-container { 1663 position: relative; 1664 margin-bottom: 30px; 1665 overflow: hidden; 1666 } 1667 1668 .mgpd-masonry { 1669 align-items: flex-start; 1670 position: relative !important; 1671 height: auto !important; 1672 min-height: 400px; 1673 } 1674 1675 .mgpd-masonry-item { 1676 margin-bottom: 1.5rem; 1677 width: 100%; 1678 position: relative; 1679 } 1680 1681 /* Prevent layout jumping during load */ 1682 .mgpd-masonry-container:not(.masonry-loaded) .mgpd-masonry { 1683 opacity: 0; 1684 transition: opacity 0.3s ease; 1685 } 1686 1687 .mgpd-masonry-container.masonry-loaded .mgpd-masonry { 1688 opacity: 1; 1689 } 1690 1691 /* Fix for items overlapping footer */ 1692 .mgpd-masonry::after { 1693 content: ''; 1694 display: block; 1695 clear: both; 1696 height: 0; 1697 } 1698 1699 /* Ensure proper container bounds */ 1700 .mgpd { 1701 position: relative; 1702 z-index: 1; 1703 margin-bottom: 40px; 1704 } 1705 1706 /* Specific column widths for masonry */ 1707 .mgpd-masonry .mgpd-masonry-item.col-lg-4 { 1708 width: 33.333333%; 1709 } 1710 1711 .mgpd-masonry .mgpd-masonry-item.col-lg-3 { 1712 width: 25%; 1713 } 1714 1715 .mgpd-masonry .mgpd-masonry-item.col-lg-6 { 1716 width: 50%; 1717 } 1718 1719 .mgpd-masonry .mgpd-masonry-item.col-lg-12 { 1720 width: 100%; 1721 } 1722 1723 .mgpd-masonry .mgpd-masonry-item.col-lg-2 { 1724 width: 16.666667%; 1725 } 1726 1727 /* Ensure images are responsive in masonry layout */ 1728 .mgpd-masonry .mg-card img { 1729 width: 100%; 1730 height: auto; 1731 display: block; 1732 } 1733 1734 /* Masonry item transition effects */ 1735 .mgpd-masonry-item { 1736 transition: transform 0.3s ease; 1737 } 1738 1739 .mgpd-masonry-item:hover { 1740 transform: translateY(-2px); 1741 } 1742 1743 /* Responsive masonry adjustments */ 1744 @media (max-width: 991.98px) { 1745 .mgpd-masonry .mgpd-masonry-item.col-lg-4, 1746 .mgpd-masonry .mgpd-masonry-item.col-lg-3, 1747 .mgpd-masonry .mgpd-masonry-item.col-lg-2 { 1748 width: 50%; 1749 } 1750 1751 .mgpd-masonry-item { 1752 margin-bottom: 1rem; 1753 } 1754 } 1755 1756 @media (max-width: 767.98px) { 1757 .mgpd-masonry .mgpd-masonry-item { 1758 width: 100% !important; 1759 margin-bottom: 1rem; 1760 } 1761 } 1762 1763 /* Loading state for masonry */ 1764 .mgpd-masonry-container:not(.masonry-loaded) .mgpd-masonry-item { 1765 opacity: 0; 1766 transform: translateY(20px); 1767 } 1768 1769 .mgpd-masonry-container.masonry-loaded .mgpd-masonry-item { 1770 opacity: 1; 1771 transform: translateY(0); 1772 transition: opacity 0.3s ease, transform 0.3s ease; 1773 } 1774 1775 /* Elementor Editor Mode Fix - Ensure items always visible in editor */ 1776 .elementor-editor-active .mgpd-masonry-container .mgpd-masonry-item { 1777 opacity: 1 !important; 1778 transform: none !important; 1779 visibility: visible !important; 1780 position: relative !important; 1781 } 1782 1783 /* Force masonry container to show properly in editor */ 1784 .elementor-editor-active .mgpd-masonry { 1785 display: flex !important; 1786 flex-wrap: wrap !important; 1787 height: auto !important; 1788 } 1789 1790 /* Masonry Style Variations */ 1791 1792 /* Style 1 - Default Heights (all images same height) */ 1793 .mgpd-masonry-style1 .mgpd-masonry-item .mg-card .mp-post-img figure { 1794 height: 200px; 1795 } 1796 1797 /* Style 2 - Alternating Heights (big then small pattern) */ 1798 .mgpd-masonry-style2 .mgpd-masonry-item:nth-child(odd) .mg-card .mp-post-img figure { 1799 height: 300px; 1800 } 1801 1802 .mgpd-masonry-style2 .mgpd-masonry-item:nth-child(even) .mg-card .mp-post-img figure { 1803 height: 180px; 1804 } 1805 1806 /* Style 3 - Pattern Heights (two big, one small repeating pattern) */ 1807 .mgpd-masonry-style3 .mgpd-masonry-item:nth-child(3n+1) .mg-card .mp-post-img figure, 1808 .mgpd-masonry-style3 .mgpd-masonry-item:nth-child(3n+2) .mg-card .mp-post-img figure { 1809 height: 280px; 1810 } 1811 1812 .mgpd-masonry-style3 .mgpd-masonry-item:nth-child(3n) .mg-card .mp-post-img figure { 1813 height: 160px; 1814 } 1815 1816 /* Ensure images cover the full height */ 1817 .mgpd-masonry-container .mg-card .mp-post-img figure img { 1818 width: 100%; 1819 height: 100%; 1820 object-fit: cover; 1821 object-position: center; 1822 } 1823 1824 /* Responsive adjustments for masonry styles */ 1825 @media (max-width: 991.98px) { 1826 .mgpd-masonry-style1 .mgpd-masonry-item .mg-card .mp-post-img figure, 1827 .mgpd-masonry-style2 .mgpd-masonry-item .mg-card .mp-post-img figure, 1828 .mgpd-masonry-style3 .mgpd-masonry-item .mg-card .mp-post-img figure { 1829 height: 200px; 1830 } 1831 } 1832 1833 @media (max-width: 767.98px) { 1834 .mgpd-masonry-style1 .mgpd-masonry-item .mg-card .mp-post-img figure, 1835 .mgpd-masonry-style2 .mgpd-masonry-item .mg-card .mp-post-img figure, 1836 .mgpd-masonry-style3 .mgpd-masonry-item .mg-card .mp-post-img figure { 1837 height: 180px; 1838 } 1839 } 1840 1841 /* Premium Features Styles (Pro Only) */ 1842 1843 /* AJAX Filter Buttons */ 1844 .mgpd-ajax-filter-container { 1845 margin-bottom: 30px; 1846 text-align: center; 1847 } 1848 1849 .mgpd-filter-buttons { 1850 display: flex; 1851 flex-wrap: wrap; 1852 justify-content: center; 1853 gap: 10px; 1854 } 1855 1856 .mgpd-filter-btn { 1857 background: #f8f9fa; 1858 border: 2px solid #dee2e6; 1859 color: #495057; 1860 padding: 8px 16px; 1861 border-radius: 25px; 1862 cursor: pointer; 1863 transition: all 0.3s ease; 1864 font-weight: 500; 1865 text-transform: capitalize; 1866 } 1867 1868 .mgpd-filter-btn:hover, 1869 .mgpd-filter-btn.active { 1870 background: #007cba; 1871 border-color: #007cba; 1872 color: #ffffff; 1873 transform: translateY(-2px); 1874 box-shadow: 0 4px 12px rgba(0, 124, 186, 0.3); 1875 } 1876 1877 /* Loading State */ 1878 .mgpd-loading .mg-card { 1879 opacity: 0.5; 1880 transition: opacity 0.3s ease; 1881 } 1882 1883 .mgpd-loading-spinner { 1884 color: #007cba; 1885 font-size: 16px; 1886 display: flex; 1887 align-items: center; 1888 justify-content: center; 1889 gap: 10px; 1890 } 1891 1892 .mgpd-loading-spinner .mgpd-spinner { 1893 animation: mgpd-spin 1s linear infinite; 1894 } 1895 1896 @keyframes mgpd-spin { 1897 0% { transform: rotate(0deg); } 1898 100% { transform: rotate(360deg); } 1899 } 1900 1901 /* Reading Time */ 1902 .mgpd-reading-time { 1903 display: inline-flex; 1904 align-items: center; 1905 gap: 5px; 1906 background: #e7f3ff; 1907 color: #0066cc; 1908 padding: 4px 10px; 1909 border-radius: 15px; 1910 font-size: 12px; 1911 margin: 8px 8px 8px 0; 1912 font-weight: 500; 1913 } 1914 1915 .mgpd-reading-time svg { 1916 width: 14px; 1917 height: 14px; 1918 flex-shrink: 0; 1919 } 1920 1921 /* View Count */ 1922 .mgpd-view-count { 1923 display: inline-flex; 1924 align-items: center; 1925 gap: 5px; 1926 background: #f0f8f0; 1927 color: #28a745; 1928 padding: 4px 10px; 1929 border-radius: 15px; 1930 font-size: 12px; 1931 margin: 8px 8px 8px 0; 1932 font-weight: 500; 1933 } 1934 1935 .mgpd-view-count svg { 1936 width: 14px; 1937 height: 14px; 1938 flex-shrink: 0; 1939 } 1940 1941 /* Social Share Buttons */ 1942 .mgpd-social-share { 1943 display: flex; 1944 gap: 8px; 1945 margin: 12px 0; 1946 } 1947 1948 .mgpd-social-share a { 1949 display: flex; 1950 align-items: center; 1951 justify-content: center; 1952 width: 32px; 1953 height: 32px; 1954 border-radius: 50%; 1955 text-decoration: none; 1956 transition: all 0.3s ease; 1957 font-size: 14px; 1958 } 1959 1960 .mgpd-share-facebook { 1961 background: #3b5998; 1962 color: #ffffff; 1963 } 1964 1965 .mgpd-share-facebook:hover { 1966 background: #2d4373; 1967 transform: translateY(-2px); 1968 box-shadow: 0 4px 12px rgba(59, 89, 152, 0.4); 1969 } 1970 1971 .mgpd-share-twitter { 1972 background: #000000; 1973 color: #ffffff; 1974 } 1975 1976 .mgpd-share-twitter:hover { 1977 background: #333333; 1978 transform: translateY(-2px); 1979 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); 1980 } 1981 1982 .mgpd-share-linkedin { 1983 background: #0077b5; 1984 color: #ffffff; 1985 } 1986 1987 .mgpd-share-linkedin:hover { 1988 background: #005885; 1989 transform: translateY(-2px); 1990 box-shadow: 0 4px 12px rgba(0, 119, 181, 0.4); 1991 } 1992 1993 .mgpd-share-pinterest { 1994 background: #bd081c; 1995 color: #ffffff; 1996 } 1997 1998 .mgpd-share-pinterest:hover { 1999 background: #8c0613; 2000 transform: translateY(-2px); 2001 box-shadow: 0 4px 12px rgba(189, 8, 28, 0.4); 2002 } 2003 2004 .mgpd-share-instagram { 2005 background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%); 2006 color: #ffffff; 2007 } 2008 2009 .mgpd-share-instagram:hover { 2010 opacity: 0.8; 2011 transform: translateY(-2px); 2012 box-shadow: 0 4px 12px rgba(188, 24, 136, 0.4); 2013 } 2014 2015 /* Premium Features Display Styles */ 2016 /* Image Top Style */ 2017 .mgpd-premium-image-top .mp-post-img { 2018 position: relative; 2019 } 2020 2021 .mgpd-premium-image-top .mgpd-premium-features { 2022 position: absolute; 2023 bottom: 10px; 2024 left: 0; 2025 right: 10px; 2026 z-index: 2; 2027 display: flex; 2028 flex-wrap: wrap; 2029 gap: 8px; 2030 align-items: center; 2031 width: 100%; 2032 justify-content: center; 2033 } 2034 2035 .mgpd-premium-image-top .mgpd-reading-time, 2036 .mgpd-premium-image-top .mgpd-view-count { 2037 background: rgba(255, 255, 255, 0.95); 2038 backdrop-filter: blur(10px); 2039 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); 2040 } 2041 2042 .mgpd-premium-image-top .mgpd-social-share { 2043 margin: 0; 2044 background: rgba(255, 255, 255, 0.95); 2045 backdrop-filter: blur(10px); 2046 padding: 6px; 2047 border-radius: 20px; 2048 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); 2049 } 2050 2051 /* Image Overlay Style */ 2052 .mgpd-premium-image-overlay .mp-post-img { 2053 position: relative; 2054 } 2055 .mp-post-img .mgpd-time-count-wrap { 2056 display: flex; 2057 justify-content: space-between; 2058 align-items: center; 2059 width: 100%; 2060 padding: 0 20px; 2061 } 2062 .mgpd-premium-image-overlay .mgpd-premium-features { 2063 position: absolute; 2064 bottom: 0; 2065 left: 0; 2066 right: 0; 2067 background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.6) 60%, transparent 100%); 2068 padding: 15px; 2069 opacity: 0; 2070 transform: translateY(10px); 2071 transition: all 0.3s ease; 2072 z-index: 2; 2073 } 2074 2075 .mgpd-premium-image-overlay .mg-card:hover .mgpd-premium-features { 2076 opacity: 1; 2077 transform: translateY(0); 2078 } 2079 2080 .mgpd-premium-image-overlay .mgpd-reading-time, 2081 .mgpd-premium-image-overlay .mgpd-view-count { 2082 background: rgba(255, 255, 255, 0.2); 2083 backdrop-filter: blur(10px); 2084 color: #ffffff; 2085 border: 1px solid rgba(255, 255, 255, 0.3); 2086 } 2087 2088 .mgpd-premium-image-overlay .mgpd-reading-time svg, 2089 .mgpd-premium-image-overlay .mgpd-view-count svg { 2090 fill: #ffffff; 2091 } 2092 2093 .mgpd-premium-image-overlay .mgpd-social-share { 2094 margin: 10px 0 0 0; 2095 justify-content: center; 2096 } 2097 2098 .mgpd-premium-image-overlay .mgpd-social-share a { 2099 border: 1px solid rgba(255, 255, 255, 0.3); 2100 backdrop-filter: blur(10px); 2101 } 2102 2103 /* Video Wrapper */ 2104 .mgpd-video-wrapper { 2105 position: relative; 2106 display: block; 2107 width: 100%; 2108 text-decoration: none; 2109 } 2110 2111 .mgpd-video-wrapper img { 2112 width: 100%; 2113 height: auto; 2114 display: block; 2115 } 2116 2117 .mgpd-video-wrapper .mgpd-video-play-icon { 2118 position: absolute; 2119 top: 50%; 2120 left: 50%; 2121 transform: translate(-50%, -50%); 2122 width: 60px; 2123 height: 60px; 2124 background: rgba(255, 0, 0, 0.9); 2125 border-radius: 50%; 2126 display: flex; 2127 align-items: center; 2128 justify-content: center; 2129 z-index: 2; 2130 transition: all 0.3s ease; 2131 pointer-events: none; 2132 } 2133 2134 .mgpd-video-wrapper:hover .mgpd-video-play-icon { 2135 background: rgba(255, 0, 0, 1); 2136 transform: translate(-50%, -50%) scale(1.15); 2137 } 2138 2139 .mgpd-video-wrapper .mgpd-video-play-icon::before { 2140 content: ''; 2141 width: 0; 2142 height: 0; 2143 border-style: solid; 2144 border-width: 12px 0 12px 20px; 2145 border-color: transparent transparent transparent #ffffff; 2146 margin-left: 3px; 2147 } 2148 2149 /* Hide premium features when video is present */ 2150 .mgpd-video-wrapper ~ .mgpd-premium-features, 2151 .mp-post-img:has(.mgpd-video-wrapper) .mgpd-premium-features { 2152 display: none !important; 2153 } 2154 2155 /* Placeholder Image */ 2156 .mgpd-placeholder-img { 2157 width: 100%; 2158 min-height: 250px; 2159 background: #ddd; 2160 display: flex; 2161 align-items: center; 2162 justify-content: center; 2163 position: relative; 2164 } 2165 2166 .mgpd-placeholder-img::before { 2167 content: 'No Image'; 2168 color: #999; 2169 font-size: 18px; 2170 font-weight: 500; 2171 text-transform: uppercase; 2172 letter-spacing: 2px; 2173 } 2174 2175 /* Advanced Hover Effects */ 2176 .mgpd-hover-zoom .mg-card { 2177 transition: transform 0.3s ease; 2178 overflow: hidden; 2179 } 2180 2181 .mgpd-hover-zoom .mg-card.mgpd-hover-active { 2182 transform: scale(1.05); 2183 box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); 2184 } 2185 2186 .mgpd-hover-zoom .mg-card .mp-post-img img { 2187 transition: transform 0.3s ease; 2188 } 2189 2190 .mgpd-hover-zoom .mg-card.mgpd-hover-active .mp-post-img img { 2191 transform: scale(1.1); 2192 } 2193 2194 .mgpd-hover-slide .mg-card { 2195 transition: transform 0.3s ease; 2196 } 2197 2198 .mgpd-hover-slide .mg-card.mgpd-hover-active { 2199 transform: translateY(-10px); 2200 box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15); 2201 } 2202 2203 .mgpd-hover-fade .mg-card { 2204 transition: opacity 0.3s ease; 2205 } 2206 2207 .mgpd-hover-fade .mg-card.mgpd-hover-active { 2208 opacity: 0.9; 2209 box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); 2210 } 2211 2212 .mgpd-hover-rotate .mg-card { 2213 transition: transform 0.3s ease; 2214 } 2215 2216 .mgpd-hover-rotate .mg-card.mgpd-hover-active { 2217 transform: rotate(2deg) scale(1.02); 2218 box-shadow: 0 12px 28px rgba(0, 0, 0, 0.15); 2219 } 2220 2221 /* Infinite Scroll Enhancements */ 2222 .mgpd-infinite-scroll-enabled { 2223 position: relative; 2224 } 2225 2226 .mgpd-infinite-scroll-trigger { 2227 visibility: hidden; 2228 } 2229 2230 /* Responsive Design for Premium Features */ 2231 @media (max-width: 768px) { 2232 .mgpd-filter-buttons { 2233 gap: 5px; 2234 } 2235 2236 .mgpd-filter-btn { 2237 padding: 6px 12px; 2238 font-size: 14px; 2239 } 2240 2241 .mgpd-social-share a { 2242 width: 28px; 2243 height: 28px; 2244 font-size: 12px; 2245 } 2246 2247 .mgpd-reading-time, 2248 .mgpd-view-count { 2249 font-size: 11px; 2250 padding: 3px 8px; 2251 } 2252 } 2253 2254 @media (max-width: 576px) { 2255 .mgpd-ajax-filter-container { 2256 margin-bottom: 20px; 2257 } 2258 2259 .mgpd-social-share { 2260 justify-content: center; 2261 gap: 6px; 2262 } 2263 2264 /* Disable complex hover effects on mobile */ 2265 .mgpd-hover-zoom .mg-card.mgpd-hover-active, 2266 .mgpd-hover-slide .mg-card.mgpd-hover-active, 2267 .mgpd-hover-rotate .mg-card.mgpd-hover-active { 2268 transform: none; 2269 } 2270 } -
magical-posts-display/trunk/assets/js/main.js
r2328226 r3380394 2 2 "use strict"; 3 3 4 // document ready function4 // Document ready function 5 5 jQuery(document).ready(function($){ 6 /*----- 7 Bootstrap carousel active 8 ----------------------*/ 9 /*var mobileSlider = $('.carousel'); 10 mobileSlider.carousel({ 11 interval: 8000, 6 // Show sticker lists 7 $('.mgpd-sticker ul').show(); 8 }); 9 10 // Enhanced masonry initialization for multiple containers 11 $(window).on('load', function() { 12 $('.mgpd-masonry').each(function() { 13 var $container = $(this); 14 var $wrapper = $container.closest('.mgpd-masonry-container'); 15 var container = this; 16 17 // Wait for images to load before initializing masonry 18 imagesLoaded(container, function() { 19 try { 20 var masonryInstance = new Masonry(container, { 21 itemSelector: '.mgpd-masonry-item', 22 percentPosition: true, 23 gutter: 0, 24 horizontalOrder: true, 25 fitWidth: false, 26 transitionDuration: 0 // Disable animation for initial load 27 }); 28 29 // Store masonry instance for later use 30 $container.data('masonry', masonryInstance); 31 32 // Force layout calculation after initialization 33 setTimeout(function() { 34 masonryInstance.layout(); 35 $container.css('height', 'auto'); 36 }, 100); 37 38 // Add loaded class for smooth appearance 39 $wrapper.addClass('masonry-loaded'); 40 41 } catch (error) { 42 console.error('MGPD: Error initializing masonry:', error); 43 } 12 44 }); 45 }); 46 47 // Initialize Premium Features if available 48 if (typeof initMGPDPremiumFeatures === 'function') { 49 initMGPDPremiumFeatures(); 50 } 51 }); 13 52 14 $('.awesome-carousel .carousel-inner .item:first-child').addClass('active');*/ 15 16 $('.mgpd-sticker ul').show(); 53 // Also initialize on DOM ready for faster loading 54 $(document).ready(function() { 55 // Pre-initialize masonry containers 56 $('.mgpd-masonry').each(function() { 57 var $container = $(this); 58 $container.css('min-height', '600px'); // Temporary min-height 59 }); 60 }); 17 61 18 });//End document ready function 19 // masonry active 20 21 var container = document.querySelector('.mgpd-masonry'); 22 //create empty var msnry 23 var msnry; 24 // initialize Masonry after all images have loaded 25 if ( $(container).length > 0 ){ 26 imagesLoaded( container, function() { 27 msnry = new Masonry( container, { 28 itemSelector: '.mgpd-masonry-item' 29 }); 30 }); 62 // Global function to reinitialize masonry (can be called by premium features) 63 // Add throttling to prevent excessive calls 64 var mgpdMasonryThrottle = false; 31 65 32 } 66 window.mgpdReinitializeMasonry = function() { 67 if (mgpdMasonryThrottle) { 68 return; // Silent throttle 69 } 70 71 mgpdMasonryThrottle = true; 72 73 setTimeout(function() { 74 mgpdMasonryThrottle = false; 75 }, 500); // Throttle for 500ms 76 77 $('.mgpd-masonry').each(function() { 78 var $container = $(this); 79 var container = this; 80 var masonryInstance = $container.data('masonry'); 81 82 // Check if masonry is already initialized on this container 83 if (masonryInstance) { 84 // Masonry is initialized, reload items 85 imagesLoaded(container, function() { 86 try { 87 // Use direct instance methods instead of jQuery plugin 88 masonryInstance.reloadItems(); 89 masonryInstance.layout(); 90 91 // Reset height to auto to allow proper calculation 92 $container.css('height', 'auto'); 93 94 } catch (error) { 95 console.error('MGPD: Error reloading masonry:', error); 96 } 97 }); 98 } else { 99 // Masonry not initialized, initialize it first 100 imagesLoaded(container, function() { 101 try { 102 var newMasonryInstance = new Masonry(container, { 103 itemSelector: '.mgpd-masonry-item', 104 percentPosition: true, 105 gutter: 0, 106 horizontalOrder: true, 107 fitWidth: false 108 }); 109 110 // Store masonry instance 111 $container.data('masonry', newMasonryInstance); 112 113 // Add loaded class for smooth appearance 114 $container.closest('.mgpd-masonry-container').addClass('masonry-loaded'); 115 116 } catch (error) { 117 console.error('MGPD: Error initializing masonry:', error); 118 } 119 }); 120 } 121 }); 122 }; 123 124 }(jQuery)); 33 125 34 126 35 }(jQuery));36 37 -
magical-posts-display/trunk/composer.json
r3196996 r3380394 1 1 { 2 "name": "magical-posts-display/wordpress-plugin", 3 "description": "Magical Posts Display - Elementor Advanced Posts widgets", 4 "type": "wordpress-plugin", 5 "license": "GPL-2.0-or-later", 2 6 "require": { 7 "php": ">=7.4", 3 8 "appsero/client": "^2.0.4", 4 9 "htmlburger/carbon-fields": "^3.6" 10 }, 11 "require-dev": { 12 "phpstan/phpstan": "^1.0" 13 }, 14 "autoload": { 15 "psr-4": { 16 "MagicalPostsDisplay\\": "includes/" 17 } 5 18 } 6 19 } -
magical-posts-display/trunk/file-include.php
r3235168 r3380394 1 1 <?php 2 /*3 *4 * Magical posts display5 * All files includes6 *7 *8 *9 */10 2 3 /** 4 * File Include Manager 5 * 6 * Manages all file inclusions for the plugin 7 * Organized by functionality and context 8 * 9 * REORGANIZATION SUMMARY: 10 * - Admin notices moved to admin/admin-page/admin-info.php 11 * - Assets (CSS/JS) handling moved to includes/class-assets-manager.php 12 * - AJAX handlers moved to includes/class-ajax-handler.php 13 * - WordPress hooks moved to includes/class-hooks-handler.php 14 * - Main plugin class cleaned up to focus on core initialization 15 * 16 * @package Magical Posts Display 17 * @since 1.2.54 18 */ 19 20 if (!defined('ABSPATH')) { 21 exit; // Exit if accessed directly. 22 } 23 24 // Initialize plugin data 11 25 $mg_args = array( 12 26 'posts_per_page' => -1, 13 27 'ignore_sticky_posts' => 1, 14 28 'post_type' => 'mp-display', 15 16 29 ); 17 30 … … 19 32 $install_date = gmdate("Y-m-d", strtotime(get_option('mgposte_install_date'))); 20 33 $compare_date = '2023-03-07'; 34 35 // Include core classes 36 require_once(MAGICAL_POSTS_DISPLAY_DIR . 'includes/class-assets-manager.php'); 37 require_once(MAGICAL_POSTS_DISPLAY_DIR . 'includes/class-ajax-handler.php'); 38 require_once(MAGICAL_POSTS_DISPLAY_DIR . 'includes/class-hooks-handler.php'); 39 40 // Initialize core handlers 41 if (class_exists('MPD_Assets_Manager')) { 42 MPD_Assets_Manager::init(); 43 } 44 45 if (class_exists('MPD_Ajax_Handler')) { 46 MPD_Ajax_Handler::init(); 47 } 48 49 if (class_exists('MPD_Hooks_Handler')) { 50 MPD_Hooks_Handler::init(); 51 } 21 52 22 53 if (is_admin()) { … … 53 84 require_once(MAGICAL_POSTS_DISPLAY_DIR . 'includes/mp-posts-function.php'); 54 85 55 //admin info 56 if (!mpd_check_plugin_active('magical-posts-display-pro/magical-posts-display-pro.php')) { 86 // Load traits 87 if (file_exists(MAGICAL_POSTS_DISPLAY_DIR . 'includes/traits/SVG_Icons_Trait.php')) { 88 require_once(MAGICAL_POSTS_DISPLAY_DIR . 'includes/traits/SVG_Icons_Trait.php'); 89 } 90 if (file_exists(MAGICAL_POSTS_DISPLAY_DIR . 'includes/traits/Advanced_Media_Trait.php')) { 91 require_once(MAGICAL_POSTS_DISPLAY_DIR . 'includes/traits/Advanced_Media_Trait.php'); 92 } 93 if (file_exists(MAGICAL_POSTS_DISPLAY_DIR . 'includes/traits/Premium_Features_Trait.php')) { 94 require_once(MAGICAL_POSTS_DISPLAY_DIR . 'includes/traits/Premium_Features_Trait.php'); 95 } 96 97 // Admin info (moved to conditional include based on context) 98 if (is_admin() && !mpd_check_plugin_active('magical-posts-display-pro/magical-posts-display-pro.php')) { 57 99 require_once(MAGICAL_POSTS_DISPLAY_DIR . 'admin/admin-page/admin-info.php'); 58 100 } … … 84 126 85 127 86 /* 87 * 88 * Plugin activation hook 89 * 90 */ 91 function mp_display_activation_setup() 92 { 93 // Trigger our function that registers the custom post type 94 mp_display_post_type(); 95 96 // Clear the permalinks after the post type has been registered 97 flush_rewrite_rules(); 98 // Add new administrator role 99 mp_display_admin_role(); 100 } 101 102 /* 103 * 104 * Plugin deactivation hook 105 * 106 */ 107 108 function mp_display_deactivation_setup() 109 { 110 111 // Clear the permalinks to remove our post type's rules 112 flush_rewrite_rules(); 113 114 // gets the administrator role remove 115 mp_display_admin_role_remove(); 116 } 117 118 register_activation_hook(__FILE__, 'mp_display_activation_setup'); 119 register_deactivation_hook(__FILE__, 'mp_display_deactivation_setup'); 128 // Plugin activation and deactivation hooks are now handled by MPD_Hooks_Handler class 120 129 121 130 … … 177 186 } 178 187 179 if (!function_exists('mpd_count_post_visits')) { 180 function mpd_count_post_visits() 181 { 182 if (is_single()) { 183 global $post; 184 $views = get_post_meta($post->ID, 'mpd_my_post_viewed', true); 185 if ($views == '') { 186 update_post_meta($post->ID, 'mpd_my_post_viewed', '1'); 187 } else { 188 $views_no = intval($views); 189 update_post_meta($post->ID, 'mpd_my_post_viewed', ++$views_no); 190 } 191 } 192 } 193 add_action('wp_head', 'mpd_count_post_visits'); 194 } 188 // Post visit counting is now handled by MPD_Hooks_Handler class -
magical-posts-display/trunk/includes/blocks/posts-tab.php
r3116993 r3380394 477 477 endwhile; 478 478 479 wp_reset_ query();479 wp_reset_postdata(); 480 480 wp_reset_postdata(); 481 481 else : -
magical-posts-display/trunk/includes/elementor/elementor-main.php
r3325763 r3380394 66 66 require_once(MAGICAL_POSTS_DISPLAY_DIR . '/includes/elementor/widgets/news-magazine-grid.php'); 67 67 $widgets_manager->register(new \mgpdNewsMagazineGrid()); 68 68 69 69 // News Magazine Image Grid 70 70 require_once(MAGICAL_POSTS_DISPLAY_DIR . '/includes/elementor/widgets/news-magazine-img-grid.php'); … … 76 76 77 77 $category_prefix = 'mgp-'; 78 $category_slug = $category_prefix . 'mgposts';78 $category_slug = $category_prefix . 'mgposts'; 79 79 80 $elements_manager->add_category($category_slug, [81 'title' => esc_html__( 'Magical Posts Display', 'magical-posts-display'),82 'icon' => 'fa fa-magic',83 ]);80 $elements_manager->add_category($category_slug, [ 81 'title' => esc_html__('Magical Posts Display', 'magical-posts-display'), 82 'icon' => 'fa fa-magic', 83 ]); 84 84 85 // Get all existing categories86 $categories = $elements_manager->get_categories();85 // Get all existing categories 86 $categories = $elements_manager->get_categories(); 87 87 88 // Remove your custom category from the list to reposition it89 $magical_category = $categories[ $category_slug] ?? null;90 unset( $categories[ $category_slug ]);88 // Remove your custom category from the list to reposition it 89 $magical_category = $categories[$category_slug] ?? null; 90 unset($categories[$category_slug]); 91 91 92 if ( ! $magical_category) {93 return; // Stop if not found94 }92 if (! $magical_category) { 93 return; // Stop if not found 94 } 95 95 96 // Insert at index 3 (4th position)97 $before = array_slice( $categories, 0, 3, true);98 $after = array_slice( $categories, 3, null, true);99 $reordered = $before + [ $category_slug => $magical_category] + $after;96 // Insert at index 3 (4th position) 97 $before = array_slice($categories, 0, 4, true); 98 $after = array_slice($categories, 4, null, true); 99 $reordered = $before + [$category_slug => $magical_category] + $after; 100 100 101 // Use reflection to inject reordered categories 102 $reflection = new \ReflectionClass( $elements_manager ); 103 $property = $reflection->getProperty( 'categories' ); 104 $property->setAccessible( true ); 105 $property->setValue( $elements_manager, $reordered ); 106 101 // Use reflection to inject reordered categories 102 $reflection = new \ReflectionClass($elements_manager); 103 $property = $reflection->getProperty('categories'); 104 $property->setAccessible(true); 105 $property->setValue($elements_manager, $reordered); 107 106 } 108 107 … … 125 124 126 125 wp_enqueue_style("mp-tab-style", MAGICAL_POSTS_DISPLAY_ASSETS . 'css/widget-style/mp-tabs.css', array(), MAGICAL_POSTS_DISPLAY_VERSION, 'all'); 127 126 128 127 // Register News Magazine Grid styles 129 128 wp_register_style('magical-news-magazine-grid', MAGICAL_POSTS_DISPLAY_ASSETS . 'css/news-magazine-grid.css', array(), MAGICAL_POSTS_DISPLAY_VERSION, 'all'); 130 129 131 130 // Register News Magazine Image Grid styles 132 131 wp_register_style('magical-news-magazine-img-grid', MAGICAL_POSTS_DISPLAY_ASSETS . 'css/news-magazine-img-grid.css', array(), MAGICAL_POSTS_DISPLAY_VERSION, 'all'); -
magical-posts-display/trunk/includes/elementor/widgets/advanced-posts-grid1.php
r3116993 r3380394 1925 1925 endif; 1926 1926 endwhile; 1927 wp_reset_ query();1927 wp_reset_postdata(); 1928 1928 wp_reset_postdata(); 1929 1929 ?> -
magical-posts-display/trunk/includes/elementor/widgets/advanced-posts-grid2.php
r3116993 r3380394 1995 1995 endif; 1996 1996 endwhile; 1997 wp_reset_ query();1997 wp_reset_postdata(); 1998 1998 wp_reset_postdata(); 1999 1999 ?> -
magical-posts-display/trunk/includes/elementor/widgets/advanced-posts-img-grid.php
r3214174 r3380394 1333 1333 ] 1334 1334 ); 1335 1335 1336 1336 $this->add_responsive_control( 1337 1337 'mgpg_description_padding', … … 1345 1345 ] 1346 1346 ); 1347 1347 1348 1348 $this->add_responsive_control( 1349 1349 'mgpg_description_margin', … … 1357 1357 ] 1358 1358 ); 1359 1359 1360 1360 $this->add_control( 1361 1361 'mgpg_description_color', … … 1368 1368 ] 1369 1369 ); 1370 1370 1371 1371 $this->add_control( 1372 1372 'mgpg_description_bgcolor', … … 1379 1379 ] 1380 1380 ); 1381 1381 1382 1382 $this->add_control( 1383 1383 'mgpg_description_radius', … … 1391 1391 ] 1392 1392 ); 1393 1393 1394 1394 $this->end_controls_tab(); // End of Normal Tab 1395 1395 1396 1396 // Hover Tab 1397 1397 $this->start_controls_tab( … … 1401 1401 ] 1402 1402 ); 1403 1403 1404 1404 $this->add_control( 1405 1405 'mgpg_description_hover_color', … … 1412 1412 ] 1413 1413 ); 1414 1414 1415 1415 $this->add_control( 1416 1416 'mgpg_description_hover_bgcolor', … … 1423 1423 ] 1424 1424 ); 1425 1425 1426 1426 $this->add_control( 1427 1427 'mgpg_des_hover_transition', … … 1441 1441 ] 1442 1442 ); 1443 1443 1444 1444 $this->end_controls_tab(); // End of Hover Tab 1445 1445 1446 1446 $this->end_controls_tabs(); 1447 1447 1448 1448 $this->add_group_control( 1449 1449 \Elementor\Group_Control_Typography::get_type(), … … 1454 1454 ] 1455 1455 ); 1456 1456 1457 1457 $this->end_controls_section(); 1458 1458 $this->start_controls_section( … … 1478 1478 1479 1479 1480 $this->start_controls_tabs('mgpg_meta_cat_tabs');1481 1480 $this->start_controls_tabs('mgpg_meta_cat_tabs'); 1481 1482 1482 // Normal Tab 1483 1483 $this->start_controls_tab( … … 1487 1487 ] 1488 1488 ); 1489 1489 1490 1490 $this->add_control( 1491 1491 'mgpg_meta_cat_text_color', … … 1498 1498 ] 1499 1499 ); 1500 1500 1501 1501 $this->add_control( 1502 1502 'mgpg_meta_cat_bg_color', … … 1509 1509 ] 1510 1510 ); 1511 1511 1512 1512 $this->add_responsive_control( 1513 1513 'mgpg_meta_cat_margin', … … 1520 1520 ] 1521 1521 ); 1522 1522 1523 1523 $this->add_responsive_control( 1524 1524 'mgpg_meta_cat_padding', … … 1531 1531 ] 1532 1532 ); 1533 1533 1534 1534 $this->add_control( 1535 1535 'mgpg_meta_cat_border_radius', … … 1543 1543 ] 1544 1544 ); 1545 1545 1546 1546 $this->add_group_control( 1547 1547 \Elementor\Group_Control_Border::get_type(), … … 1552 1552 ] 1553 1553 ); 1554 1554 1555 1555 $this->add_group_control( 1556 1556 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1561 1561 ] 1562 1562 ); 1563 1563 1564 1564 $this->end_controls_tab(); // End Normal Tab 1565 1565 1566 1566 // Hover Tab 1567 1567 $this->start_controls_tab( … … 1571 1571 ] 1572 1572 ); 1573 1573 1574 1574 $this->add_control( 1575 1575 'mgpg_meta_cat_text_color_hover', … … 1582 1582 ] 1583 1583 ); 1584 1584 1585 1585 $this->add_control( 1586 1586 'mgpg_meta_cat_bg_color_hover', … … 1593 1593 ] 1594 1594 ); 1595 1595 1596 1596 $this->add_group_control( 1597 1597 \Elementor\Group_Control_Border::get_type(), … … 1602 1602 ] 1603 1603 ); 1604 1604 1605 1605 $this->add_group_control( 1606 1606 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1611 1611 ] 1612 1612 ); 1613 1613 1614 1614 $this->end_controls_tab(); // End Hover Tab 1615 1615 1616 1616 $this->end_controls_tabs(); // End Tabs 1617 1617 1618 1618 $this->add_group_control( 1619 1619 \Elementor\Group_Control_Typography::get_type(), … … 1643 1643 ] 1644 1644 ); 1645 1645 1646 1646 $this->add_control( 1647 1647 'mgpg_author_style_section', … … 1653 1653 ); 1654 1654 1655 1655 1656 1656 $this->start_controls_tabs('mgpg_author_tabs'); 1657 1657 1658 1658 // Normal Tab 1659 1659 $this->start_controls_tab( … … 1663 1663 ] 1664 1664 ); 1665 1665 1666 1666 $this->add_group_control( 1667 1667 \Elementor\Group_Control_Typography::get_type(), … … 1702 1702 ] 1703 1703 ); 1704 1704 1705 1705 $this->add_control( 1706 1706 'mgpg_author_background_color', … … 1713 1713 ] 1714 1714 ); 1715 1715 1716 1716 $this->add_group_control( 1717 1717 \Elementor\Group_Control_Border::get_type(), … … 1722 1722 ] 1723 1723 ); 1724 1724 1725 1725 $this->add_responsive_control( 1726 1726 'mgpg_author_margin', … … 1733 1733 ] 1734 1734 ); 1735 1735 1736 1736 $this->add_responsive_control( 1737 1737 'mgpg_author_padding', … … 1744 1744 ] 1745 1745 ); 1746 1746 1747 1747 $this->end_controls_tab(); 1748 1748 1749 1749 // Hover Tab 1750 1750 $this->start_controls_tab( … … 1754 1754 ] 1755 1755 ); 1756 1756 1757 1757 $this->add_control( 1758 1758 'mgpg_author_hover_text_color', … … 1765 1765 ] 1766 1766 ); 1767 1767 1768 1768 $this->add_control( 1769 1769 'mgpg_author_hover_background_color', … … 1776 1776 ] 1777 1777 ); 1778 1778 1779 1779 $this->add_group_control( 1780 1780 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1785 1785 ] 1786 1786 ); 1787 1787 1788 1788 $this->add_control( 1789 1789 'mgpg_author_transition_duration', … … 1803 1803 ] 1804 1804 ); 1805 1805 1806 1806 $this->end_controls_tab(); 1807 1807 1808 1808 $this->end_controls_tabs(); 1809 1809 1810 1810 1811 1811 … … 1990 1990 } 1991 1991 endwhile; 1992 wp_reset_ query();1992 wp_reset_postdata(); 1993 1993 wp_reset_postdata(); 1994 1994 ?> -
magical-posts-display/trunk/includes/elementor/widgets/posts-carousel.php
r3116993 r3380394 2290 2290 <?php 2291 2291 endwhile; 2292 wp_reset_ query();2292 wp_reset_postdata(); 2293 2293 wp_reset_postdata(); 2294 2294 ?> -
magical-posts-display/trunk/includes/elementor/widgets/posts-cat.php
r2961712 r3380394 421 421 'content_grid_boxshadow', 422 422 [ 423 'label' => __('Use Box shadow?', 'magical- addons-for-elementor'),423 'label' => __('Use Box shadow?', 'magical-posts-display'), 424 424 'type' => \Elementor\Controls_Manager::SWITCHER, 425 'yes' => __('Yes', 'magical- addons-for-elementor'),426 'no' => __('No', 'magical- addons-for-elementor'),425 'yes' => __('Yes', 'magical-posts-display'), 426 'no' => __('No', 'magical-posts-display'), 427 427 'default' => 'yes', 428 428 ] -
magical-posts-display/trunk/includes/elementor/widgets/posts-grid.php
r3214174 r3380394 1 1 <?php 2 3 2 4 3 class mgpdEPostsGrid extends \Elementor\Widget_Base 5 4 { 5 use SVG_Icons_Trait; 6 use Advanced_Media_Trait; 6 7 7 8 /** … … 126 127 'show_byid' => esc_html__('Show By Id (Post Only)', 'magical-posts-display'), 127 128 'show_byid_manually' => esc_html__('Add ID Manually', 'magical-posts-display'), 129 'advanced_query' => esc_html__('Advanced Query Builder (Pro Only)', 'magical-posts-display'), 130 'custom_fields' => esc_html__('Custom Fields Filter (Pro Only)', 'magical-posts-display'), 131 'exclude_current' => esc_html__('Exclude Current Post (Pro Only)', 'magical-posts-display'), 128 132 ], 129 133 ] … … 239 243 ); 240 244 $this->add_control( 245 'mgpg_layout_type', 246 [ 247 'label' => __('Layout Type', 'magical-posts-display'), 248 'type' => \Elementor\Controls_Manager::SELECT, 249 'default' => 'static', 250 'options' => [ 251 'static' => __('Static', 'magical-posts-display'), 252 'masonry' => __('Masonry', 'magical-posts-display'), 253 ], 254 'description' => __('Choose between static grid layout or masonry layout. Masonry creates a dynamic, Pinterest-style layout. <strong>Note: Masonry only works on frontend, not in editor preview.</strong>', 'magical-posts-display'), 255 ] 256 ); 257 $this->add_control( 258 'mgpg_masonry_style', 259 [ 260 'label' => __('Masonry Style', 'magical-posts-display'), 261 'type' => \Elementor\Controls_Manager::SELECT, 262 'default' => 'style1', 263 'options' => [ 264 'style1' => __('Style 1 - Default Heights', 'magical-posts-display'), 265 'style2' => __('Style 2 - Alternating Heights', 'magical-posts-display'), 266 'style3' => __('Style 3 - Pattern Heights', 'magical-posts-display'), 267 ], 268 'condition' => [ 269 'mgpg_layout_type' => 'masonry', 270 ], 271 'description' => __('Choose different image height patterns for masonry layout. <strong>Note: Masonry preview only works on frontend.</strong>', 'magical-posts-display'), 272 ] 273 ); 274 $this->add_control( 241 275 'mgpg_post_style', 242 276 [ … … 284 318 ] 285 319 ); 320 321 $this->add_control( 322 'mgpg_media_source', 323 [ 324 'label' => __('Advanced Media Source (Pro Only)', 'magical-posts-display'), 325 'type' => \Elementor\Controls_Manager::SELECT, 326 'options' => [ 327 'featured' => __('Featured Image Only', 'magical-posts-display'), 328 'content' => __('First Content Image (Pro Only)', 'magical-posts-display'), 329 'video' => __('Video Embed (YouTube/Vimeo) (Pro Only)', 'magical-posts-display'), 330 'priority' => __('Priority Fallback (Pro Only)', 'magical-posts-display'), 331 ], 332 'default' => 'featured', 333 'description' => __('Choose media source with priority fallback system (Pro Only)', 'magical-posts-display'), 334 'classes' => 'mpd-pro-control', 335 'condition' => [ 336 'mgpg_post_img_show' => 'yes', 337 ], 338 ] 339 ); 340 341 $this->add_control( 342 'mgpg_media_priority', 343 [ 344 'label' => __('Priority Order (Pro Only)', 'magical-posts-display'), 345 'type' => \Elementor\Controls_Manager::SELECT2, 346 'multiple' => true, 347 'options' => [ 348 'video' => __('Video Embed', 'magical-posts-display'), 349 'featured' => __('Featured Image', 'magical-posts-display'), 350 'content' => __('First Content Image', 'magical-posts-display'), 351 'placeholder' => __('Placeholder Image', 'magical-posts-display'), 352 ], 353 'default' => ['video', 'featured', 'content', 'placeholder'], 354 'description' => __('Set priority order for media fallback. First available source will be used (Pro Only)', 'magical-posts-display'), 355 'classes' => 'mpd-pro-control', 356 'condition' => [ 357 'mgpg_post_img_show' => 'yes', 358 'mgpg_media_source' => 'priority', 359 ], 360 ] 361 ); 362 363 $this->add_control( 364 'mgpg_video_play_icon', 365 [ 366 'label' => __('Show Video Play Icon', 'magical-posts-display'), 367 'type' => \Elementor\Controls_Manager::SWITCHER, 368 'default' => 'yes', 369 'description' => __('Display play icon overlay on video thumbnails (Pro Only)', 'magical-posts-display'), 370 'classes' => 'mpd-pro-control', 371 'condition' => [ 372 'mgpg_post_img_show' => 'yes', 373 'mgpg_media_source' => ['video', 'priority'], 374 ], 375 'condition_type' => 'or', 376 ] 377 ); 378 286 379 $this->add_control( 287 380 'mgpg_show_title', … … 590 683 ); 591 684 $this->end_controls_section(); 685 686 // Premium Features Section 687 $this->start_controls_section( 688 'mgpg_premium_features', 689 [ 690 'label' => sprintf('%s %s', __('Premium Features', 'magical-posts-display'), mp_display__pro_only_text()), 691 'tab' => \Elementor\Controls_Manager::TAB_CONTENT, 692 ] 693 ); 694 if (empty(mp_display_check_main_ok())) { 695 $this->add_control( 696 'mgpg_premium_info', 697 [ 698 'type' => \Elementor\Controls_Manager::RAW_HTML, 699 'raw' => sprintf('<span style="color:red">%s</span>', __('These advanced features are only available in the Pro version.', 'magical-posts-display')), 700 ] 701 ); 702 } 703 $this->add_control( 704 'mgpg_ajax_filter', 705 [ 706 'label' => __('AJAX Category Filter', 'magical-posts-display'), 707 'type' => \Elementor\Controls_Manager::SWITCHER, 708 'description' => __('Enable dynamic category filtering without page reload (Pro Only)', 'magical-posts-display'), 709 'classes' => 'mpd-pro-control', 710 ] 711 ); 712 713 $this->add_control( 714 'mgpg_infinite_scroll', 715 [ 716 'label' => __('Infinite Scroll', 'magical-posts-display'), 717 'type' => \Elementor\Controls_Manager::SWITCHER, 718 'description' => __('Load more posts automatically when scrolling (Pro Only)', 'magical-posts-display'), 719 'classes' => 'mpd-pro-control', 720 ] 721 ); 722 723 $this->add_control( 724 'mgpg_reading_time', 725 [ 726 'label' => __('Reading Time Display', 'magical-posts-display'), 727 'type' => \Elementor\Controls_Manager::SWITCHER, 728 'description' => __('Show estimated reading time for each post (Pro Only)', 'magical-posts-display'), 729 'classes' => 'mpd-pro-control', 730 ] 731 ); 732 733 $this->add_control( 734 'mgpg_view_count', 735 [ 736 'label' => __('Post Views Counter', 'magical-posts-display'), 737 'type' => \Elementor\Controls_Manager::SWITCHER, 738 'description' => __('Display post view counts with analytics (Pro Only)', 'magical-posts-display'), 739 'classes' => 'mpd-pro-control', 740 ] 741 ); 742 743 $this->add_control( 744 'mgpg_social_share', 745 [ 746 'label' => __('Social Share Buttons', 'magical-posts-display'), 747 'type' => \Elementor\Controls_Manager::SWITCHER, 748 'description' => __('Add social sharing buttons to each post card (Pro Only)', 'magical-posts-display'), 749 'classes' => 'mpd-pro-control', 750 ] 751 ); 752 753 $this->add_control( 754 'mgpg_premium_features_style', 755 [ 756 'label' => __('Premium Features Display Style', 'magical-posts-display'), 757 'type' => \Elementor\Controls_Manager::SELECT, 758 'options' => [ 759 'default' => __('Default (Below Content)', 'magical-posts-display'), 760 'image-top' => __('Top of Image (Pro Only)', 'magical-posts-display'), 761 'image-overlay' => __('Image Overlay on Hover (Pro Only)', 'magical-posts-display'), 762 ], 763 'default' => 'default', 764 'description' => __('Choose where to display reading time, views, and social buttons (Pro Only)', 'magical-posts-display'), 765 'classes' => 'mpd-pro-control', 766 'condition' => [ 767 'mgpg_reading_time' => 'yes', 768 'mgpg_view_count' => 'yes', 769 'mgpg_social_share' => 'yes', 770 ], 771 'condition_type' => 'or', 772 ] 773 ); 774 775 $this->add_control( 776 'mgpg_hover_effects', 777 [ 778 'label' => __('Advanced Hover Effects', 'magical-posts-display'), 779 'type' => \Elementor\Controls_Manager::SELECT, 780 'options' => [ 781 'none' => __('None', 'magical-posts-display'), 782 'zoom' => __('Zoom Effect (Pro Only)', 'magical-posts-display'), 783 'slide' => __('Slide Effect (Pro Only)', 'magical-posts-display'), 784 'fade' => __('Fade Effect (Pro Only)', 'magical-posts-display'), 785 'rotate' => __('Rotate Effect (Pro Only)', 'magical-posts-display'), 786 ], 787 'default' => 'none', 788 'description' => __('Choose advanced hover animations for post cards (Pro Only)', 'magical-posts-display'), 789 'classes' => 'mpd-pro-control', 790 ] 791 ); 792 if (mp_display_check_main_ok()) { 793 $this->add_control( 794 'mgpg_ajax_info', 795 [ 796 'type' => \Elementor\Controls_Manager::RAW_HTML, 797 'raw' => sprintf('<span style="color:red">%s</span>', __('All Ajax features only work in the frontend', 'magical-posts-display')), 798 ] 799 ); 800 } 801 $this->end_controls_section(); 802 592 803 $this->start_controls_section( 593 804 'mgpg_pagination', … … 933 1144 $this->end_controls_section(); 934 1145 1146 // Filter Buttons Style Section 1147 $this->start_controls_section( 1148 'mgpd_filter_buttons_style', 1149 [ 1150 'label' => __('Filter Buttons', 'magical-posts-display'), 1151 'tab' => \Elementor\Controls_Manager::TAB_STYLE, 1152 'condition' => [ 1153 'mgpg_ajax_filter' => 'yes', 1154 ] 1155 ] 1156 ); 1157 1158 $this->add_responsive_control( 1159 'mgpd_filter_align', 1160 [ 1161 'label' => __('Alignment', 'magical-posts-display'), 1162 'type' => \Elementor\Controls_Manager::CHOOSE, 1163 'options' => [ 1164 'left' => [ 1165 'title' => __('Left', 'magical-posts-display'), 1166 'icon' => 'eicon-text-align-left', 1167 ], 1168 'center' => [ 1169 'title' => __('Center', 'magical-posts-display'), 1170 'icon' => 'eicon-text-align-center', 1171 ], 1172 'right' => [ 1173 'title' => __('Right', 'magical-posts-display'), 1174 'icon' => 'eicon-text-align-right', 1175 ], 1176 ], 1177 'default' => 'center', 1178 'selectors' => [ 1179 '{{WRAPPER}} .mgpd-filter-buttons' => 'text-align: {{VALUE}};', 1180 ], 1181 ] 1182 ); 1183 1184 $this->add_responsive_control( 1185 'mgpd_filter_spacing', 1186 [ 1187 'label' => __('Buttons Spacing', 'magical-posts-display'), 1188 'type' => \Elementor\Controls_Manager::SLIDER, 1189 'size_units' => ['px'], 1190 'range' => [ 1191 'px' => [ 1192 'min' => 0, 1193 'max' => 50, 1194 'step' => 1, 1195 ], 1196 ], 1197 'selectors' => [ 1198 '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn' => 'margin: 0 {{SIZE}}{{UNIT}};', 1199 ], 1200 ] 1201 ); 1202 1203 $this->add_responsive_control( 1204 'mgpd_filter_margin', 1205 [ 1206 'label' => __('Container Margin', 'magical-posts-display'), 1207 'type' => \Elementor\Controls_Manager::DIMENSIONS, 1208 'size_units' => ['px', 'em', '%'], 1209 'selectors' => [ 1210 '{{WRAPPER}} .mgpd-filter-buttons' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 1211 ], 1212 ] 1213 ); 1214 1215 $this->add_responsive_control( 1216 'mgpd_filter_padding', 1217 [ 1218 'label' => __('Container Padding', 'magical-posts-display'), 1219 'type' => \Elementor\Controls_Manager::DIMENSIONS, 1220 'size_units' => ['px', 'em', '%'], 1221 'selectors' => [ 1222 '{{WRAPPER}} .mgpd-filter-buttons' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 1223 ], 1224 ] 1225 ); 1226 1227 // Button Tabs for Normal and Active states 1228 $this->start_controls_tabs('mgpd_filter_btn_tabs'); 1229 1230 // Normal State Tab 1231 $this->start_controls_tab( 1232 'mgpd_filter_btn_normal', 1233 [ 1234 'label' => __('Normal', 'magical-posts-display'), 1235 ] 1236 ); 1237 1238 $this->add_group_control( 1239 \Elementor\Group_Control_Typography::get_type(), 1240 [ 1241 'name' => 'mgpd_filter_btn_typography', 1242 'selector' => '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn', 1243 ] 1244 ); 1245 1246 $this->add_control( 1247 'mgpd_filter_btn_color', 1248 [ 1249 'label' => __('Text Color', 'magical-posts-display'), 1250 'type' => \Elementor\Controls_Manager::COLOR, 1251 'default' => '#333333', 1252 'selectors' => [ 1253 '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn' => 'color: {{VALUE}};', 1254 ], 1255 ] 1256 ); 1257 1258 $this->add_group_control( 1259 \Elementor\Group_Control_Background::get_type(), 1260 [ 1261 'name' => 'mgpd_filter_btn_bg', 1262 'label' => __('Background', 'magical-posts-display'), 1263 'types' => ['classic', 'gradient'], 1264 'selector' => '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn', 1265 ] 1266 ); 1267 1268 $this->add_responsive_control( 1269 'mgpd_filter_btn_padding', 1270 [ 1271 'label' => __('Padding', 'magical-posts-display'), 1272 'type' => \Elementor\Controls_Manager::DIMENSIONS, 1273 'size_units' => ['px', 'em', '%'], 1274 'default' => [ 1275 'top' => 10, 1276 'right' => 20, 1277 'bottom' => 10, 1278 'left' => 20, 1279 'unit' => 'px', 1280 ], 1281 'selectors' => [ 1282 '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 1283 ], 1284 ] 1285 ); 1286 1287 $this->add_control( 1288 'mgpd_filter_btn_border_radius', 1289 [ 1290 'label' => __('Border Radius', 'magical-posts-display'), 1291 'type' => \Elementor\Controls_Manager::DIMENSIONS, 1292 'size_units' => ['px', '%'], 1293 'selectors' => [ 1294 '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 1295 ], 1296 ] 1297 ); 1298 1299 $this->add_group_control( 1300 \Elementor\Group_Control_Border::get_type(), 1301 [ 1302 'name' => 'mgpd_filter_btn_border', 1303 'selector' => '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn', 1304 ] 1305 ); 1306 1307 $this->add_group_control( 1308 \Elementor\Group_Control_Box_Shadow::get_type(), 1309 [ 1310 'name' => 'mgpd_filter_btn_shadow', 1311 'selector' => '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn', 1312 ] 1313 ); 1314 1315 $this->end_controls_tab(); 1316 1317 // Active/Hover State Tab 1318 $this->start_controls_tab( 1319 'mgpd_filter_btn_active', 1320 [ 1321 'label' => __('Active/Hover', 'magical-posts-display'), 1322 ] 1323 ); 1324 1325 $this->add_control( 1326 'mgpd_filter_btn_active_color', 1327 [ 1328 'label' => __('Text Color', 'magical-posts-display'), 1329 'type' => \Elementor\Controls_Manager::COLOR, 1330 'default' => '#ffffff', 1331 'selectors' => [ 1332 '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn.active' => 'color: {{VALUE}};', 1333 '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn:hover' => 'color: {{VALUE}};', 1334 ], 1335 ] 1336 ); 1337 1338 $this->add_group_control( 1339 \Elementor\Group_Control_Background::get_type(), 1340 [ 1341 'name' => 'mgpd_filter_btn_active_bg', 1342 'label' => __('Background', 'magical-posts-display'), 1343 'types' => ['classic', 'gradient'], 1344 'selector' => '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn.active, {{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn:hover', 1345 ] 1346 ); 1347 1348 $this->add_control( 1349 'mgpd_filter_btn_active_border_color', 1350 [ 1351 'label' => __('Border Color', 'magical-posts-display'), 1352 'type' => \Elementor\Controls_Manager::COLOR, 1353 'selectors' => [ 1354 '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn.active' => 'border-color: {{VALUE}};', 1355 '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn:hover' => 'border-color: {{VALUE}};', 1356 ], 1357 ] 1358 ); 1359 1360 $this->add_group_control( 1361 \Elementor\Group_Control_Box_Shadow::get_type(), 1362 [ 1363 'name' => 'mgpd_filter_btn_active_shadow', 1364 'selector' => '{{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn.active, {{WRAPPER}} .mgpd-filter-buttons .mgpd-filter-btn:hover', 1365 ] 1366 ); 1367 1368 $this->end_controls_tab(); 1369 1370 $this->end_controls_tabs(); 1371 1372 $this->end_controls_section(); 1373 935 1374 $this->start_controls_section( 936 1375 'mgpg_title_style', … … 940 1379 ] 941 1380 ); 942 1381 943 1382 // Adding Tabs for Normal and Hover 944 1383 $this->start_controls_tabs('mgpg_title_tabs'); 945 1384 946 1385 // Normal Tab 947 1386 $this->start_controls_tab( … … 951 1390 ] 952 1391 ); 953 1392 954 1393 $this->add_responsive_control( 955 1394 'mgpg_title_padding', … … 963 1402 ] 964 1403 ); 965 1404 966 1405 $this->add_responsive_control( 967 1406 'mgpg_title_margin', … … 975 1414 ] 976 1415 ); 977 1416 978 1417 $this->add_control( 979 1418 'mgpg_title_color', … … 986 1425 ] 987 1426 ); 988 1427 989 1428 $this->add_control( 990 1429 'mgpg_title_bgcolor', … … 997 1436 ] 998 1437 ); 999 1438 1000 1439 $this->add_control( 1001 1440 'mgpg_descb_radius', … … 1009 1448 ] 1010 1449 ); 1011 1450 1012 1451 $this->add_group_control( 1013 1452 \Elementor\Group_Control_Typography::get_type(), … … 1018 1457 ] 1019 1458 ); 1020 1459 1021 1460 $this->end_controls_tab(); 1022 1461 1023 1462 // Hover Tab 1024 1463 $this->start_controls_tab( … … 1028 1467 ] 1029 1468 ); 1030 1469 1031 1470 $this->add_control( 1032 1471 'mgpg_hover_transition', … … 1057 1496 ] 1058 1497 ); 1059 1498 1060 1499 $this->add_control( 1061 1500 'mgpg_title_hover_bgcolor', … … 1068 1507 ] 1069 1508 ); 1070 1509 1071 1510 $this->add_control( 1072 1511 'mgpg_descb_hover_radius', … … 1080 1519 ] 1081 1520 ); 1082 1083 $this->end_controls_tab(); 1521 1522 $this->end_controls_tab(); 1084 1523 $this->end_controls_tabs(); 1085 1524 $this->end_controls_section(); 1086 1525 1087 1526 1088 1527 $this->start_controls_section( … … 1093 1532 ] 1094 1533 ); 1095 1534 1096 1535 $this->start_controls_tabs('mgpg_description_tabs'); 1097 1536 1098 1537 // Normal Tab 1099 1538 $this->start_controls_tab( … … 1103 1542 ] 1104 1543 ); 1105 1544 1106 1545 $this->add_responsive_control( 1107 1546 'mgpg_description_padding', … … 1115 1554 ] 1116 1555 ); 1117 1556 1118 1557 $this->add_responsive_control( 1119 1558 'mgpg_description_margin', … … 1127 1566 ] 1128 1567 ); 1129 1568 1130 1569 $this->add_control( 1131 1570 'mgpg_description_color', … … 1138 1577 ] 1139 1578 ); 1140 1579 1141 1580 $this->add_control( 1142 1581 'mgpg_description_bgcolor', … … 1149 1588 ] 1150 1589 ); 1151 1590 1152 1591 $this->add_control( 1153 1592 'mgpg_description_radius', … … 1161 1600 ] 1162 1601 ); 1163 1602 1164 1603 $this->end_controls_tab(); // End of Normal Tab 1165 1604 1166 1605 // Hover Tab 1167 1606 $this->start_controls_tab( … … 1171 1610 ] 1172 1611 ); 1173 1612 1174 1613 $this->add_control( 1175 1614 'mgpg_description_hover_color', … … 1182 1621 ] 1183 1622 ); 1184 1623 1185 1624 $this->add_control( 1186 1625 'mgpg_description_hover_bgcolor', … … 1193 1632 ] 1194 1633 ); 1195 1634 1196 1635 $this->add_control( 1197 1636 'mgpg_des_hover_transition', … … 1211 1650 ] 1212 1651 ); 1213 1652 1214 1653 $this->end_controls_tab(); // End of Hover Tab 1215 1654 1216 1655 $this->end_controls_tabs(); 1217 1656 1218 1657 $this->add_group_control( 1219 1658 \Elementor\Group_Control_Typography::get_type(), … … 1224 1663 ] 1225 1664 ); 1226 1665 1227 1666 $this->end_controls_section(); 1228 1667 1229 1668 $this->start_controls_section( 1230 1669 'mgpg_meta_style', … … 1246 1685 ] 1247 1686 ); 1248 1687 1249 1688 $this->start_controls_tabs('mgpg_meta_cat_tabs'); 1250 1689 1251 1690 // Normal Tab 1252 1691 $this->start_controls_tab( … … 1256 1695 ] 1257 1696 ); 1258 1697 1259 1698 $this->add_control( 1260 1699 'mgpg_meta_cat_text_color', … … 1267 1706 ] 1268 1707 ); 1269 1708 1270 1709 $this->add_control( 1271 1710 'mgpg_meta_cat_bg_color', … … 1278 1717 ] 1279 1718 ); 1280 1719 1281 1720 $this->add_responsive_control( 1282 1721 'mgpg_meta_cat_margin', … … 1289 1728 ] 1290 1729 ); 1291 1730 1292 1731 $this->add_responsive_control( 1293 1732 'mgpg_meta_cat_padding', … … 1300 1739 ] 1301 1740 ); 1302 1741 1303 1742 $this->add_control( 1304 1743 'mgpg_meta_cat_border_radius', … … 1321 1760 ] 1322 1761 ); 1323 1762 1324 1763 $this->add_group_control( 1325 1764 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1330 1769 ] 1331 1770 ); 1332 1771 1333 1772 $this->end_controls_tab(); // End Normal Tab 1334 1773 1335 1774 // Hover Tab 1336 1775 $this->start_controls_tab( … … 1340 1779 ] 1341 1780 ); 1342 1781 1343 1782 $this->add_control( 1344 1783 'mgpg_meta_cat_text_color_hover', … … 1351 1790 ] 1352 1791 ); 1353 1792 1354 1793 $this->add_control( 1355 1794 'mgpg_meta_cat_bg_color_hover', … … 1362 1801 ] 1363 1802 ); 1364 1803 1365 1804 $this->add_group_control( 1366 1805 \Elementor\Group_Control_Border::get_type(), … … 1371 1810 ] 1372 1811 ); 1373 1812 1374 1813 $this->add_group_control( 1375 1814 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1380 1819 ] 1381 1820 ); 1382 1821 1383 1822 $this->end_controls_tab(); // End Hover Tab 1384 1823 1385 1824 $this->end_controls_tabs(); // End Tabs 1386 1825 1387 1826 $this->add_group_control( 1388 1827 \Elementor\Group_Control_Typography::get_type(), … … 1434 1873 ] 1435 1874 ); 1436 1875 1437 1876 $this->add_control( 1438 1877 'mgpg_author_style_section', … … 1442 1881 'separator' => 'before', 1443 1882 'condition' => [ 1444 'mgpg_author_show' => 'yes',1445 ], 1446 ] 1447 ); 1448 1449 1883 'mgpg_author_show' => 'yes', 1884 ], 1885 ] 1886 ); 1887 1888 1450 1889 $this->start_controls_tabs('mgpg_author_tabs'); 1451 1890 1452 1891 // Normal Tab 1453 1892 $this->start_controls_tab( … … 1457 1896 ] 1458 1897 ); 1459 1898 1460 1899 $this->add_group_control( 1461 1900 \Elementor\Group_Control_Typography::get_type(), … … 1496 1935 ] 1497 1936 ); 1498 1937 1499 1938 $this->add_control( 1500 1939 'mgpg_author_background_color', … … 1507 1946 ] 1508 1947 ); 1509 1948 1510 1949 $this->add_group_control( 1511 1950 \Elementor\Group_Control_Border::get_type(), … … 1516 1955 ] 1517 1956 ); 1518 1957 1519 1958 $this->add_responsive_control( 1520 1959 'mgpg_author_margin', … … 1527 1966 ] 1528 1967 ); 1529 1968 1530 1969 $this->add_responsive_control( 1531 1970 'mgpg_author_padding', … … 1538 1977 ] 1539 1978 ); 1540 1979 1541 1980 $this->end_controls_tab(); 1542 1981 1543 1982 // Hover Tab 1544 1983 $this->start_controls_tab( … … 1548 1987 ] 1549 1988 ); 1550 1989 1551 1990 $this->add_control( 1552 1991 'mgpg_author_hover_text_color', … … 1559 1998 ] 1560 1999 ); 1561 2000 1562 2001 $this->add_control( 1563 2002 'mgpg_author_hover_background_color', … … 1570 2009 ] 1571 2010 ); 1572 2011 1573 2012 $this->add_group_control( 1574 2013 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1579 2018 ] 1580 2019 ); 1581 2020 1582 2021 $this->add_control( 1583 2022 'mgpg_author_transition_duration', … … 1597 2036 ] 1598 2037 ); 1599 2038 1600 2039 $this->end_controls_tab(); 1601 2040 1602 2041 $this->end_controls_tabs(); 1603 1604 1605 2042 2043 2044 1606 2045 $this->add_control( 1607 2046 'mgpg_meta_date', … … 1621 2060 'label' => __('Normal', 'magical-posts-display'), 1622 2061 ]); 1623 2062 1624 2063 $this->add_control( 1625 2064 'mgpg_meta_date_color', … … 1632 2071 ] 1633 2072 ); 1634 2073 1635 2074 $this->add_control( 1636 2075 'mgpg_meta_date_background_color', … … 1643 2082 ] 1644 2083 ); 1645 2084 1646 2085 $this->add_responsive_control( 1647 2086 'mgpg_meta_date_margin', … … 1654 2093 ] 1655 2094 ); 1656 2095 1657 2096 $this->add_responsive_control( 1658 2097 'mgpg_meta_date_padding', … … 1665 2104 ] 1666 2105 ); 1667 2106 1668 2107 $this->add_group_control( 1669 2108 \Elementor\Group_Control_Border::get_type(), … … 1673 2112 ] 1674 2113 ); 1675 2114 1676 2115 $this->add_group_control( 1677 2116 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1681 2120 ] 1682 2121 ); 1683 2122 1684 2123 $this->end_controls_tab(); 1685 2124 1686 2125 // Hover Tab 1687 2126 $this->start_controls_tab('mgpg_meta_date_hover', [ 1688 2127 'label' => __('Hover', 'magical-posts-display'), 1689 2128 ]); 1690 2129 1691 2130 $this->add_control( 1692 2131 'mgpg_meta_date_hover_color', … … 1699 2138 ] 1700 2139 ); 1701 2140 1702 2141 $this->add_control( 1703 2142 'mgpg_meta_date_hover_background_color', … … 1710 2149 ] 1711 2150 ); 1712 2151 1713 2152 $this->add_group_control( 1714 2153 \Elementor\Group_Control_Border::get_type(), … … 1718 2157 ] 1719 2158 ); 1720 2159 1721 2160 $this->add_group_control( 1722 2161 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1726 2165 ] 1727 2166 ); 1728 2167 1729 2168 $this->add_control( 1730 2169 'mgpg_meta_date_transition', … … 1745 2184 ] 1746 2185 ); 1747 2186 1748 2187 $this->end_controls_tab(); 1749 2188 $this->end_controls_tabs(); 1750 2189 1751 2190 $this->add_group_control( 1752 2191 \Elementor\Group_Control_Typography::get_type(), … … 1757 2196 ] 1758 2197 ); 1759 1760 2198 2199 1761 2200 $this->add_responsive_control( 1762 2201 'mgpg_meta_date_icon_size', … … 1776 2215 ], 1777 2216 ] 1778 ); 2217 ); 1779 2218 1780 2219 $this->add_control( … … 1796 2235 'label' => __('Normal', 'magical-posts-display'), 1797 2236 ]); 1798 2237 1799 2238 $this->add_control( 1800 2239 'mgpg_meta_tag_color', … … 1808 2247 ] 1809 2248 ); 1810 2249 1811 2250 $this->add_control( 1812 2251 'mgpg_meta_tag_background_color', … … 1819 2258 ] 1820 2259 ); 1821 2260 1822 2261 $this->add_responsive_control( 1823 2262 'mgpg_meta_tag_margin', … … 1831 2270 ] 1832 2271 ); 1833 2272 1834 2273 $this->add_responsive_control( 1835 2274 'mgpg_meta_tag_padding', … … 1843 2282 ] 1844 2283 ); 1845 2284 1846 2285 $this->add_group_control( 1847 2286 \Elementor\Group_Control_Border::get_type(), … … 1851 2290 ] 1852 2291 ); 1853 2292 1854 2293 $this->add_group_control( 1855 2294 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1859 2298 ] 1860 2299 ); 1861 2300 1862 2301 $this->end_controls_tab(); 1863 2302 1864 2303 // Hover Tab 1865 2304 $this->start_controls_tab('mgpg_meta_tag_hover', [ 1866 2305 'label' => __('Hover', 'magical-posts-display'), 1867 2306 ]); 1868 2307 1869 2308 $this->add_control( 1870 2309 'mgpg_meta_tag_hover_color', … … 1878 2317 ] 1879 2318 ); 1880 2319 1881 2320 $this->add_control( 1882 2321 'mgpg_meta_tag_hover_background_color', … … 1889 2328 ] 1890 2329 ); 1891 2330 1892 2331 $this->add_group_control( 1893 2332 \Elementor\Group_Control_Border::get_type(), … … 1897 2336 ] 1898 2337 ); 1899 2338 1900 2339 $this->add_group_control( 1901 2340 \Elementor\Group_Control_Box_Shadow::get_type(), … … 1905 2344 ] 1906 2345 ); 1907 2346 1908 2347 $this->add_control( 1909 2348 'mgpg_meta_tag_transition', … … 1924 2363 ] 1925 2364 ); 1926 2365 1927 2366 $this->end_controls_tab(); 1928 2367 $this->end_controls_tabs(); … … 1963 2402 ], 1964 2403 ] 1965 ); 2404 ); 1966 2405 1967 2406 $this->end_controls_section(); … … 2016 2455 ] 2017 2456 ); 2018 2457 2019 2458 $this->add_group_control( 2020 2459 \Elementor\Group_Control_Typography::get_type(), … … 2378 2817 $this->end_controls_tabs(); 2379 2818 $this->end_controls_section(); 2819 2820 // Premium Features Style Section 2821 $this->start_controls_section( 2822 'mgpg_premium_style', 2823 [ 2824 'label' => sprintf('%s %s', __('✨ Premium Features Style', 'magical-posts-display'), mp_display__pro_only_text()), 2825 'tab' => \Elementor\Controls_Manager::TAB_STYLE, 2826 ] 2827 ); 2828 2829 if (empty(mp_display_check_main_ok())) { 2830 $this->add_control( 2831 'mgpg_premium_style_info', 2832 [ 2833 'label' => sprintf('<span style="color:red">%s</span>', __('Premium features styling only works with pro version.', 'magical-posts-display')), 2834 'type' => \Elementor\Controls_Manager::HEADING, 2835 'separator' => 'before', 2836 ] 2837 ); 2838 } 2839 2840 // Reading Time Style 2841 $this->add_control( 2842 'mgpg_reading_time_heading', 2843 [ 2844 'label' => __('Reading Time', 'magical-posts-display'), 2845 'type' => \Elementor\Controls_Manager::HEADING, 2846 'separator' => 'before', 2847 ] 2848 ); 2849 2850 $this->add_control( 2851 'mgpg_reading_time_color', 2852 [ 2853 'label' => __('Text Color', 'magical-posts-display'), 2854 'type' => \Elementor\Controls_Manager::COLOR, 2855 'selectors' => [ 2856 '{{WRAPPER}} .mgpd-reading-time' => 'color: {{VALUE}};', 2857 ], 2858 ] 2859 ); 2860 2861 $this->add_control( 2862 'mgpg_reading_time_bg', 2863 [ 2864 'label' => __('Background Color', 'magical-posts-display'), 2865 'type' => \Elementor\Controls_Manager::COLOR, 2866 'selectors' => [ 2867 '{{WRAPPER}} .mgpd-reading-time' => 'background-color: {{VALUE}};', 2868 ], 2869 ] 2870 ); 2871 2872 $this->add_group_control( 2873 \Elementor\Group_Control_Typography::get_type(), 2874 [ 2875 'name' => 'mgpg_reading_time_typography', 2876 'label' => __('Typography', 'magical-posts-display'), 2877 'selector' => '{{WRAPPER}} .mgpd-reading-time', 2878 ] 2879 ); 2880 2881 $this->add_responsive_control( 2882 'mgpg_reading_time_padding', 2883 [ 2884 'label' => __('Padding', 'magical-posts-display'), 2885 'type' => \Elementor\Controls_Manager::DIMENSIONS, 2886 'size_units' => ['px', 'em', '%'], 2887 'selectors' => [ 2888 '{{WRAPPER}} .mgpd-reading-time' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 2889 ], 2890 ] 2891 ); 2892 2893 $this->add_responsive_control( 2894 'mgpg_reading_time_margin', 2895 [ 2896 'label' => __('Margin', 'magical-posts-display'), 2897 'type' => \Elementor\Controls_Manager::DIMENSIONS, 2898 'size_units' => ['px', 'em', '%'], 2899 'selectors' => [ 2900 '{{WRAPPER}} .mgpd-reading-time' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 2901 ], 2902 ] 2903 ); 2904 2905 $this->add_responsive_control( 2906 'mgpg_reading_time_border_radius', 2907 [ 2908 'label' => __('Border Radius', 'magical-posts-display'), 2909 'type' => \Elementor\Controls_Manager::DIMENSIONS, 2910 'size_units' => ['px', '%'], 2911 'selectors' => [ 2912 '{{WRAPPER}} .mgpd-reading-time' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 2913 ], 2914 ] 2915 ); 2916 2917 // View Count Style 2918 $this->add_control( 2919 'mgpg_view_count_heading', 2920 [ 2921 'label' => __('View Count', 'magical-posts-display'), 2922 'type' => \Elementor\Controls_Manager::HEADING, 2923 'separator' => 'before', 2924 ] 2925 ); 2926 2927 $this->add_control( 2928 'mgpg_view_count_color', 2929 [ 2930 'label' => __('Text Color', 'magical-posts-display'), 2931 'type' => \Elementor\Controls_Manager::COLOR, 2932 'selectors' => [ 2933 '{{WRAPPER}} .mgpd-view-count' => 'color: {{VALUE}};', 2934 ], 2935 ] 2936 ); 2937 2938 $this->add_control( 2939 'mgpg_view_count_bg', 2940 [ 2941 'label' => __('Background Color', 'magical-posts-display'), 2942 'type' => \Elementor\Controls_Manager::COLOR, 2943 'selectors' => [ 2944 '{{WRAPPER}} .mgpd-view-count' => 'background-color: {{VALUE}};', 2945 ], 2946 ] 2947 ); 2948 2949 $this->add_group_control( 2950 \Elementor\Group_Control_Typography::get_type(), 2951 [ 2952 'name' => 'mgpg_view_count_typography', 2953 'label' => __('Typography', 'magical-posts-display'), 2954 'selector' => '{{WRAPPER}} .mgpd-view-count', 2955 ] 2956 ); 2957 2958 $this->add_responsive_control( 2959 'mgpg_view_count_padding', 2960 [ 2961 'label' => __('Padding', 'magical-posts-display'), 2962 'type' => \Elementor\Controls_Manager::DIMENSIONS, 2963 'size_units' => ['px', 'em', '%'], 2964 'selectors' => [ 2965 '{{WRAPPER}} .mgpd-view-count' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 2966 ], 2967 ] 2968 ); 2969 2970 $this->add_responsive_control( 2971 'mgpg_view_count_margin', 2972 [ 2973 'label' => __('Margin', 'magical-posts-display'), 2974 'type' => \Elementor\Controls_Manager::DIMENSIONS, 2975 'size_units' => ['px', 'em', '%'], 2976 'selectors' => [ 2977 '{{WRAPPER}} .mgpd-view-count' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 2978 ], 2979 ] 2980 ); 2981 2982 $this->add_responsive_control( 2983 'mgpg_view_count_border_radius', 2984 [ 2985 'label' => __('Border Radius', 'magical-posts-display'), 2986 'type' => \Elementor\Controls_Manager::DIMENSIONS, 2987 'size_units' => ['px', '%'], 2988 'selectors' => [ 2989 '{{WRAPPER}} .mgpd-view-count' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 2990 ], 2991 ] 2992 ); 2993 2994 // Social Share Buttons Style 2995 $this->add_control( 2996 'mgpg_social_share_heading', 2997 [ 2998 'label' => __('Social Share Buttons', 'magical-posts-display'), 2999 'type' => \Elementor\Controls_Manager::HEADING, 3000 'separator' => 'before', 3001 ] 3002 ); 3003 3004 $this->add_responsive_control( 3005 'mgpg_social_share_size', 3006 [ 3007 'label' => __('Button Size', 'magical-posts-display'), 3008 'type' => \Elementor\Controls_Manager::SLIDER, 3009 'size_units' => ['px'], 3010 'range' => [ 3011 'px' => [ 3012 'min' => 20, 3013 'max' => 60, 3014 'step' => 1, 3015 ], 3016 ], 3017 'default' => [ 3018 'unit' => 'px', 3019 'size' => 32, 3020 ], 3021 'selectors' => [ 3022 '{{WRAPPER}} .mgpd-social-share a' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', 3023 ], 3024 ] 3025 ); 3026 3027 $this->add_responsive_control( 3028 'mgpg_social_share_gap', 3029 [ 3030 'label' => __('Gap Between Buttons', 'magical-posts-display'), 3031 'type' => \Elementor\Controls_Manager::SLIDER, 3032 'size_units' => ['px'], 3033 'range' => [ 3034 'px' => [ 3035 'min' => 0, 3036 'max' => 30, 3037 'step' => 1, 3038 ], 3039 ], 3040 'default' => [ 3041 'unit' => 'px', 3042 'size' => 8, 3043 ], 3044 'selectors' => [ 3045 '{{WRAPPER}} .mgpd-social-share' => 'gap: {{SIZE}}{{UNIT}};', 3046 ], 3047 ] 3048 ); 3049 3050 $this->add_responsive_control( 3051 'mgpg_social_share_margin', 3052 [ 3053 'label' => __('Margin', 'magical-posts-display'), 3054 'type' => \Elementor\Controls_Manager::DIMENSIONS, 3055 'size_units' => ['px', 'em', '%'], 3056 'selectors' => [ 3057 '{{WRAPPER}} .mgpd-social-share' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 3058 ], 3059 ] 3060 ); 3061 3062 // Social Button Colors with Tabs 3063 $this->add_control( 3064 'mgpg_social_colors_heading', 3065 [ 3066 'label' => __('Individual Button Colors', 'magical-posts-display'), 3067 'type' => \Elementor\Controls_Manager::HEADING, 3068 'separator' => 'before', 3069 ] 3070 ); 3071 3072 $this->start_controls_tabs('mgpg_social_colors_tabs'); 3073 3074 // Normal State Tab 3075 $this->start_controls_tab( 3076 'mgpg_social_normal_tab', 3077 [ 3078 'label' => __('Normal', 'magical-posts-display'), 3079 ] 3080 ); 3081 3082 $this->add_control( 3083 'mgpg_social_facebook_color', 3084 [ 3085 'label' => __('Facebook', 'magical-posts-display'), 3086 'type' => \Elementor\Controls_Manager::COLOR, 3087 'selectors' => [ 3088 '{{WRAPPER}} .mgpd-share-facebook' => 'background-color: {{VALUE}};', 3089 ], 3090 ] 3091 ); 3092 3093 $this->add_control( 3094 'mgpg_social_twitter_color', 3095 [ 3096 'label' => __('X (Twitter)', 'magical-posts-display'), 3097 'type' => \Elementor\Controls_Manager::COLOR, 3098 'selectors' => [ 3099 '{{WRAPPER}} .mgpd-share-twitter' => 'background-color: {{VALUE}};', 3100 ], 3101 ] 3102 ); 3103 3104 $this->add_control( 3105 'mgpg_social_linkedin_color', 3106 [ 3107 'label' => __('LinkedIn', 'magical-posts-display'), 3108 'type' => \Elementor\Controls_Manager::COLOR, 3109 'selectors' => [ 3110 '{{WRAPPER}} .mgpd-share-linkedin' => 'background-color: {{VALUE}};', 3111 ], 3112 ] 3113 ); 3114 3115 $this->add_control( 3116 'mgpg_social_pinterest_color', 3117 [ 3118 'label' => __('Pinterest', 'magical-posts-display'), 3119 'type' => \Elementor\Controls_Manager::COLOR, 3120 'selectors' => [ 3121 '{{WRAPPER}} .mgpd-share-pinterest' => 'background-color: {{VALUE}};', 3122 ], 3123 ] 3124 ); 3125 3126 $this->add_control( 3127 'mgpg_social_instagram_color', 3128 [ 3129 'label' => __('Instagram', 'magical-posts-display'), 3130 'type' => \Elementor\Controls_Manager::COLOR, 3131 'selectors' => [ 3132 '{{WRAPPER}} .mgpd-share-instagram' => 'background-color: {{VALUE}};', 3133 ], 3134 ] 3135 ); 3136 3137 $this->end_controls_tab(); 3138 3139 // Hover State Tab 3140 $this->start_controls_tab( 3141 'mgpg_social_hover_tab', 3142 [ 3143 'label' => __('Hover', 'magical-posts-display'), 3144 ] 3145 ); 3146 3147 $this->add_control( 3148 'mgpg_social_facebook_hover_color', 3149 [ 3150 'label' => __('Facebook', 'magical-posts-display'), 3151 'type' => \Elementor\Controls_Manager::COLOR, 3152 'selectors' => [ 3153 '{{WRAPPER}} .mgpd-share-facebook:hover' => 'background-color: {{VALUE}};', 3154 ], 3155 ] 3156 ); 3157 3158 $this->add_control( 3159 'mgpg_social_twitter_hover_color', 3160 [ 3161 'label' => __('X (Twitter)', 'magical-posts-display'), 3162 'type' => \Elementor\Controls_Manager::COLOR, 3163 'selectors' => [ 3164 '{{WRAPPER}} .mgpd-share-twitter:hover' => 'background-color: {{VALUE}};', 3165 ], 3166 ] 3167 ); 3168 3169 $this->add_control( 3170 'mgpg_social_linkedin_hover_color', 3171 [ 3172 'label' => __('LinkedIn', 'magical-posts-display'), 3173 'type' => \Elementor\Controls_Manager::COLOR, 3174 'selectors' => [ 3175 '{{WRAPPER}} .mgpd-share-linkedin:hover' => 'background-color: {{VALUE}};', 3176 ], 3177 ] 3178 ); 3179 3180 $this->add_control( 3181 'mgpg_social_pinterest_hover_color', 3182 [ 3183 'label' => __('Pinterest', 'magical-posts-display'), 3184 'type' => \Elementor\Controls_Manager::COLOR, 3185 'selectors' => [ 3186 '{{WRAPPER}} .mgpd-share-pinterest:hover' => 'background-color: {{VALUE}};', 3187 ], 3188 ] 3189 ); 3190 3191 $this->add_control( 3192 'mgpg_social_instagram_hover_color', 3193 [ 3194 'label' => __('Instagram', 'magical-posts-display'), 3195 'type' => \Elementor\Controls_Manager::COLOR, 3196 'selectors' => [ 3197 '{{WRAPPER}} .mgpd-share-instagram:hover' => 'background-color: {{VALUE}};', 3198 ], 3199 ] 3200 ); 3201 3202 $this->end_controls_tab(); 3203 $this->end_controls_tabs(); 3204 3205 // Hover Effects 3206 $this->add_control( 3207 'mgpg_social_hover_heading', 3208 [ 3209 'label' => __('Hover Effects', 'magical-posts-display'), 3210 'type' => \Elementor\Controls_Manager::HEADING, 3211 'separator' => 'before', 3212 ] 3213 ); 3214 3215 $this->add_control( 3216 'mgpg_social_hover_scale', 3217 [ 3218 'label' => __('Scale on Hover', 'magical-posts-display'), 3219 'type' => \Elementor\Controls_Manager::SWITCHER, 3220 'label_on' => __('Yes', 'magical-posts-display'), 3221 'label_off' => __('No', 'magical-posts-display'), 3222 'return_value' => 'yes', 3223 'default' => 'yes', 3224 'selectors' => [ 3225 '{{WRAPPER}} .mgpd-social-share a:hover' => 'transform: scale(1.1);', 3226 ], 3227 ] 3228 ); 3229 3230 $this->add_control( 3231 'mgpg_social_transition_speed', 3232 [ 3233 'label' => __('Transition Speed (ms)', 'magical-posts-display'), 3234 'type' => \Elementor\Controls_Manager::SLIDER, 3235 'range' => [ 3236 'px' => [ 3237 'min' => 100, 3238 'max' => 1000, 3239 'step' => 50, 3240 ], 3241 ], 3242 'default' => [ 3243 'size' => 300, 3244 ], 3245 'selectors' => [ 3246 '{{WRAPPER}} .mgpd-social-share a' => 'transition: all {{SIZE}}ms ease;', 3247 ], 3248 ] 3249 ); 3250 3251 $this->end_controls_section(); 3252 } 3253 3254 /** 3255 * Render premium features content 3256 * 3257 * @param string $reading_time Show reading time 3258 * @param string $view_count Show view count 3259 * @param string $social_share Show social share 3260 */ 3261 private function render_premium_features_content($reading_time, $view_count, $social_share) 3262 { 3263 3264 if ($reading_time || $view_count) { 3265 echo '<div class="mgpd-time-count-wrap">'; 3266 // Reading Time Display 3267 if ($reading_time) { 3268 $content = get_the_content(); 3269 $word_count = str_word_count(wp_strip_all_tags($content)); 3270 $reading_time_value = ceil($word_count / 200); // Average reading speed: 200 words per minute 3271 echo '<div class="mgpd-reading-time">' . $this->get_reading_time_icon(16) . ' ' . $reading_time_value . ' min read</div>'; 3272 } 3273 3274 // Post Views Counter 3275 if ($view_count) { 3276 $post_views = get_post_meta(get_the_ID(), 'mp_post_post_viewed', true); 3277 $post_views = $post_views ? $post_views : 0; 3278 echo '<div class="mgpd-view-count">' . $this->get_view_count_icon(16) . ' ' . number_format($post_views) . ' views</div>'; 3279 } 3280 echo '</div>'; 3281 } 3282 // Social Share Buttons 3283 if ($social_share) { 3284 $post_url = get_permalink(); 3285 $post_title = get_the_title(); 3286 echo '<div class="mgpd-social-share">'; 3287 echo $this->get_all_social_share_buttons($post_url, $post_title, null, 20); 3288 echo '</div>'; 3289 } 3290 } 3291 3292 /** 3293 * Render single post item 3294 * Reusable method for both normal render and AJAX responses 3295 * 3296 * @param array $settings Widget settings 3297 * @param string $item_class CSS classes for the item wrapper 3298 */ 3299 private function render_single_post_item($settings, $item_class = '') 3300 { 3301 $mgpg_post_style = $settings['mgpg_post_style']; 3302 $mgpg_post_type = $settings['mgpg_post_type']; 3303 $mgpg_post_img_show = $settings['mgpg_post_img_show']; 3304 $mgpg_media_source = $settings['mgpg_media_source'] ?? 'featured'; 3305 $mgpg_premium_features_style = $settings['mgpg_premium_features_style'] ?? 'default'; 3306 $mgpg_show_title = $settings['mgpg_show_title']; 3307 $mgpg_title_tag = $settings['mgpg_title_tag']; 3308 $mgpg_crop_title = $settings['mgpg_crop_title']; 3309 $mgpg_desc_show = $settings['mgpg_desc_show']; 3310 $mgpg_crop_desc = $settings['mgpg_crop_desc']; 3311 $mgpg_post_btn = $settings['mgpg_post_btn']; 3312 $mgpg_btn_title = $settings['mgpg_btn_title']; 3313 $mgpg_usebtn_icon = $settings['mgpg_usebtn_icon']; 3314 $mgpg_btn_icon_position = $settings['mgpg_btn_icon_position'] ?? 'right'; 3315 $mgpg_btn_target = $settings['mgpg_btn_target']; 3316 $mgpg_reading_time = $settings['mgpg_reading_time'] ?? false; 3317 $mgpg_view_count = $settings['mgpg_view_count'] ?? false; 3318 $mgpg_social_share = $settings['mgpg_social_share'] ?? false; 3319 ?> 3320 <div class="<?php echo esc_attr($item_class); ?>"> 3321 <div class="card mg-card mg-shadow mgp-card mb-4"> 3322 <?php 3323 if ($mgpg_post_img_show) { 3324 echo '<div class="mp-post-img">'; 3325 3326 // Check if using advanced media source (Pro Only) 3327 if (mp_display_check_main_ok() && $mgpg_media_source && $mgpg_media_source !== 'featured') { 3328 $media_settings = array( 3329 'mgpg_media_source' => $mgpg_media_source, 3330 'mgpg_media_priority' => $settings['mgpg_media_priority'] ?? array('video', 'featured', 'content', 'placeholder'), 3331 'mgpg_video_play_icon' => $settings['mgpg_video_play_icon'] ?? 'yes' 3332 ); 3333 echo $this->get_advanced_media(get_the_ID(), $media_settings); 3334 } else { 3335 // Use default featured image 3336 mp_post_thumbnail($mgpg_post_img_show); 3337 } 3338 3339 // Premium features - Image Top style 3340 if (mp_display_check_main_ok() && $mgpg_premium_features_style === 'image-top') { 3341 echo '<div class="mgpd-premium-features">'; 3342 $this->render_premium_features_content($mgpg_reading_time, $mgpg_view_count, $mgpg_social_share); 3343 echo '</div>'; 3344 } 3345 3346 // Premium features - Image Overlay style 3347 if (mp_display_check_main_ok() && $mgpg_premium_features_style === 'image-overlay') { 3348 echo '<div class="mgpd-premium-features">'; 3349 $this->render_premium_features_content($mgpg_reading_time, $mgpg_view_count, $mgpg_social_share); 3350 echo '</div>'; 3351 } 3352 3353 echo '</div>'; 3354 } 3355 ?> 3356 <div class="mg-card-text card-body"> 3357 <?php 3358 if ($mgpg_post_style == '3') { 3359 ?> 3360 <div class="magical-post-authon-category"> 3361 <?php 3362 mpd_posts_meta($settings['mgpg_author_show']); 3363 mp_post_cat_display($settings['mgpg_category_show']); 3364 ?> 3365 </div> 3366 <?php 3367 } 3368 if ($mgpg_post_type == 'post' && ($mgpg_post_style == '1' || $mgpg_post_style == '2')) { 3369 mp_post_cat_display($settings['mgpg_category_show'], $settings['mgpg_cat_type'] ?? 'one', ', '); 3370 } 3371 ?> 3372 <?php 3373 mp_post_title($mgpg_show_title, $mgpg_title_tag, $mgpg_crop_title); 3374 ?> 3375 <?php 3376 if ($mgpg_post_style == '1') { 3377 mpd_posts_meta($settings['mgpg_author_show'], $settings['mgpg_date_show'], $settings['mgpg_comment_icon_show']); 3378 } 3379 ?> 3380 <?php if ($mgpg_desc_show) : ?> 3381 <p><?php 3382 if (has_excerpt()) { 3383 echo esc_html(wp_trim_words(get_the_excerpt(), $mgpg_crop_desc, '...')); 3384 } else { 3385 echo esc_html(wp_trim_words(get_the_content(), $mgpg_crop_desc, '...')); 3386 } 3387 ?> 3388 </p> 3389 <?php endif; ?> 3390 3391 <?php 3392 // Premium Features Content (Pro Only) - Only show in default position 3393 if (mp_display_check_main_ok() && (!$mgpg_premium_features_style || $mgpg_premium_features_style === 'default')) { 3394 $this->render_premium_features_content($mgpg_reading_time, $mgpg_view_count, $mgpg_social_share); 3395 } 3396 ?> 3397 3398 <?php 3399 if ($mgpg_post_style == '3') { 3400 ?> 3401 <div class="mgp_there_style-time"> 3402 <span> 3403 <i class="fa-regular fa-calendar-days"></i> 3404 <?php echo esc_html(get_the_date('d M Y')); ?> 3405 </span> 3406 <?php 3407 if ($mgpg_post_btn && ($mgpg_post_style == '3')) { 3408 mp_post_btn( 3409 $text = $mgpg_btn_title, 3410 $icon_show = $mgpg_usebtn_icon, 3411 $icon = $settings['mgpg_btn_icon'], 3412 $icon_position = $mgpg_btn_icon_position, 3413 $target = $mgpg_btn_target, 3414 $class = $settings['mgpg_link_type'] ?? '' 3415 ); 3416 } 3417 ?> 3418 </div> 3419 <?php 3420 } 3421 if ($mgpg_post_btn && ($mgpg_post_style == '1' || $mgpg_post_style == '2')) { 3422 mp_post_btn( 3423 $text = $mgpg_btn_title, 3424 $icon_show = $mgpg_usebtn_icon, 3425 $icon = $settings['mgpg_btn_icon'], 3426 $icon_position = $mgpg_btn_icon_position, 3427 $target = $mgpg_btn_target, 3428 $class = $settings['mgpg_link_type'] ?? '' 3429 ); 3430 } 3431 3432 if ($mgpg_post_style == '2') { 3433 mpd_posts_meta_author_date($settings['mgpg_author_show'], $settings['mgpg_date_show']); 3434 } 3435 3436 mpd_post_tags($settings['mgpg_tag_show']); 3437 3438 ?> 3439 </div> 3440 3441 </div> 3442 </div> 3443 <?php 2380 3444 } 2381 3445 … … 2481 3545 2482 3546 //grid layout 3547 $mgpg_layout_type = $this->get_settings('mgpg_layout_type'); 3548 $mgpg_masonry_style = $this->get_settings('mgpg_masonry_style'); 2483 3549 $mgpg_post_style = $this->get_settings('mgpg_post_style'); 2484 3550 $mgpg_rownumber = $this->get_settings('mgpg_rownumber'); … … 2496 3562 $mgpg_btn_target = $this->get_settings('mgpg_btn_target'); 2497 3563 $mgpg_btn_icon = $this->get_settings('mgpg_btn_icon'); 3564 3565 // Premium Features Settings (Pro Only) 3566 $mgpg_ajax_filter = $this->get_settings('mgpg_ajax_filter'); 3567 $mgpg_infinite_scroll = $this->get_settings('mgpg_infinite_scroll'); 3568 $mgpg_reading_time = $this->get_settings('mgpg_reading_time'); 3569 $mgpg_view_count = $this->get_settings('mgpg_view_count'); 3570 $mgpg_social_share = $this->get_settings('mgpg_social_share'); 3571 $mgpg_hover_effects = $this->get_settings('mgpg_hover_effects'); 3572 $mgpg_premium_features_style = $this->get_settings('mgpg_premium_features_style'); 3573 $mgpg_media_source = $this->get_settings('mgpg_media_source'); 2498 3574 $mgpg_btn_icon_position = $this->get_settings('mgpg_btn_icon_position'); 2499 3575 … … 2509 3585 $column_set = 'col-lg-' . $mgpg_rownumber . ' col-md-6'; 2510 3586 } 2511 ?> 2512 <div id="mgp-items" class="mgpd mgp-items style<?php echo esc_attr($mgpg_post_style); ?>"> 2513 <div class="row" data-masonry='{"percentPosition": true }'> 2514 <?php while ($mgpg_posts->have_posts()) : $mgpg_posts->the_post(); ?> 2515 <div class="<?php echo esc_attr($column_set); ?>"> 2516 <div class="card mg-card mg-shadow mgp-card mb-4"> 2517 <?php mp_post_thumbnail($mgpg_post_img_show); ?> 2518 <div class="mg-card-text card-body"> 3587 3588 // Add masonry specific classes 3589 $container_class = 'mgpd mgp-items style' . esc_attr($mgpg_post_style); 3590 $row_class = 'row'; 3591 $item_class = $column_set; 3592 3593 // Add premium feature classes 3594 if ($mgpg_ajax_filter && mp_display_check_main_ok()) { 3595 $container_class .= ' mgpd-ajax-filter-enabled'; 3596 } 3597 if ($mgpg_infinite_scroll && mp_display_check_main_ok()) { 3598 $container_class .= ' mgpd-infinite-scroll'; 3599 } 3600 if ($mgpg_hover_effects && $mgpg_hover_effects !== 'none' && mp_display_check_main_ok()) { 3601 $container_class .= ' mgpd-hover-' . esc_attr($mgpg_hover_effects); 3602 } 3603 // Add premium features style class 3604 if ($mgpg_premium_features_style && $mgpg_premium_features_style !== 'default' && mp_display_check_main_ok()) { 3605 $container_class .= ' mgpd-premium-' . esc_attr($mgpg_premium_features_style); 3606 } 3607 3608 if ($mgpg_layout_type === 'masonry') { 3609 $masonry_style = $mgpg_masonry_style ? $mgpg_masonry_style : 'style1'; 3610 $container_class .= ' mgpd-masonry-container mgpd-masonry-' . esc_attr($masonry_style); 3611 $row_class .= ' mgpd-masonry'; 3612 $item_class .= ' mgpd-masonry-item'; 3613 } 3614 ?> 3615 3616 <?php 3617 // Premium Features - Category Filter (Pro Only) - Move to top 3618 if (mp_display_check_main_ok() && $mgpg_ajax_filter && $mgpg_post_type == 'post') { 3619 $categories = get_categories(array('hide_empty' => true)); 3620 if (!empty($categories)) { 3621 echo '<div class="mgpd-ajax-filter-container">'; 3622 echo '<div class="mgpd-filter-buttons">'; 3623 echo '<button class="mgpd-filter-btn active" data-category="all">' . __('All', 'magical-posts-display') . '</button>'; 3624 foreach ($categories as $category) { 3625 echo '<button class="mgpd-filter-btn" data-category="' . esc_attr($category->slug) . '">' . esc_html($category->name) . '</button>'; 3626 } 3627 echo '</div>'; 3628 echo '</div>'; 3629 } 3630 } 3631 ?> 3632 3633 <div id="mgp-items" class="<?php echo esc_attr($container_class); ?>"> 3634 <div class="<?php echo esc_attr($row_class); ?>"> 3635 <?php while ($mgpg_posts->have_posts()) : $mgpg_posts->the_post(); ?> 3636 <?php $this->render_single_post_item($settings, $item_class); ?> 2519 3637 <?php 2520 if ($mgpg_post_style == '3') { 3638 endwhile; 3639 wp_reset_postdata(); 3640 wp_reset_postdata(); 2521 3641 ?> 2522 <div class="magical-post-authon-category"> 2523 <?php 2524 mpd_posts_meta($settings['mgpg_author_show']); 2525 mp_post_cat_display($settings['mgpg_category_show']); 2526 ?> 2527 </div> 2528 <?php 3642 </div> 3643 </div> 3644 3645 <?php 3646 // Inline Masonry Initialization Script for better compatibility 3647 if ($mgpg_layout_type === 'masonry') { 3648 $widget_id = uniqid('mgpd_masonry_'); 3649 ?> 3650 <script type="text/javascript"> 3651 (function() { 3652 // Initialize masonry for this specific widget 3653 function initMasonry<?php echo $widget_id; ?>() { 3654 var container = document.querySelector('.mgpd-masonry-container'); 3655 if (container && typeof Masonry !== 'undefined' && typeof imagesLoaded !== 'undefined') { 3656 var masonryGrid = container.querySelector('.mgpd-masonry'); 3657 if (masonryGrid) { 3658 // Force all images to load first 3659 imagesLoaded(masonryGrid, function() { 3660 // Clear any existing height to let masonry calculate properly 3661 masonryGrid.style.height = ''; 3662 3663 // Initialize masonry 3664 var masonry = new Masonry(masonryGrid, { 3665 itemSelector: '.mgpd-masonry-item', 3666 columnWidth: '.mgpd-masonry-item', 3667 percentPosition: true, 3668 transitionDuration: 0 3669 }); 3670 3671 // Store instance for global access 3672 window.mgpdMasonryInstance = masonry; 3673 3674 // Force layout calculation after a brief delay 3675 setTimeout(function() { 3676 masonry.layout(); 3677 }, 100); 3678 }); 3679 } 3680 } 2529 3681 } 2530 if ($mgpg_post_type == 'post' && ($mgpg_post_style == '1' || $mgpg_post_style == '2')) { 2531 mp_post_cat_display($settings['mgpg_category_show'], $settings['mgpg_cat_type'], ', '); 2532 } 2533 ?> 2534 <?php 2535 mp_post_title($mgpg_show_title, $mgpg_title_tag, $mgpg_crop_title); 2536 ?> 2537 <?php 2538 if ($mgpg_post_style == '1') { 2539 mpd_posts_meta($settings['mgpg_author_show'], $settings['mgpg_date_show'], $settings['mgpg_comment_icon_show']); 3682 3683 // Initialize when DOM is ready 3684 if (document.readyState === 'loading') { 3685 document.addEventListener('DOMContentLoaded', initMasonry<?php echo $widget_id; ?>); 3686 } else { 3687 initMasonry<?php echo $widget_id; ?>(); 2540 3688 } 2541 ?> 2542 <?php if ($mgpg_desc_show) : ?> 2543 <p><?php 2544 if (has_excerpt()) { 2545 echo esc_html(wp_trim_words(get_the_excerpt(), $mgpg_crop_desc, '...')); 2546 } else { 2547 echo esc_html(wp_trim_words(get_the_content(), $mgpg_crop_desc, '...')); 2548 } 2549 ?> 2550 </p> 2551 <?php endif; ?> 2552 <?php 2553 if ($mgpg_post_style == '3') { 2554 ?> 2555 <div class="mgp_there_style-time"> 2556 <span> 2557 <i class="fa-regular fa-calendar-days"></i> 2558 <?php echo esc_html(get_the_date('d M Y')); ?> 2559 </span> 2560 <?php 2561 if ($mgpg_post_btn && ($mgpg_post_style == '3')) { 2562 mp_post_btn( 2563 $text = $mgpg_btn_title, 2564 $icon_show = $mgpg_usebtn_icon, 2565 $icon = $settings['mgpg_btn_icon'], 2566 $icon_position = $mgpg_btn_icon_position, 2567 $target = $mgpg_btn_target, 2568 $class = $settings['mgpg_link_type'] 2569 ); 2570 } 2571 ?> 2572 </div> 2573 <?php 2574 } 2575 if ($mgpg_post_btn && ($mgpg_post_style == '1' || $mgpg_post_style == '2')) { 2576 mp_post_btn( 2577 $text = $mgpg_btn_title, 2578 $icon_show = $mgpg_usebtn_icon, 2579 $icon = $settings['mgpg_btn_icon'], 2580 $icon_position = $mgpg_btn_icon_position, 2581 $target = $mgpg_btn_target, 2582 $class = $settings['mgpg_link_type'] 2583 ); 2584 } 2585 2586 if ($mgpg_post_style == '2') { 2587 mpd_posts_meta_author_date($settings['mgpg_author_show'], $settings['mgpg_date_show']); 2588 } 2589 2590 mpd_post_tags($settings['mgpg_tag_show']); 2591 2592 ?> 2593 </div> 2594 2595 </div> 2596 </div> 2597 <?php 2598 endwhile; 2599 wp_reset_query(); 2600 wp_reset_postdata(); 3689 3690 // Also initialize on window load as fallback 3691 window.addEventListener('load', initMasonry<?php echo $widget_id; ?>); 3692 })(); 3693 </script> 3694 <?php 3695 } 2601 3696 ?> 2602 </div> 2603 </div> 2604 2605 <?php 3697 3698 <?php 2606 3699 if ($mgpg_pagination_show) { 2607 3700 mp_display_pagination($paged, $mgpg_posts, $settings['mgpg_pagination_style']); 2608 3701 } 2609 3702 ?> 3703 3704 <?php 3705 // Premium Features JavaScript & HTML (Pro Only) 3706 if (mp_display_check_main_ok()) { 3707 3708 // Infinite Scroll Trigger 3709 if ($mgpg_infinite_scroll) { 3710 echo '<div class="mgpd-infinite-scroll-trigger" style="height: 1px; margin-top: 50px;"></div>'; 3711 echo '<div class="mgpd-loading-spinner" style="display: none; text-align: center; padding: 20px;">'; 3712 echo $this->get_loading_spinner_icon(40); 3713 echo '<span>' . __('Loading more posts...', 'magical-posts-display') . '</span>'; 3714 echo '</div>'; 3715 } 3716 3717 // Only localize script if any premium features are enabled 3718 if ($mgpg_ajax_filter || $mgpg_infinite_scroll || ($mgpg_hover_effects && $mgpg_hover_effects !== 'none')) { 3719 // Localize script data for JavaScript 3720 wp_localize_script('mgpd-premium-features', 'mgpd_ajax', array( 3721 'ajaxurl' => admin_url('admin-ajax.php'), 3722 'nonce' => wp_create_nonce('mgpd_ajax_nonce'), 3723 'settings' => $settings, 3724 'layout_type' => $mgpg_layout_type, 3725 'ajax_filter_enabled' => $mgpg_ajax_filter && $mgpg_post_type == 'post', 3726 'infinite_scroll_enabled' => $mgpg_infinite_scroll, 3727 'hover_effects_enabled' => $mgpg_hover_effects && $mgpg_hover_effects !== 'none', 3728 'current_page' => $paged, 3729 'max_pages' => $mgpg_posts->max_num_pages, 3730 'post_type' => $mgpg_post_type, 3731 'texts' => array( 3732 'error_loading' => __('Error loading posts. Please try again.', 'magical-posts-display'), 3733 'loading_more' => __('Loading more posts...', 'magical-posts-display') 3734 ) 3735 )); 3736 } 3737 } 3738 ?> 3739 2610 3740 <?php else : 2611 3741 mp_display_posts_not_found($settings['mgpg_post_type']); 2612 3742 endif; 2613 3743 } 3744 3745 /** 3746 * AJAX handler for category filtering 3747 * Static method to be called from WordPress AJAX hooks 3748 */ 3749 public static function ajax_filter_posts() 3750 { 3751 // Check nonce for security 3752 if (!isset($_POST['nonce']) || !wp_verify_nonce(wp_unslash($_POST['nonce']), 'mgpd_ajax_nonce')) { 3753 wp_die(__('Security check failed', 'magical-posts-display')); 3754 } 3755 3756 // Check if pro version is active 3757 if (!mp_display_check_main_ok()) { 3758 wp_send_json_error(__('Premium feature requires pro version', 'magical-posts-display')); 3759 } 3760 3761 $category = isset($_POST['category']) ? sanitize_text_field(wp_unslash($_POST['category'])) : ''; 3762 $settings = isset($_POST['settings']) ? wp_unslash($_POST['settings']) : array(); 3763 $post_type = isset($_POST['post_type']) ? sanitize_text_field(wp_unslash($_POST['post_type'])) : 'post'; 3764 3765 // Build query args 3766 $args = array( 3767 'post_type' => $post_type, 3768 'post_status' => 'publish', 3769 'posts_per_page' => isset($settings['mgpg_posts_count']) ? absint($settings['mgpg_posts_count']) : 6, 3770 'ignore_sticky_posts' => 1 3771 ); 3772 3773 // Add category filter if not "all" 3774 if ($category !== 'all' && $post_type === 'post') { 3775 $args['tax_query'] = array( 3776 array( 3777 'taxonomy' => 'category', 3778 'field' => 'slug', 3779 'terms' => $category 3780 ) 3781 ); 3782 } 3783 3784 $query = new WP_Query($args); 3785 $output = ''; 3786 3787 if ($query->have_posts()) { 3788 // Instantiate widget to reuse render method 3789 $widget = new self(); 3790 3791 // Calculate item class - consistent with render() method 3792 $mgpg_rownumber = isset($settings['mgpg_rownumber']) ? $settings['mgpg_rownumber'] : '4'; 3793 $mgpg_layout_type = isset($settings['mgpg_layout_type']) ? $settings['mgpg_layout_type'] : 'grid'; 3794 3795 if ($mgpg_rownumber == '12') { 3796 $item_class = 'col-lg-12'; 3797 } else { 3798 $item_class = 'col-lg-' . $mgpg_rownumber . ' col-md-6'; 3799 } 3800 3801 if ($mgpg_layout_type === 'masonry') { 3802 $item_class .= ' mgpd-masonry-item'; 3803 } 3804 3805 while ($query->have_posts()) { 3806 $query->the_post(); 3807 ob_start(); 3808 $widget->render_single_post_item($settings, $item_class); 3809 $output .= ob_get_clean(); 3810 } 3811 wp_reset_postdata(); 3812 } 3813 3814 wp_send_json_success($output); 3815 } 3816 3817 /** 3818 * AJAX handler for infinite scroll 3819 * Static method to be called from WordPress AJAX hooks 3820 */ 3821 public static function ajax_infinite_scroll() 3822 { 3823 // Check nonce for security 3824 if (!isset($_POST['nonce']) || !wp_verify_nonce(wp_unslash($_POST['nonce']), 'mgpd_ajax_nonce')) { 3825 wp_die(__('Security check failed', 'magical-posts-display')); 3826 } 3827 3828 // Check if pro version is active 3829 if (!mp_display_check_main_ok()) { 3830 wp_send_json_error(__('Premium feature requires pro version', 'magical-posts-display')); 3831 } 3832 3833 $page = isset($_POST['page']) ? absint($_POST['page']) : 1; 3834 $settings = isset($_POST['settings']) ? wp_unslash($_POST['settings']) : array(); 3835 $post_type = isset($_POST['post_type']) ? sanitize_text_field(wp_unslash($_POST['post_type'])) : 'post'; 3836 3837 // Build query args 3838 $args = array( 3839 'post_type' => $post_type, 3840 'post_status' => 'publish', 3841 'posts_per_page' => isset($settings['mgpg_posts_count']) ? absint($settings['mgpg_posts_count']) : 6, 3842 'paged' => $page, 3843 'ignore_sticky_posts' => 1 3844 ); 3845 3846 $query = new WP_Query($args); 3847 $output = ''; 3848 3849 if ($query->have_posts()) { 3850 // Instantiate widget 3851 $widget = new self(); 3852 3853 // Calculate item class - consistent with render() method 3854 $mgpg_rownumber = isset($settings['mgpg_rownumber']) ? $settings['mgpg_rownumber'] : '4'; 3855 $mgpg_layout_type = isset($settings['mgpg_layout_type']) ? $settings['mgpg_layout_type'] : 'grid'; 3856 3857 if ($mgpg_rownumber == '12') { 3858 $item_class = 'col-lg-12'; 3859 } else { 3860 $item_class = 'col-lg-' . $mgpg_rownumber . ' col-md-6'; 3861 } 3862 3863 if ($mgpg_layout_type === 'masonry') { 3864 $item_class .= ' mgpd-masonry-item'; 3865 } 3866 3867 while ($query->have_posts()) { 3868 $query->the_post(); 3869 ob_start(); 3870 $widget->render_single_post_item($settings, $item_class); 3871 $output .= ob_get_clean(); 3872 } 3873 wp_reset_postdata(); 3874 } 3875 wp_send_json_success($output); 3876 } 2614 3877 } -
magical-posts-display/trunk/includes/elementor/widgets/posts-list.php
r3116993 r3380394 1878 1878 <?php 1879 1879 endwhile; 1880 wp_reset_ query();1880 wp_reset_postdata(); 1881 1881 wp_reset_postdata(); 1882 1882 ?> -
magical-posts-display/trunk/includes/elementor/widgets/posts-slider.php
r3324281 r3380394 1700 1700 1701 1701 endwhile; 1702 wp_reset_ query();1702 wp_reset_postdata(); 1703 1703 wp_reset_postdata(); 1704 1704 ?> … … 1742 1742 $mgps_btn_target = $settings['mgps_btn_target']; 1743 1743 $mgps_layout_style = $settings['mgps_layout_style']; 1744 1744 1745 1745 if ($mgps_layout_style === 'style_two') { 1746 1746 $this->render_style_two($settings, $mgpslide_category, $mgps_post_btn, $mgps_btn_title, $mgps_usebtn_icon, $mgps_btn_icon_position, $mgps_btn_target); … … 1800 1800 ?> 1801 1801 </div> 1802 <?php1802 <?php 1803 1803 } 1804 1804 1805 1805 private function render_style_two($settings, $mgpslide_category, $mgps_post_btn, $mgps_btn_title, $mgps_usebtn_icon, $mgps_btn_icon_position, $mgps_btn_target) 1806 1806 { 1807 ?>1807 ?> 1808 1808 <!-- Slides Style Two --> 1809 1809 <div class="swiper-slide mgs-item mgs-item-style-two"> … … 1855 1855 </div> 1856 1856 </div> 1857 <?php1857 <?php 1858 1858 } 1859 1859 } -
magical-posts-display/trunk/includes/elementor/widgets/posts-tab.php
r3116993 r3380394 2094 2094 <?php 2095 2095 endwhile; 2096 wp_reset_ query();2096 wp_reset_postdata(); 2097 2097 wp_reset_postdata(); 2098 2098 ?> -
magical-posts-display/trunk/includes/elementor/widgets/posts-ticker.php
r3235168 r3380394 686 686 <?php 687 687 endwhile; 688 wp_reset_ query();688 wp_reset_postdata(); 689 689 wp_reset_postdata(); 690 690 ?> -
magical-posts-display/trunk/includes/mp-posts-function.php
r3334686 r3380394 78 78 <?php 79 79 // translators: %s: list of categories 80 $categories_text = sprintf(esc_html__('%s', 'magical- addons-for-elementor'), $mpg_cat_list);80 $categories_text = sprintf(esc_html__('%s', 'magical-posts-display'), $mpg_cat_list); 81 81 printf('<span class="mgp-post-cats">%s</span>', wp_kses_post($categories_text)); 82 82 ?> … … 154 154 155 155 156 function mpd_validate_html_tag($tag, $default_tag = 'h2', $allowed_tags = array()) { 156 function mpd_validate_html_tag($tag, $default_tag = 'h2', $allowed_tags = array()) 157 { 157 158 // Use the provided whitelist or fall back to a predefined set of safe tags 158 159 $safe_tags = !empty($allowed_tags) ? $allowed_tags : array( 159 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span', 'p' 160 'h1', 161 'h2', 162 'h3', 163 'h4', 164 'h5', 165 'h6', 166 'div', 167 'span', 168 'p' 160 169 ); 161 170 -
magical-posts-display/trunk/magical-posts-display.php
r3334686 r3380394 1 1 <?php 2 /* 3 * @link http://wpthemespace.com 4 * @since 1.0.0 5 * @package Magical Posts Display 2 3 /** 4 * Plugin Name: Magical Posts Display 5 * Plugin URI: http://wpthemespace.com/magical-posts-display 6 * Description: Show your site posts, Pages and Custom Post Types with many different styles by Elementor Widgets. 7 * Version: 1.2.54 8 * Author: Noor Alam 9 * Author URI: http://wpthemespace.com 10 * Text Domain: magical-posts-display 11 * Domain Path: /languages 12 * Requires at least: 6.0 13 * Requires PHP: 7.4 14 * License: GPL-2.0+ 15 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt 6 16 * 7 * @wordpress-plugin 8 * Plugin Name: Magical Posts Display 9 * Plugin URI: http://wpthemespace.com 10 * Description: Show your site posts, Pages and Custom Post Types with many different styles by Elementor Widgets. 11 * Version: 1.2.53 12 * Author: Noor alam 13 * Author URI: https://profiles.wordpress.org/nalam-1 14 * License: GPL-2.0+ 15 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt 16 * Text Domain: magical-posts-display 17 * Domain Path: /languages 17 * @package magical-posts-display 18 18 */ 19 19 … … 21 21 exit; // Exit if accessed directly. 22 22 } 23 23 24 24 25 /** … … 37 38 * @var string The plugin version. 38 39 */ 39 const version = '1.2.5 3';40 const version = '1.2.54'; 40 41 41 42 /** … … 46 47 * @var string Minimum PHP version required to run the plugin. 47 48 */ 48 const MINIMUM_PHP_VERSION = '5.6'; 49 50 49 const MINIMUM_PHP_VERSION = '7.4'; 51 50 /** 52 51 * Instance … … 96 95 add_action('plugins_loaded', [$this, 'init']); 97 96 add_filter('plugin_action_links_' . plugin_basename(__FILE__), [$this, 'admin_adminpro_link']); 98 add_action('init', [$this, 'elementor_notice_hide_options']);99 97 require_once('lib/custom-template/pagetemplater.php'); 100 98 require_once('includes/elementor/extra.php'); 101 99 } 102 100 103 // After active go homepage 104 /* 105 public function mgpd_plugin_homego($plugin) 106 { 107 if (plugin_basename(__FILE__) == $plugin) { 108 wp_redirect(admin_url('admin.php?page=mgpd-page')); 109 die(); 110 } 111 } 112 */ 101 // After active go homepage - functionality removed 102 // Was: mgpd_plugin_homego method for redirect after activation 113 103 114 104 public function admin_adminpro_link($links) 115 105 { 116 $newlink = sprintf("<a target='_blank' href='%s'><span style='color:red;font-weight:bold'>%s</span></a>", esc_url('https://wpthemespace.com/product/magical-posts-display-pro/?add-to-cart=8239'), __('Get Pro', ' optionsdemo'));106 $newlink = sprintf("<a target='_blank' href='%s'><span style='color:red;font-weight:bold'>%s</span></a>", esc_url('https://wpthemespace.com/product/magical-posts-display-pro/?add-to-cart=8239'), __('Get Pro', 'magical-posts-display')); 117 107 if (empty(mp_display_check_main_ok())) { 118 108 $links[] = $newlink; … … 147 137 public function init() 148 138 { 149 139 // Include all plugin files 150 140 require_once('file-include.php'); 151 141 152 // require_once( 'lib/carbon-fields/vendor/autoload.php' );142 // Initialize new user settings 153 143 $this->mgposts_new_user(); 154 144 145 // Handle Carbon Fields loading for older installations 155 146 $install_date = gmdate("Y-m-d", strtotime(get_option('mgposte_install_date', current_time('mysql', true)))); 156 147 $compare_date = '2023-03-07'; … … 162 153 } 163 154 164 165 166 155 // Check for required PHP version 167 156 if (version_compare(PHP_VERSION, self::MINIMUM_PHP_VERSION, '<')) { 168 add_action('admin_notices', [$this, 'admin_notice_minimum_php_version']); 169 return; 170 } 171 // 172 add_action('admin_enqueue_scripts', [$this, 'mgpost_display_editor_scripts']); 173 add_action('enqueue_block_assets', [$this, 'mgpblock_style']); 174 add_action('enqueue_block_assets', [$this, 'mgpblock_scripts']); 175 add_action('enqueue_block_editor_assets', [$this, 'mgpblock_editor_scripts']); 176 177 // Add image size 178 add_image_size('slider-bg', 1600, 600, true); 179 add_image_size('card-grid', 600, 900, true); 180 add_image_size('card-list', 600, 700, true); 181 182 // Check if Elementor installed and activated 157 return; // Admin notice is now handled by admin-info.php 158 } 159 160 // Load Elementor integration if available 183 161 if (did_action('elementor/loaded')) { 184 162 require_once('includes/elementor/elementor-main.php'); 185 } else { 186 global $pagenow; 187 if (in_array($pagenow, array('plugins.php', 'admin.php')) && !(get_option('mgelhide9'))) { 188 add_action('admin_notices', [$this, 'admin_notice_missing_main_plugin']); 163 } 164 165 // Track plugin activation and installation 166 $this->track_plugin_usage(); 167 168 // Initialize Appsero tracking after 2 days 169 $mgposte_install_date = get_option('mgposte_install_date'); 170 if (!empty($mgposte_install_date)) { 171 $install_day = round((time() - strtotime($mgposte_install_date)) / 24 / 60 / 60); 172 if ($install_day > 2) { 173 //$this->appsero_init_tracker_magical_posts_display(); 189 174 } 190 175 } 176 } 177 178 /** 179 * Track plugin usage 180 */ 181 public function track_plugin_usage() 182 { 191 183 $is_plugin_activated = get_option('mgposte_plugin_activated'); 192 184 if ('yes' !== $is_plugin_activated) { 193 185 update_option('mgposte_plugin_activated', 'yes'); 194 186 } 187 195 188 $mgposte_install_date = get_option('mgposte_install_date'); 196 189 if (empty($mgposte_install_date)) { 197 190 update_option('mgposte_install_date', current_time('mysql')); 198 191 } 199 if (!empty($mgposte_install_date)) {200 $install_day = round((time() - strtotime($mgposte_install_date)) / 24 / 60 / 60);201 if ($install_day > 2) {202 $this->appsero_init_tracker_magical_posts_display();203 }204 }205 }206 207 public function elementor_notice_hide_options()208 {209 if (isset($_GET['mgelhide']) && $_GET['mgelhide'] == 1) {210 // delete_option( 'mgelhide');211 update_option('mgelhide9', 1);212 }213 }214 215 216 /**217 * Admin notice218 *219 * Warning when the site doesn't have Elementor installed or activated.220 *221 * @since 1.0.0222 *223 * @access public224 */225 public function admin_notice_missing_main_plugin()226 {227 if (get_option('mgelhide9')) {228 return;229 }230 if (isset($_GET['activate'])) unset($_GET['activate']);231 232 233 if (file_exists(WP_PLUGIN_DIR . '/elementor/elementor.php')) {234 $magial_eactive_url = wp_nonce_url('plugins.php?action=activate&plugin=elementor/elementor.php&plugin_status=all&paged=1', 'activate-plugin_elementor/elementor.php');235 $message = sprintf(236 /* translators: 1: Plugin name 2: Elementor 3: Elementor installation link */237 esc_html__('%1$s Recommended %2$s plugin, which is currently NOT RUNNING %3$s', 'magical-posts-display'),238 '<strong>' . esc_html__('Magical Posts Display', 'magical-posts-display') . '</strong>',239 '<strong>' . esc_html__('Elementor', 'magical-posts-display') . '</strong>',240 '<a class="button button-primary" style="margin-left:20px" href="' . $magial_eactive_url . '">' . __('Activate Elementor', 'magical-posts-display') . '</a>'241 242 );243 } else {244 $magial_einstall_url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=elementor'), 'install-plugin_elementor');245 $message = sprintf(246 /* translators: 1: Plugin name 2: Elementor 3: Elementor installation link */247 esc_html__('%1$s Recommended %2$s plugin for use all Elementor addons, which is currently NOT RUNNING %3$s', 'magical-posts-display'),248 '<strong>' . esc_html__('Magical Posts Display', 'magical-posts-display') . '</strong>',249 '<strong>' . esc_html__('Elementor', 'magical-posts-display') . '</strong>',250 '<a class="button button-primary" style="margin-left:20px" href="' . $magial_einstall_url . '">' . __('Install Elementor', 'magical-posts-display') . '</a>'251 /* '<a class="button skipelementor" style="margin-left:20px" href="#">' . __('Skip it for only use Gutenberg addons', 'magical-posts-display') . '</a>' */252 253 );254 }255 256 printf('<div class="notice notice-warning is-dismissible mgpd-notice"><p style="padding: 13px 0">%1$s</p></div>', wp_kses_post($message));257 }258 259 260 261 /**262 * Add style and scripts263 *264 * Add the plugin style and scripts for this265 *266 * @since 1.0.0267 *268 * @access public269 */270 public function mgpblock_style()271 {272 wp_register_style(273 'swiper',274 plugins_url('/assets/css/swiper.min.css', __FILE__),275 [],276 '8.4.5',277 'all'278 );279 280 wp_enqueue_style('venobox.min', plugins_url('/assets/css/venobox.min.css', __FILE__), array(), '1.0.0', 'all');281 wp_enqueue_style('bootstrap', plugins_url('/assets/css/bootstrap.min.css', __FILE__), array(), '5.1.1', 'all');282 wp_enqueue_style('mpd-fonts', plugins_url('/assets/css/fontello.css', __FILE__), array(), MAGICAL_POSTS_DISPLAY_VERSION, 'all');283 // wp_enqueue_style('swiper.min', plugins_url('/assets/css/swiper.min.css', __FILE__), array(), '5.3.8', 'all');284 wp_enqueue_style('mpd-style', plugins_url('/assets/css/mp-style.css', __FILE__), array(), MAGICAL_POSTS_DISPLAY_VERSION, 'all');285 }286 287 public function mgpblock_scripts()288 {289 290 wp_register_script(291 'mg-swiper',292 plugins_url('/assets/js/swiper.min.js', __FILE__),293 ['jquery'],294 '8.4.5',295 true296 );297 wp_register_script(298 'jquery.easy-ticker',299 plugins_url('/assets/js/jquery.easy-ticker.min.js', __FILE__),300 ['jquery'],301 '3.1.0',302 true303 );304 305 wp_enqueue_script('masonry');306 wp_enqueue_script('venobox-js', plugins_url('/assets/js/venobox.min.js', __FILE__), array('jquery'), '1.0.0', true);307 wp_enqueue_script('bootstrap.bundle.min', plugins_url('/assets/js/bootstrap.bundle.min.js', __FILE__), array('jquery'), '5.1.1', false);308 wp_enqueue_script('mpd-main', plugins_url('/assets/js/main.js', __FILE__), array('jquery'), MAGICAL_POSTS_DISPLAY_VERSION, true);309 }310 311 /**312 * Add style and scripts for gutenburg editor313 *314 * Add the plugin style and scripts for gutenburg editor315 *316 * @since 1.0.4317 *318 * @access public319 */320 public function mgpblock_editor_scripts()321 {322 wp_enqueue_style('mp-admin-block', plugins_url('/assets/css/mgblock-admin.css', __FILE__), array(), '1.0.0', 'all');323 }324 325 326 /**327 * Add style and scripts for editor328 *329 * Add the plugin style and scripts for editor only330 *331 * @since 1.0.0332 *333 * @access public334 */335 public function mgpost_display_editor_scripts()336 {337 global $pagenow;338 339 340 wp_enqueue_style('mp-admin-style', plugins_url('/assets/css/admin-style.css', __FILE__), array(), MAGICAL_POSTS_DISPLAY_VERSION, 'all');341 if (in_array($pagenow, array('post-new.php', 'post.php'))) {342 wp_enqueue_script('cmb2-conditional-logic', plugins_url('/assets/js/cmb2-conditional-logic.js', __FILE__), array('jquery'), '2.5.1', true);343 }344 if (isset($_GET['page']) && $_GET['page'] == 'mgpd-page') {345 wp_enqueue_style('mp-admin-page', plugins_url('/assets/css/mgadmin-page.css', __FILE__), array(), MAGICAL_POSTS_DISPLAY_VERSION, 'all');346 wp_enqueue_style('venobox.min', plugins_url('/assets/css/venobox.min.css', __FILE__), array(), MAGICAL_POSTS_DISPLAY_VERSION, 'all');347 wp_enqueue_script('venobox-js', plugins_url('/assets/js/venobox.min.js', __FILE__), array('jquery'), MAGICAL_POSTS_DISPLAY_VERSION, true);348 }349 wp_enqueue_script('mgntc-js', plugins_url('/assets/js/mgntc.js', __FILE__), array('jquery'), '1.0.0', true);350 192 } 351 193 … … 363 205 364 206 365 366 367 /**368 * Admin notice369 *370 * Warning when the site doesn't have a minimum required PHP version.371 *372 * @since 1.0.0373 *374 * @access public375 */376 public function admin_notice_minimum_php_version()377 {378 379 if (isset($_GET['activate'])) unset($_GET['activate']);380 381 $message = sprintf(382 /* translators: 1: Plugin name 2: PHP 3: Required PHP version */383 esc_html__('"%1$s" requires "%2$s" version %3$s or greater.', 'magical-posts-display'),384 '<strong>' . esc_html__('Magical Posts Display', 'magical-posts-display') . '</strong>',385 '<strong>' . esc_html__('PHP', 'magical-posts-display') . '</strong>',386 self::MINIMUM_PHP_VERSION387 );388 389 printf(390 '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>',391 wp_kses_post($message)392 );393 }394 207 395 208
Note: See TracChangeset
for help on using the changeset viewer.