Changeset 3395798
- Timestamp:
- 11/14/2025 02:29:00 PM (3 months ago)
- Location:
- abtestkit/trunk
- Files:
-
- 2 edited
-
abtestkit.php (modified) (6 diffs)
-
readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
abtestkit/trunk/abtestkit.php
r3394584 r3395798 4 4 * Plugin URI: https://wordpress.org/plugins/abtestkit 5 5 * Description: Simple, user friendly A/B testing. 6 * Version: 1.0. 26 * Version: 1.0.3 7 7 * Author: abtestkit 8 8 * License: GPL-2.0-or-later … … 1841 1841 } 1842 1842 1843 /** 1844 * Integration layer: regenerate CSS/assets for common page builders 1845 * when we duplicate a page (Version B). 1846 * 1847 * @param int $new_id The ID of the duplicated page. 1848 * @param int $source_id The original/control page ID. 1849 */ 1850 function abtestkit_regenerate_builder_assets( int $new_id, int $source_id = 0 ) : void { 1851 $new_id = (int) $new_id; 1852 $source_id = (int) $source_id; 1853 1854 if ( $new_id <= 0 ) { 1855 return; 1856 } 1857 1858 // ───────────────────────────────────────────────────── 1859 // Elementor 1860 // ───────────────────────────────────────────────────── 1861 if ( defined( 'ELEMENTOR_VERSION' ) && class_exists( '\Elementor\Plugin' ) ) { 1862 try { 1863 // Clear any old CSS and build fresh CSS for this post 1864 if ( isset( \Elementor\Plugin::$instance->files_manager ) 1865 && method_exists( \Elementor\Plugin::$instance->files_manager, 'clear_cache' ) 1866 ) { 1867 \Elementor\Plugin::$instance->files_manager->clear_cache(); 1868 } 1869 1870 // Ask Elementor to clear generated CSS for the post (external hook). 1871 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 1872 do_action( 'elementor/css-file/post/clear', $new_id ); 1873 1874 // Newer Elementor has a per-post CSS object. 1875 if ( class_exists( '\Elementor\Core\Files\CSS\Post' ) ) { 1876 $css = new \Elementor\Core\Files\CSS\Post( $new_id ); 1877 if ( method_exists( $css, 'update' ) ) { 1878 $css->update(); 1879 } 1880 } 1881 } catch ( \Throwable $e ) { 1882 // Fail silently – never break the site if Elementor changes APIs. 1883 } 1884 } 1885 1886 // ───────────────────────────────────────────────────── 1887 // Breakdance 1888 // ───────────────────────────────────────────────────── 1889 if ( function_exists( 'breakdance' ) ) { 1890 try { 1891 // Official per-post CSS regeneration. 1892 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 1893 do_action( 'breakdance_generate_css_for_post', $new_id ); 1894 1895 // Optional: full CSS cache clear (heavier; keep only if needed). 1896 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 1897 // do_action( 'breakdance_clear_css_cache' ); 1898 } catch ( \Throwable $e ) { 1899 } 1900 } 1901 1902 // ───────────────────────────────────────────────────── 1903 // Beaver Builder 1904 // ───────────────────────────────────────────────────── 1905 if ( class_exists( 'FLBuilderModel' ) ) { 1906 try { 1907 if ( method_exists( 'FLBuilderModel', 'delete_asset_cache_for_post' ) ) { 1908 \FLBuilderModel::delete_asset_cache_for_post( $new_id ); 1909 } 1910 if ( function_exists( 'fl_builder_flush_caches' ) ) { 1911 fl_builder_flush_caches(); 1912 } 1913 } catch ( \Throwable $e ) { 1914 } 1915 } 1916 1917 // ───────────────────────────────────────────────────── 1918 // Divi 1919 // ───────────────────────────────────────────────────── 1920 if ( function_exists( 'et_core_cache_flush' ) ) { 1921 try { 1922 et_core_cache_flush(); 1923 } catch ( \Throwable $e ) { 1924 } 1925 } 1926 1927 // ───────────────────────────────────────────────────── 1928 // Bricks 1929 // ───────────────────────────────────────────────────── 1930 if ( defined( 'BRICKS_VERSION' ) ) { 1931 try { 1932 // External hook – you or Bricks can hook into this. 1933 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 1934 do_action( 'bricks/abtestkit/regenerate_css', $new_id, $source_id ); 1935 } catch ( \Throwable $e ) { 1936 } 1937 } 1938 1939 // ───────────────────────────────────────────────────── 1940 // Oxygen 1941 // ───────────────────────────────────────────────────── 1942 if ( function_exists( 'ct_cssbuffer_update' ) ) { 1943 try { 1944 ct_cssbuffer_update(); 1945 } catch ( \Throwable $e ) { 1946 } 1947 } 1948 1949 // ───────────────────────────────────────────────────── 1950 // WPBakery / Visual Composer: shortcode-based 1951 // ───────────────────────────────────────────────────── 1952 // No direct API needed, but expose a hook for add-ons. 1953 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 1954 do_action( 'abtestkit/after_duplicate/wpbakery', $new_id, $source_id ); 1955 1956 // ───────────────────────────────────────────────────── 1957 // Generic caches (object cache / page caches) 1958 // ───────────────────────────────────────────────────── 1959 if ( function_exists( 'wp_cache_flush' ) ) { 1960 wp_cache_flush(); 1961 } 1962 } 1843 1963 1844 1964 /** Duplicate a page (content + meta + taxonomies). */ … … 1877 1997 } 1878 1998 1879 // ───────────────────────────────────────────────────────────1999 // ─────────────────────────────────────────────────────────── 1880 2000 // Builder compatibility: regenerate CSS/assets on the clone 1881 2001 // ─────────────────────────────────────────────────────────── 1882 1883 // Elementor 1884 if ( defined('ELEMENTOR_VERSION') && class_exists('\Elementor\Plugin') ) { 1885 try { 1886 // Clear any old CSS and build fresh CSS for this post 1887 if ( method_exists(\Elementor\Plugin::$instance->files_manager, 'clear_cache') ) { 1888 \Elementor\Plugin::$instance->files_manager->clear_cache(); 1889 } 1890 // Ask Elementor to clear generated CSS for the post (external hook). 1891 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 1892 do_action( 'elementor/css-file/post/clear', $new_id ); // safe even if no listeners 1893 1894 // Newer Elementor has a per-post CSS object 1895 if ( class_exists('\Elementor\Core\Files\CSS\Post') ) { 1896 $css = new \Elementor\Core\Files\CSS\Post( $new_id ); 1897 if ( method_exists( $css, 'update' ) ) { $css->update(); } 1898 } 1899 } catch ( \Throwable $e ) {} 1900 } 1901 1902 // Beaver Builder 1903 if ( class_exists('FLBuilderModel') ) { 1904 try { 1905 if ( method_exists('FLBuilderModel', 'delete_asset_cache_for_post') ) { 1906 \FLBuilderModel::delete_asset_cache_for_post( $new_id ); 1907 } 1908 // Broad cache flush fallback 1909 if ( function_exists('fl_builder_flush_caches') ) { fl_builder_flush_caches(); } 1910 } catch ( \Throwable $e ) {} 1911 } 1912 1913 // Divi (et-*) 1914 if ( function_exists('et_core_cache_flush') ) { 1915 try { et_core_cache_flush(); } catch ( \Throwable $e ) {} 1916 } 1917 1918 // WPBakery / Visual Composer mostly stores shortcodes in post_content. 1919 // No special call needed, but this hook lets add-ons listen: 1920 do_action( 'abtestkit/after_duplicate/wpbakery', $new_id, $post_id ); 1921 1922 // Bricks 1923 if ( defined('BRICKS_VERSION') ) { 1924 // Request Bricks to regenerate CSS (external integration hook). 1925 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 1926 do_action( 'bricks/abtestkit/regenerate_css', $new_id ); 1927 } 1928 1929 // Oxygen 1930 if ( function_exists('ct_cssbuffer_update') ) { 1931 // Best-effort: ask Oxygen to rebuild CSS buffers 1932 try { ct_cssbuffer_update(); } catch ( \Throwable $e ) {} 1933 } 1934 1935 // Generic theme/plugin caches (best-effort, all guarded elsewhere too) 1936 if ( function_exists('wp_cache_flush') ) { wp_cache_flush(); } 2002 abtestkit_regenerate_builder_assets( $new_id, $post_id ); 1937 2003 1938 2004 return $new_id; 1939 2005 } 2006 1940 2007 1941 2008 // ── Admin Dashboard UI ─────────────────────────────────────────────────────── … … 1947 2014 'abtestkit-dashboard', 1948 2015 'abtestkit_render_page_tests_dashboard', 1949 'dashicons-randomize',2016 plugins_url( 'assets/img/menu-icon.png', __FILE__ ), 1950 2017 59 1951 2018 ); 2019 1952 2020 add_submenu_page( 1953 2021 'abtestkit-dashboard', … … 1959 2027 ); 1960 2028 }, 9 ); 2029 1961 2030 1962 2031 /** Handle create/start/pause/reset/apply/delete */ … … 3051 3120 dbDelta($sql); 3052 3121 } 3122 3123 // Align abtestkit admin menu icon 3124 add_action( 'admin_head', function () { 3125 ?> 3126 <style> 3127 #adminmenu #toplevel_page_abtestkit-dashboard .wp-menu-image img { 3128 width: 20px !important; 3129 height: 20px !important; 3130 padding-top: 5px; /* tweak 2–4px if you want it a touch higher/lower */ 3131 } 3132 </style> 3133 <?php 3134 }); -
abtestkit/trunk/readme.txt
r3394591 r3395798 1 === abtestkit ===1 === abtestkit - universal AB testing for Wordpress === 2 2 Contributors: abtestkit 3 3 Tags: ab testing, split testing, ab test, a b testing, a/b testing, testing, gutenberg, wordpress editor, core editor, conversion, optimization, experiment … … 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.4 7 Stable tag: 1.0. 27 Stable tag: 1.0.3 8 8 License: GPL-2.0-or-later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 15 15 = The simplest way to A/B test in WordPress = 16 16 17 **abtestkit** lets you run clean, fast, privacy-friendly A /B tests without code or complicated interfaces.17 **abtestkit** lets you run clean, fast, privacy-friendly AB tests without code or complicated interfaces. 18 18 Create full-page split tests in seconds, track performance automatically, and apply the winner with one click. 19 19 20 21 20 22 21 ### Why abtestkit? … … 25 24 * **Stay in flow** - test variants directly in the Gutenberg editor. 26 25 * **Keep control** - your data stays in your WordPress database. (GDPR friendly) 27 * **Works with any builder** — Gutenberg, Elementor, Beaver Builder, Bricks, Oxygen, Brizy, and more.26 * **Works with any builder** — Gutenberg, Elementor, Beaver Builder, Bricks, Oxygen, Brizy, Breakdance, and more. 28 27 * **Caching compatible** — built for modern caching and performance plugins. 29 28 * **No analysis needed** - abtestkit tracks impressions & clicks, then automatically declares the winning variant with 95% confidence.
Note: See TracChangeset
for help on using the changeset viewer.