data
1 year ago
engines
10 months ago
exceptions
1 year ago
modules
10 months ago
query
10 months ago
rest
10 months ago
services
10 months ago
admin.php
10 months ago
api.php
10 months ago
core.php
10 months ago
discussion.php
1 year ago
event.php
1 year ago
init.php
11 months ago
logging.php
1 year ago
reply.php
10 months ago
rest.php
10 months ago
admin.php
379 lines
| 1 | <?php |
| 2 | |
| 3 | class Meow_MWAI_Admin extends MeowCommon_Admin { |
| 4 | public $core; |
| 5 | public $contentGeneratorEnabled; |
| 6 | public $imagesGeneratorEnabled; |
| 7 | public $playgroundEnabled; |
| 8 | public $suggestionsEnabled; |
| 9 | |
| 10 | public function __construct( $core ) { |
| 11 | $this->core = $core; |
| 12 | parent::__construct( MWAI_PREFIX, MWAI_ENTRY, MWAI_DOMAIN, class_exists( 'MeowPro_MWAI_Core' ) ); |
| 13 | if ( is_admin() ) { |
| 14 | $this->contentGeneratorEnabled = $this->core->get_option( 'module_generator_content' ); |
| 15 | $this->imagesGeneratorEnabled = $this->core->get_option( 'module_generator_images' ); |
| 16 | $this->playgroundEnabled = $this->core->get_option( 'module_playground' ); |
| 17 | $can_access_settings = $this->core->can_access_settings(); |
| 18 | $can_access_features = $this->core->can_access_features(); |
| 19 | |
| 20 | if ( $can_access_settings || $can_access_features ) { |
| 21 | add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] ); |
| 22 | } |
| 23 | |
| 24 | if ( $can_access_settings ) { |
| 25 | add_action( 'admin_menu', [ $this, 'app_menu' ] ); |
| 26 | } |
| 27 | |
| 28 | if ( $can_access_features ) { |
| 29 | add_action( 'admin_menu', [ $this, 'admin_menu' ] ); |
| 30 | |
| 31 | // Only if the Suggestions are enabled. |
| 32 | $this->suggestionsEnabled = $this->core->get_option( 'module_suggestions' ); |
| 33 | if ( $this->suggestionsEnabled ) { |
| 34 | add_filter( 'post_row_actions', [ $this, 'post_row_actions' ], 10, 2 ); |
| 35 | add_filter( 'page_row_actions', [ $this, 'post_row_actions' ], 10, 2 ); |
| 36 | } |
| 37 | |
| 38 | if ( $this->imagesGeneratorEnabled ) { |
| 39 | add_filter( 'media_row_actions', [ $this, 'media_row_actions' ], 10, 2 ); |
| 40 | } |
| 41 | |
| 42 | add_action( 'admin_footer', [ $this, 'admin_footer' ] ); |
| 43 | } |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | public function admin_menu() { |
| 48 | |
| 49 | // Generate New (under Posts) |
| 50 | if ( $this->contentGeneratorEnabled ) { |
| 51 | add_submenu_page( |
| 52 | 'edit.php', |
| 53 | 'Generate New', |
| 54 | 'Generate New', |
| 55 | 'read', |
| 56 | 'mwai_content_generator', |
| 57 | [ $this, 'ai_content_generator' ], |
| 58 | 2 |
| 59 | ); |
| 60 | } |
| 61 | |
| 62 | // In Tools |
| 63 | if ( $this->playgroundEnabled ) { |
| 64 | add_management_page( |
| 65 | 'Playground', |
| 66 | __( 'Playground', 'ai-engine' ), |
| 67 | 'read', |
| 68 | 'mwai_dashboard', |
| 69 | [ $this, 'ai_playground' ] |
| 70 | ); |
| 71 | } |
| 72 | if ( $this->contentGeneratorEnabled ) { |
| 73 | add_management_page( |
| 74 | 'Generate Content', |
| 75 | 'Generate Content', |
| 76 | 'read', |
| 77 | 'mwai_content_generator', |
| 78 | [ $this, 'ai_content_generator' ] |
| 79 | ); |
| 80 | } |
| 81 | if ( $this->imagesGeneratorEnabled ) { |
| 82 | add_management_page( |
| 83 | 'Generate Images', |
| 84 | 'Generate Images', |
| 85 | 'read', |
| 86 | 'mwai_images_generator', |
| 87 | [ $this, 'ai_image_generator' ] |
| 88 | ); |
| 89 | } |
| 90 | |
| 91 | // In the Admin Bar: |
| 92 | add_action( 'admin_bar_menu', [ $this, 'admin_bar_menu' ], 100 ); |
| 93 | } |
| 94 | |
| 95 | public function admin_bar_menu( $wp_admin_bar ) { |
| 96 | |
| 97 | $admin_bar = $this->core->get_option( 'admin_bar' ); |
| 98 | $settings = isset( $admin_bar['settings'] ) && $admin_bar['settings']; |
| 99 | $playground = isset( $admin_bar['playground'] ) && $admin_bar['playground']; |
| 100 | $content_generator = isset( $admin_bar['content_generator'] ) && $admin_bar['content_generator']; |
| 101 | $images_generator = isset( $admin_bar['images_generator'] ) && $admin_bar['images_generator']; |
| 102 | |
| 103 | if ( $settings ) { |
| 104 | $wp_admin_bar->add_node( [ |
| 105 | 'id' => 'mwai-settings', |
| 106 | 'title' => '<span class="ab-icon dashicons-before dashicons-admin-settings" style="top: 2px;"></span>' . __( 'AI Engine', 'ai-engine' ), |
| 107 | 'href' => admin_url( 'admin.php?page=mwai_settings' ), |
| 108 | 'meta' => [ 'class' => 'mwai-settings' ], |
| 109 | ] ); |
| 110 | } |
| 111 | |
| 112 | if ( $content_generator ) { |
| 113 | $wp_admin_bar->add_node( [ |
| 114 | 'id' => 'mwai-content-generator', |
| 115 | 'title' => MWAI_IMG_WAND_HTML . __( 'Content', 'ai-engine' ), |
| 116 | 'href' => admin_url( 'tools.php?page=mwai_content_generator' ), |
| 117 | 'meta' => [ 'class' => 'mwai-content-generator' ], |
| 118 | ] ); |
| 119 | } |
| 120 | if ( $images_generator ) { |
| 121 | $wp_admin_bar->add_node( [ |
| 122 | 'id' => 'mwai-image-generator', |
| 123 | 'title' => MWAI_IMG_WAND_HTML . __( 'Images', 'ai-engine' ), |
| 124 | 'href' => admin_url( 'tools.php?page=mwai_images_generator' ), |
| 125 | 'meta' => [ 'class' => 'mwai-images-generator' ], |
| 126 | ] ); |
| 127 | } |
| 128 | |
| 129 | // The Global Magic Wand |
| 130 | // if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { |
| 131 | // $wp_admin_bar->add_node( array( |
| 132 | // 'id' => 'mwai-debug', |
| 133 | // 'title' => MWAI_IMG_WAND_HTML . __( 'Magic Wand', 'ai-engine' ), |
| 134 | // //'href' => admin_url( 'tools.php?page=mwai_debug' ), |
| 135 | // 'meta' => array( 'class' => 'mwai-debug' ), |
| 136 | // ) ); |
| 137 | // } |
| 138 | |
| 139 | if ( $playground ) { |
| 140 | $wp_admin_bar->add_node( [ |
| 141 | 'id' => 'mwai-playground', |
| 142 | 'title' => MWAI_IMG_WAND_HTML . __( 'Playground', 'ai-engine' ), |
| 143 | 'href' => admin_url( 'tools.php?page=mwai_dashboard' ), |
| 144 | 'meta' => [ 'class' => 'mwai-playground' ], |
| 145 | ] ); |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | public function ai_playground() { |
| 150 | echo '<div id="mwai-playground"></div>'; |
| 151 | } |
| 152 | |
| 153 | public function ai_content_generator() { |
| 154 | echo '<div id="mwai-content-generator"></div>'; |
| 155 | } |
| 156 | |
| 157 | public function ai_image_generator() { |
| 158 | echo '<div id="mwai-image-generator"></div>'; |
| 159 | } |
| 160 | |
| 161 | public function post_row_actions( $actions, $post ) { |
| 162 | $actions['ai_magic_wand'] = '<span class="mwai-magic-wand-action" data-id="' . $post->ID . '" data-title="' . esc_attr( $post->post_title ) . '"> |
| 163 | <a href="#" class="mwai-magic-wand-trigger">' . MWAI_IMG_WAND_HTML_XS . ' ' . __( 'Magic Wand', 'ai-engine' ) . '</a> |
| 164 | <div class="mwai-magic-wand-dropdown" style="display: none;"> |
| 165 | <a class="mwai-link-title" href="#" data-id="' . $post->ID . '" data-title="' . esc_attr( $post->post_title ) . '"> |
| 166 | <span class="dashicons dashicons-edit" style="font-size: 14px; line-height: 1.4; margin-right: 4px; pointer-events: none;"></span>' . __( 'Generate Title', 'ai-engine' ) . ' |
| 167 | </a> |
| 168 | <a class="mwai-link-excerpt" href="#" data-id="' . $post->ID . '" data-title="' . esc_attr( $post->post_title ) . '"> |
| 169 | <span class="dashicons dashicons-text" style="font-size: 14px; line-height: 1.4; margin-right: 4px; pointer-events: none;"></span>' . __( 'Generate Excerpt', 'ai-engine' ) . ' |
| 170 | </a> |
| 171 | </div> |
| 172 | </span>'; |
| 173 | return $actions; |
| 174 | } |
| 175 | |
| 176 | public function media_row_actions( $actions, $post ) { |
| 177 | if ( strpos( $post->post_mime_type, 'image/' ) === 0 ) { |
| 178 | $url = admin_url( 'tools.php?page=mwai_images_generator&editId=' . $post->ID ); |
| 179 | $actions['mwai_remix'] = '<a href="' . $url . '">' . MWAI_IMG_WAND_HTML_XS . ' ' . __( 'Edit', 'ai-engine' ) . '</a>'; |
| 180 | } |
| 181 | return $actions; |
| 182 | } |
| 183 | |
| 184 | public function admin_footer() { |
| 185 | // Don't add our admin footer div on the Site Editor |
| 186 | $current_screen = get_current_screen(); |
| 187 | if ( $current_screen && $current_screen->base === 'site-editor' ) { |
| 188 | return; |
| 189 | } |
| 190 | echo '<div id="mwai-admin-postsList"></div>'; |
| 191 | |
| 192 | // Add CSS for Magic Wand dropdown |
| 193 | ?> |
| 194 | <style> |
| 195 | .mwai-magic-wand-action { |
| 196 | position: relative; |
| 197 | display: inline-block; |
| 198 | } |
| 199 | |
| 200 | .mwai-magic-wand-trigger { |
| 201 | text-decoration: none; |
| 202 | } |
| 203 | |
| 204 | .mwai-magic-wand-dropdown { |
| 205 | position: absolute; |
| 206 | top: 100%; |
| 207 | left: 0; |
| 208 | background: #fff; |
| 209 | border: 1px solid #c3c4c7; |
| 210 | border-radius: 4px; |
| 211 | box-shadow: 0 2px 5px rgba(0,0,0,0.15); |
| 212 | min-width: 150px; |
| 213 | z-index: 1000; |
| 214 | margin-top: 4px; |
| 215 | } |
| 216 | |
| 217 | .mwai-magic-wand-dropdown a { |
| 218 | display: flex; |
| 219 | align-items: center; |
| 220 | padding: 8px 12px; |
| 221 | text-decoration: none; |
| 222 | color: #2271b1; |
| 223 | border-bottom: 1px solid #f0f0f1; |
| 224 | white-space: nowrap; |
| 225 | } |
| 226 | |
| 227 | .mwai-magic-wand-dropdown a .dashicons { |
| 228 | width: 16px; |
| 229 | height: 16px; |
| 230 | font-size: 14px; |
| 231 | } |
| 232 | |
| 233 | .mwai-magic-wand-dropdown a:last-child { |
| 234 | border-bottom: none; |
| 235 | } |
| 236 | |
| 237 | .mwai-magic-wand-dropdown a:hover { |
| 238 | background: #f0f6fc; |
| 239 | color: #135e96; |
| 240 | } |
| 241 | |
| 242 | /* Ensure dropdown stays visible when hovering over it */ |
| 243 | .mwai-magic-wand-action:hover .mwai-magic-wand-dropdown { |
| 244 | display: block !important; |
| 245 | } |
| 246 | </style> |
| 247 | <?php |
| 248 | } |
| 249 | |
| 250 | public function admin_enqueue_scripts() { |
| 251 | // Don't load our scripts on the Site Editor to avoid conflicts |
| 252 | $current_screen = get_current_screen(); |
| 253 | if ( $current_screen && $current_screen->base === 'site-editor' ) { |
| 254 | return; |
| 255 | } |
| 256 | |
| 257 | $physical_file = MWAI_PATH . '/app/index.js'; |
| 258 | $cache_buster = file_exists( $physical_file ) ? filemtime( $physical_file ) : MWAI_VERSION; |
| 259 | wp_register_script( 'mwai-vendor', MWAI_URL . 'app/vendor.js', null, $cache_buster ); |
| 260 | |
| 261 | // Base dependencies |
| 262 | $deps = [ 'mwai-vendor', 'wp-element', 'wp-components', 'wp-plugins', 'wp-i18n' ]; |
| 263 | |
| 264 | // Check if we're on AI Engine admin pages |
| 265 | // Debug: Log the current screen ID to help identify the correct page |
| 266 | if ( $current_screen && $this->core->get_option( 'server_debug_mode' ) ) { |
| 267 | error_log( '[AI Engine] Current screen ID: ' . $current_screen->id . ', Base: ' . $current_screen->base ); |
| 268 | } |
| 269 | |
| 270 | $is_ai_engine_page = $current_screen && ( |
| 271 | strpos( $current_screen->id, 'mwai_settings' ) !== false || |
| 272 | strpos( $current_screen->id, 'meowapps_page_mwai' ) !== false || |
| 273 | $current_screen->id === 'meowapps_page_mwai_settings' || |
| 274 | $current_screen->id === 'meowapps_page_mwai-ui' || |
| 275 | strpos( $current_screen->id, 'meowapps' ) !== false && strpos( $_GET['page'] ?? '', 'mwai' ) !== false |
| 276 | ); |
| 277 | |
| 278 | // Only add wp-edit-post on actual post/page editor screens, not on AI Engine admin pages |
| 279 | $is_post_editor = $current_screen && in_array( $current_screen->base, [ 'post', 'page' ] ); |
| 280 | if ( $is_post_editor ) { |
| 281 | $deps[] = 'wp-edit-post'; |
| 282 | } |
| 283 | |
| 284 | // Load block editor deps if: |
| 285 | // 1. We're on AI Engine admin pages (Forms.js component is always imported by Settings.js) OR |
| 286 | // 2. We are on a block editor screen (Edit Post) |
| 287 | $forms_module_enabled = $this->core->get_option( 'module_forms' ); |
| 288 | $load_forms_editor = $forms_module_enabled && $this->core->get_option( 'forms_editor' ); |
| 289 | $on_block_editor = function_exists( 'wp_should_load_block_editor_scripts_and_styles' ) && wp_should_load_block_editor_scripts_and_styles(); |
| 290 | |
| 291 | // Always load block editor deps on AI Engine admin pages because Forms.js is always imported |
| 292 | if ( $is_ai_engine_page || $on_block_editor ) { |
| 293 | $deps = array_merge( $deps, [ 'wp-blocks', 'wp-block-editor', 'wp-format-library', 'wp-block-library', 'wp-editor' ] ); |
| 294 | } |
| 295 | |
| 296 | wp_register_script( 'mwai', MWAI_URL . 'app/index.js', $deps, $cache_buster ); |
| 297 | wp_enqueue_script( 'mwai' ); |
| 298 | |
| 299 | // Ensure core editor styles are available for embedded block editor UIs |
| 300 | // This helps Popovers, Inspector, and toolbars match Gutenberg styling |
| 301 | if ( function_exists( 'wp_enqueue_style' ) ) { |
| 302 | // Only load wp-edit-post styles on actual post/page editor screens |
| 303 | if ( $is_post_editor ) { |
| 304 | @wp_enqueue_style( 'wp-edit-post' ); |
| 305 | } |
| 306 | @wp_enqueue_style( 'wp-components' ); |
| 307 | |
| 308 | // Load block editor styles if we're on AI Engine pages or on block editor |
| 309 | if ( $is_ai_engine_page || $on_block_editor ) { |
| 310 | @wp_enqueue_style( 'wp-block-editor' ); |
| 311 | @wp_enqueue_style( 'wp-block-library' ); |
| 312 | } |
| 313 | } |
| 314 | // Make sure core blocks and format tools are registered/available |
| 315 | if ( function_exists( 'wp_enqueue_script' ) ) { |
| 316 | if ( $is_ai_engine_page || $on_block_editor ) { |
| 317 | @wp_enqueue_script( 'wp-format-library' ); |
| 318 | @wp_enqueue_script( 'wp-block-library' ); |
| 319 | @wp_enqueue_script( 'wp-editor' ); |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | // The MD5 of the translation file built by WP uses app/i18n.js instead of app/index.js |
| 324 | add_filter( 'load_script_translation_file', function ( $file, $handle, $domain ) { |
| 325 | if ( $domain !== 'ai-engine' ) { |
| 326 | return $file; |
| 327 | } |
| 328 | $file = str_replace( md5( 'app/index.js' ), md5( 'app/i18n.js' ), $file ); |
| 329 | return $file; |
| 330 | }, 10, 3 ); |
| 331 | |
| 332 | // This is useless for AI Engine, but it avoids issues when themes and plugin calls |
| 333 | // wp_enqueue_media too late (usually, they call it in the footer). Until someone |
| 334 | // figures out what the issue is, let's load it here. |
| 335 | wp_enqueue_media(); |
| 336 | |
| 337 | wp_set_script_translations( 'mwai', 'ai-engine' ); |
| 338 | |
| 339 | // Prepare localization data |
| 340 | $localize_data = [ |
| 341 | 'api_url' => get_rest_url( null, 'mwai/v1' ), |
| 342 | 'rest_url' => get_rest_url(), |
| 343 | 'plugin_url' => MWAI_URL, |
| 344 | 'user_data' => $this->core->get_user_data(), |
| 345 | 'prefix' => MWAI_PREFIX, |
| 346 | 'domain' => MWAI_DOMAIN, |
| 347 | 'is_pro' => class_exists( 'MeowPro_MWAI_Core' ), |
| 348 | 'is_registered' => !!$this->is_registered(), |
| 349 | 'rest_nonce' => wp_create_nonce( 'wp_rest' ), |
| 350 | 'session' => $this->core->get_session_id(), |
| 351 | 'options' => $this->core->get_all_options(), |
| 352 | 'chatbots' => $this->core->get_chatbots(), |
| 353 | 'themes' => $this->core->get_themes(), |
| 354 | 'stream' => $this->core->get_option( 'ai_streaming' ), |
| 355 | ]; |
| 356 | |
| 357 | wp_localize_script( 'mwai', 'mwai', $localize_data ); |
| 358 | } |
| 359 | |
| 360 | public function is_registered() { |
| 361 | return apply_filters( MWAI_PREFIX . '_meowapps_is_registered', false, MWAI_PREFIX ); |
| 362 | } |
| 363 | |
| 364 | public function app_menu() { |
| 365 | add_submenu_page( |
| 366 | 'meowapps-main-menu', |
| 367 | 'AI Engine', |
| 368 | 'AI Engine', |
| 369 | 'manage_options', |
| 370 | 'mwai_settings', |
| 371 | [ $this, 'admin_settings' ] |
| 372 | ); |
| 373 | } |
| 374 | |
| 375 | public function admin_settings() { |
| 376 | echo '<div id="mwai-admin-settings"></div>'; |
| 377 | } |
| 378 | } |
| 379 |