| @@ -1,0 +1,142 @@ | ||
| 1 | +<?php | |
| 2 | +namespace ABlocks; | |
| 3 | + | |
| 4 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 5 | + exit; // Exit if accessed directly. | |
| 6 | +} | |
| 7 | + | |
| 8 | +class Admin { | |
| 9 | + public static function init() { | |
| 10 | + $self = new self(); | |
| 11 | + $self->dispatch_hooks(); | |
| 12 | + | |
| 13 | + add_filter( 'upload_mimes', [ $self, 'allow_lottie_json_uploads' ] ); | |
| 14 | + add_filter( 'upload_mimes', [ $self, 'allow_svg_uploads' ] ); | |
| 15 | + add_filter( 'wp_check_filetype_and_ext', function ( $data, $file, $filename ) { | |
| 16 | + $ext = pathinfo( $filename, PATHINFO_EXTENSION ); | |
| 17 | + | |
| 18 | + if ( 'json' === $ext ) { | |
| 19 | + $data['ext'] = 'json'; | |
| 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'; | |
| 24 | + } | |
| 25 | + | |
| 26 | + return $data; | |
| 27 | + }, 10, 3 ); | |
| 28 | + } | |
| 29 | + | |
| 30 | + function allow_lottie_json_uploads( $mimes ) { | |
| 31 | + $mimes['json'] = 'application/json'; | |
| 32 | + $mimes['lottie'] = 'application/json'; | |
| 33 | + return $mimes; | |
| 34 | + } | |
| 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 | + | |
| 49 | + public function dispatch_hooks() { | |
| 50 | + Admin\Menu::init(); | |
| 51 | + \ABlocks\CreatePage\page\ShowPageState::init(); | |
| 52 | + Admin\Export::init(); | |
| 53 | + Admin\Notice::init(); | |
| 54 | + add_filter( 'allowed_redirect_hosts', array( $this, 'add_white_listed_redirect_hosts' ) ); | |
| 55 | + add_action( 'current_screen', array( $this, 'conditional_loaded' ) ); | |
| 56 | + add_filter( 'plugin_action_links_' . ABLOCKS_PLUGIN_BASENAME, array( $this, 'plugin_action_links' ) ); | |
| 57 | + add_filter( 'plugin_row_meta', array( $this, 'add_plugin_links' ), 10, 2 ); | |
| 58 | + add_action( 'admin_init', array( $this, 'dispatch_activation_redirect' ), 99 ); | |
| 59 | + } | |
| 60 | + public function add_white_listed_redirect_hosts( $hosts ) { | |
| 61 | + $hosts[] = 'ablocks.pro'; | |
| 62 | + return $hosts; | |
| 63 | + } | |
| 64 | + | |
| 65 | + public function conditional_loaded() { | |
| 66 | + $screen = get_current_screen(); | |
| 67 | + | |
| 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 | + ); | |
| 80 | + | |
| 81 | + wp_safe_redirect( $link ); | |
| 82 | + exit; | |
| 83 | + } | |
| 84 | + } | |
| 85 | + | |
| 86 | + public function add_plugin_links( $links, $file ) { | |
| 87 | + if ( ABLOCKS_PLUGIN_BASENAME !== $file ) { | |
| 88 | + return $links; | |
| 89 | + } | |
| 90 | + | |
| 91 | + $map_block_links = array( | |
| 92 | + 'docs' => array( | |
| 93 | + 'url' => 'https://ablocks.pro/docs/', | |
| 94 | + 'label' => __( 'Docs', 'ablocks' ), | |
| 95 | + 'aria-label' => __( 'View aBlocks documentation', 'ablocks' ), | |
| 96 | + ), | |
| 97 | + 'video' => array( | |
| 98 | + 'url' => 'https://www.youtube.com/@ablocksteam', | |
| 99 | + 'label' => __( 'Video Tutorials', 'ablocks' ), | |
| 100 | + 'aria-label' => __( 'See Video Tutorials', 'ablocks' ), | |
| 101 | + ), | |
| 102 | + 'support' => array( | |
| 103 | + 'url' => 'https://wordpress.org/support/plugin/ablocks/', | |
| 104 | + 'label' => __( 'Community Support', 'ablocks' ), | |
| 105 | + 'aria-label' => __( 'Visit community forums', 'ablocks' ), | |
| 106 | + ), | |
| 107 | + 'review' => array( | |
| 108 | + 'url' => 'https://wordpress.org/support/plugin/ablocks/reviews/#new-post', | |
| 109 | + 'label' => __( 'Rate the plugin ★★★★★', 'ablocks' ), | |
| 110 | + 'aria-label' => __( 'Rate the plugin.', 'ablocks' ), | |
| 111 | + ), | |
| 112 | + ); | |
| 113 | + | |
| 114 | + foreach ( $map_block_links as $key => $link ) { | |
| 115 | + $links[ $key ] = sprintf( | |
| 116 | + '<a target="_blank" href="%s" aria-label="%s">%s</a>', | |
| 117 | + esc_url( $link['url'] ), | |
| 118 | + esc_attr( $link['aria-label'] ), | |
| 119 | + esc_html( $link['label'] ) | |
| 120 | + ); | |
| 121 | + } | |
| 122 | + | |
| 123 | + return $links; | |
| 124 | + } | |
| 125 | + public function plugin_action_links( $links ) { | |
| 126 | + $settings_link = sprintf( '<a href="%1$s">%2$s</a>', admin_url( 'admin.php?page=ablocks' ), esc_html__( 'Settings', 'ablocks' ) ); | |
| 127 | + | |
| 128 | + array_unshift( $links, $settings_link ); | |
| 129 | + | |
| 130 | + if ( ! defined( 'ABLOCKS_PRO_VERSION' ) ) { | |
| 131 | + $links['go_pro'] = sprintf( '<a href="%1$s" target="_blank" class="academy-plugins-gopro" style="color: #7b68ee; font-weight: bold;">%2$s</a>', 'https://ablocks.pro/pricing/', esc_html__( 'Get aBlocks Pro', 'ablocks' ) ); | |
| 132 | + } | |
| 133 | + return $links; | |
| 134 | + } | |
| 135 | + public function dispatch_activation_redirect() { | |
| 136 | + if ( get_option( 'ablocks_need_activation_redirect', false ) ) { | |
| 137 | + delete_option( 'ablocks_need_activation_redirect' ); | |
| 138 | + wp_safe_redirect( admin_url( 'admin.php?page=ablocks' ) ); | |
| 139 | + exit; | |
| 140 | + } | |
| 141 | + } | |
| 142 | +} | |