PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.6.24
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.6.24
2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 2.6.4 2.6.3 2.5.23 All 138 releases
metasync / admin / class-metasync-html-visual-editor.php

class-metasync-html-visual-editor.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.6.24, at admin/class-metasync-html-visual-editor.php

316 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MetaSync HTML Visual Editor
4 *
5 * Provides a visual editing interface for raw HTML pages with:
6 * - Click to edit text
7 * - Color picker for backgrounds/colors
8 * - Image uploader
9 * - Drag and drop reordering
10 * - Live preview
11 *
12 * @package Metasync
13 * @subpackage Metasync/admin
14 * @since 2.0.0
15 */
16
17 if (!defined('ABSPATH')) {
18 exit;
19 }
20
21 class Metasync_HTML_Visual_Editor
22 {
23 /**
24 * Plugin name
25 *
26 * @var string
27 */
28 private $plugin_name;
29
30 /**
31 * Plugin version
32 *
33 * @var string
34 */
35 private $version;
36
37 /**
38 * Initialize the class
39 *
40 * @param string $plugin_name Plugin name
41 * @param string $version Plugin version
42 */
43 public function __construct($plugin_name, $version)
44 {
45 $this->plugin_name = $plugin_name;
46 $this->version = $version;
47 }
48
49 /**
50 * Register hooks
51 */
52 public function init()
53 {
54 // Add "Edit HTML" button to post row actions
55 add_filter('post_row_actions', array($this, 'add_edit_html_button'), 10, 2);
56 add_filter('page_row_actions', array($this, 'add_edit_html_button'), 10, 2);
57
58 // Add admin menu page for the editor
59 add_action('admin_menu', array($this, 'add_editor_page'));
60
61 // Register AJAX handlers
62 add_action('wp_ajax_metasync_save_html', array($this, 'ajax_save_html'));
63 add_action('wp_ajax_metasync_upload_image', array($this, 'ajax_upload_image'));
64 }
65
66 /**
67 * Add "Edit HTML" button to row actions
68 *
69 * @param array $actions Row actions
70 * @param WP_Post $post Post object
71 * @return array Modified actions
72 */
73 public function add_edit_html_button($actions, $post)
74 {
75 // Check if this is a raw HTML page
76 $has_raw_html = get_post_meta($post->ID, '_metasync_raw_html_enabled', true);
77
78 if ($has_raw_html) {
79 $edit_url = admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-html-editor&post_id=' . $post->ID);
80 $label = Metasync::get_whitelabel_company_name() ?: 'SearchAtlas';
81
82 $actions['edit_html'] = sprintf(
83 '<a href="%s" title="%s">%s</a>',
84 esc_url($edit_url),
85 esc_attr(sprintf(__('Edit with %s Visual Editor', 'metasync'), $label)),
86 __('Edit HTML', 'metasync')
87 );
88 }
89
90 return $actions;
91 }
92
93 /**
94 * Add editor admin page
95 */
96 public function add_editor_page()
97 {
98 $label = Metasync::get_whitelabel_company_name() ?: 'SearchAtlas';
99 $page_title = sprintf(__('%s HTML Editor', 'metasync'), $label);
100
101 add_submenu_page(
102 '', // Hidden from menu
103 $page_title,
104 $page_title,
105 'edit_pages',
106 Metasync_Admin::$page_slug . '-html-editor',
107 array($this, 'render_editor_page')
108 );
109 }
110
111 /**
112 * Render the visual editor page
113 */
114 public function render_editor_page()
115 {
116 // Check permissions
117 if (!current_user_can('edit_pages')) {
118 wp_die(__('You do not have sufficient permissions to access this page.'));
119 }
120
121 // Get post ID
122 $post_id = isset($_GET['post_id']) ? intval($_GET['post_id']) : 0;
123
124 if (!$post_id) {
125 wp_die(__('Invalid page ID.'));
126 }
127
128 if (!current_user_can('edit_post', $post_id)) {
129 wp_die(__('You do not have sufficient permissions to access this page.'));
130 }
131
132 // Get post
133 $post = get_post($post_id);
134
135 if (!$post) {
136 wp_die(__('Page not found.'));
137 }
138
139 // Check if raw HTML is enabled
140 $has_raw_html = get_post_meta($post_id, '_metasync_raw_html_enabled', true);
141
142 if (!$has_raw_html) {
143 wp_die(__('This page is not a raw HTML page.'));
144 }
145
146 // Get HTML content
147 $html_content = get_post_meta($post_id, '_metasync_raw_html_content', true);
148
149 if (empty($html_content)) {
150 $html_content = '<html><body><h1>Start editing...</h1></body></html>';
151 }
152
153 // Get label for branding
154 $label = Metasync::get_whitelabel_company_name() ?: 'SearchAtlas AI';
155
156 // Enqueue editor assets
157 $this->enqueue_editor_assets();
158
159 // Render editor UI
160 include plugin_dir_path(__FILE__) . 'partials/metasync-html-editor-page.php';
161 }
162
163 /**
164 * Enqueue editor assets (GrapesJS + custom scripts)
165 */
166 private function enqueue_editor_assets()
167 {
168 // Font Awesome for icons
169 wp_enqueue_style(
170 'font-awesome',
171 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
172 array(),
173 '6.4.0'
174 );
175
176 // GrapesJS core
177 wp_enqueue_style(
178 'grapesjs',
179 'https://unpkg.com/grapesjs@0.21.7/dist/css/grapes.min.css',
180 array(),
181 '0.21.7'
182 );
183
184 wp_enqueue_script(
185 'grapesjs',
186 'https://unpkg.com/grapesjs@0.21.7/dist/grapes.min.js',
187 array(),
188 '0.21.7',
189 true
190 );
191
192 // GrapesJS Plugins
193 wp_enqueue_script(
194 'grapesjs-blocks-basic',
195 'https://unpkg.com/grapesjs-blocks-basic',
196 array('grapesjs'),
197 null,
198 true
199 );
200
201 // Custom editor JS (with timestamp for cache busting)
202 wp_enqueue_script(
203 'metasync-html-editor',
204 plugins_url('js/metasync-html-editor.js', __FILE__),
205 array('jquery', 'grapesjs'),
206 $this->version . '.' . time(),
207 true
208 );
209
210 // Custom editor CSS (with timestamp for cache busting)
211 wp_enqueue_style(
212 'metasync-html-editor',
213 plugins_url('css/metasync-html-editor.css', __FILE__),
214 array('grapesjs'),
215 $this->version . '.' . time()
216 );
217
218 // Localize script with data
219 wp_localize_script('metasync-html-editor', 'metasyncEditor', array(
220 'ajax_url' => admin_url('admin-ajax.php'),
221 'nonce' => wp_create_nonce('metasync_html_editor'),
222 'post_id' => isset($_GET['post_id']) ? intval($_GET['post_id']) : 0,
223 'preview_url' => get_permalink(isset($_GET['post_id']) ? intval($_GET['post_id']) : 0),
224 'back_url' => admin_url('edit.php?post_type=page'),
225 'i18n' => array(
226 'saving' => __('Saving...', 'metasync'),
227 'saved' => __('Saved!', 'metasync'),
228 'error' => __('Error saving', 'metasync'),
229 'confirm_exit' => __('You have unsaved changes. Are you sure you want to leave?', 'metasync'),
230 )
231 ));
232 }
233
234 /**
235 * AJAX handler for saving HTML
236 */
237 public function ajax_save_html()
238 {
239 // Check nonce
240 check_ajax_referer('metasync_html_editor', 'nonce');
241
242 // Check permissions
243 if (!current_user_can('edit_pages')) {
244 wp_send_json_error(array('message' => __('Permission denied', 'metasync')));
245 }
246
247 // Get data
248 $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
249
250 if (!$post_id) {
251 wp_send_json_error(array('message' => __('Invalid data', 'metasync')));
252 }
253
254 if (!current_user_can('edit_post', $post_id)) {
255 wp_send_json_error(array('message' => __('Permission denied', 'metasync')), 403);
256 }
257
258 $html_content = isset($_POST['html']) ? wp_kses_post($_POST['html']) : '';
259
260 if (empty($html_content)) {
261 wp_send_json_error(array('message' => __('Invalid data', 'metasync')));
262 }
263
264 // Save HTML content
265 update_post_meta($post_id, '_metasync_raw_html_content', $html_content);
266
267 // Update modified date
268 wp_update_post(array(
269 'ID' => $post_id,
270 'post_modified' => current_time('mysql'),
271 'post_modified_gmt' => current_time('mysql', 1)
272 ));
273
274 wp_send_json_success(array(
275 'message' => __('Page saved successfully', 'metasync'),
276 'preview_url' => get_permalink($post_id)
277 ));
278 }
279
280 /**
281 * AJAX handler for uploading images
282 */
283 public function ajax_upload_image()
284 {
285 // Check nonce
286 check_ajax_referer('metasync_html_editor', 'nonce');
287
288 // Check permissions
289 if (!current_user_can('upload_files')) {
290 wp_send_json_error(array('message' => __('Permission denied', 'metasync')));
291 }
292
293 // Handle file upload
294 if (!isset($_FILES['file'])) {
295 wp_send_json_error(array('message' => __('No file uploaded', 'metasync')));
296 }
297
298 require_once(ABSPATH . 'wp-admin/includes/image.php');
299 require_once(ABSPATH . 'wp-admin/includes/file.php');
300 require_once(ABSPATH . 'wp-admin/includes/media.php');
301
302 $attachment_id = media_handle_upload('file', 0);
303
304 if (is_wp_error($attachment_id)) {
305 wp_send_json_error(array('message' => $attachment_id->get_error_message()));
306 }
307
308 $image_url = wp_get_attachment_url($attachment_id);
309
310 wp_send_json_success(array(
311 'url' => $image_url,
312 'id' => $attachment_id
313 ));
314 }
315 }
316