| @@ -10,8 +10,9 @@ | ||
| 10 | 10 | $self = new self(); |
| 11 | 11 | $self->dispatch_hooks(); |
| 12 | 12 | |
| 13 | 13 | add_filter( 'upload_mimes', [ $self, 'allow_lottie_json_uploads' ] ); |
| 14 | + add_filter( 'upload_mimes', [ $self, 'allow_svg_uploads' ] ); | |
| 14 | 15 | add_filter( 'wp_check_filetype_and_ext', function ( $data, $file, $filename ) { |
| 15 | 16 | $ext = pathinfo( $filename, PATHINFO_EXTENSION ); |
| 16 | 17 | |
| 17 | 18 | if ( 'json' === $ext ) { |
| @@ -16,8 +17,11 @@ | ||
| 16 | 17 | |
| 17 | 18 | if ( 'json' === $ext ) { |
| 18 | 19 | $data['ext'] = 'json'; |
| 19 | 20 | $data['type'] = 'application/json'; |
| 21 | + } elseif ( 'svg' === strtolower( $ext ) && current_user_can( 'unfiltered_html' ) ) { | |
| 22 | + $data['ext'] = 'svg'; | |
| 23 | + $data['type'] = 'image/svg+xml'; | |
| 20 | 24 | } |
| 21 | 25 | |
| 22 | 26 | return $data; |
| 23 | 27 | }, 10, 3 ); |
| @@ -28,8 +32,21 @@ | ||
| 28 | 32 | $mimes['lottie'] = 'application/json'; |
| 29 | 33 | return $mimes; |
| 30 | 34 | } |
| 31 | 35 | |
| 36 | + // Gated to unfiltered_html (administrators, by default) rather than opened | |
| 37 | + // for every role: an SVG file can carry a <script>, and unlike the Atomic | |
| 38 | + // SVG block's own read path (which strips scripts/handlers before inlining | |
| 39 | + // markup — see atomic-svg/edit.js `cleanSvg`), the raw file the media | |
| 40 | + // library stores is unsanitised and can execute if it is ever opened | |
| 41 | + // directly as a top-level document. | |
| 42 | + function allow_svg_uploads( $mimes ) { | |
| 43 | + if ( current_user_can( 'unfiltered_html' ) ) { | |
| 44 | + $mimes['svg'] = 'image/svg+xml'; | |
| 45 | + } | |
| 46 | + return $mimes; | |
| 47 | + } | |
| 48 | + | |
| 32 | 49 | public function dispatch_hooks() { |
| 33 | 50 | Admin\Menu::init(); |
| 34 | 51 | \ABlocks\CreatePage\page\ShowPageState::init(); |
| 35 | 52 | Admin\Export::init(); |
| @@ -38,27 +55,35 @@ | ||
| 38 | 55 | add_action( 'current_screen', array( $this, 'conditional_loaded' ) ); |
| 39 | 56 | add_filter( 'plugin_action_links_' . ABLOCKS_PLUGIN_BASENAME, array( $this, 'plugin_action_links' ) ); |
| 40 | 57 | add_filter( 'plugin_row_meta', array( $this, 'add_plugin_links' ), 10, 2 ); |
| 41 | 58 | add_action( 'admin_init', array( $this, 'dispatch_activation_redirect' ), 99 ); |
| 42 | - $this->dispatch_insights(); | |
| 43 | 59 | } |
| 44 | 60 | public function add_white_listed_redirect_hosts( $hosts ) { |
| 45 | 61 | $hosts[] = 'ablocks.pro'; |
| 46 | 62 | return $hosts; |
| 47 | 63 | } |
| 64 | + | |
| 48 | 65 | public function conditional_loaded() { |
| 49 | 66 | $screen = get_current_screen(); |
| 50 | 67 | |
| 51 | - if ( ! $screen ) { | |
| 52 | - return; | |
| 53 | - } | |
| 68 | + if ( $screen && $screen->id == 'ablocks_page_ablocks-get-pro' ) { | |
| 69 | + $link = add_query_arg( | |
| 70 | + [ | |
| 71 | + 'utm_source' => 'ablocks-plugin', | |
| 72 | + 'utm_medium' => 'admin-dashboard', | |
| 73 | + 'utm_campaign' => 'upgrade-to-pro', | |
| 74 | + 'utm_content' => 'get-pro-button', | |
| 75 | + 'utm_term' => 'free-user', | |
| 76 | + 'locale' => get_locale(), | |
| 77 | + ], | |
| 78 | + 'https://ablocks.pro/pricing/' | |
| 79 | + ); | |
| 54 | 80 | |
| 55 | - switch ( $screen->id ) { | |
| 56 | - case 'ablocks_page_ablocks-get-pro': | |
| 57 | - wp_safe_redirect( 'https://ablocks.pro/pricing/' ); | |
| 58 | - exit; | |
| 81 | + wp_safe_redirect( $link ); | |
| 82 | + exit; | |
| 59 | 83 | } |
| 60 | 84 | } |
| 85 | + | |
| 61 | 86 | public function add_plugin_links( $links, $file ) { |
| 62 | 87 | if ( ABLOCKS_PLUGIN_BASENAME !== $file ) { |
| 63 | 88 | return $links; |
| 64 | 89 | } |
| @@ -112,44 +137,6 @@ | ||
| 112 | 137 | delete_option( 'ablocks_need_activation_redirect' ); |
| 113 | 138 | wp_safe_redirect( admin_url( 'admin.php?page=ablocks' ) ); |
| 114 | 139 | exit; |
| 115 | 140 | } |
| 116 | - } | |
| 117 | - public function dispatch_insights() { | |
| 118 | - Admin\Insights::init( | |
| 119 | - 'https://kodezen.com', | |
| 120 | - ABLOCKS_PLUGIN_SLUG, | |
| 121 | - 'plugin', | |
| 122 | - ABLOCKS_VERSION, | |
| 123 | - [ | |
| 124 | - 'logo' => ABLOCKS_ASSETS_URL . 'images/logo-shape.svg', // default logo URL | |
| 125 | - 'optin_message' => 'Help improve aBlocks LMS! Allow anonymous usage tracking?', | |
| 126 | - 'deactivation_message' => 'If you have a moment, please share why you are deactivating aBlocks:', | |
| 127 | - 'deactivation_reasons' => [ | |
| 128 | - 'no_longer_needed' => [ | |
| 129 | - 'label' => 'I no longer need the plugin', | |
| 130 | - ], | |
| 131 | - 'found_a_better_plugin' => [ | |
| 132 | - 'label' => 'I found a better plugin', | |
| 133 | - 'has_custom_reason' => true, | |
| 134 | - 'custom_reason_placeholder' => 'Please share which plugin', | |
| 135 | - ], | |
| 136 | - 'couldnt_get_the_plugin_to_work' => [ | |
| 137 | - 'label' => 'I couldn\'t get the plugin to work', | |
| 138 | - ], | |
| 139 | - 'temporary_deactivation' => [ | |
| 140 | - 'label' => 'It\'s a temporary deactivation', | |
| 141 | - ], | |
| 142 | - 'have_academy_pro' => [ | |
| 143 | - 'label' => 'I have aBlocks Pro', | |
| 144 | - 'toggle_text' => 'Wait! Don\'t deactivate aBlocks. You have to activate both aBlocks and aBlocks Pro in order for the plugin to work.', | |
| 145 | - ], | |
| 146 | - 'other' => [ | |
| 147 | - 'label' => 'Other', | |
| 148 | - 'has_custom_reason' => true, | |
| 149 | - 'custom_reason_placeholder' => 'Please share the reason', | |
| 150 | - ], | |
| 151 | - ], | |
| 152 | - ] | |
| 153 | - ); | |
| 154 | 141 | } |
| 155 | 142 | } |