PluginProbe
WPIDE – File Manager & Code Editor / 2.5
WPIDE – File Manager & Code Editor v2.5
3.5.8 3.5.7 2.0.14 2.0.15 2.0.16 2.0.2 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1 2.2 2.3 2.3.1 2.3.2 2.4.0 2.5 2.6 3.0 3.1 3.2 3.3 3.4 All 54 releases
wpide / wpide.php

wpide.php in WPIDE – File Manager & Code Editor 2.5, at wpide.php

1,465 lines 56.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: WPide
4 Plugin URI: https://wpide.com/
5 Description: WordPress code editor with auto-completion of both WordPress and PHP functions with reference, syntax highlighting, line numbers, tabbed editing, automatic backup.
6 Version: 2.5
7 Author: WebFactory Ltd
8 Author URI: https://www.webfactoryltd.com/
9 Requires at least: 5.0
10 Requires PHP: 5.2
11 Tested up to: 5.7
12 Text Domain: wpide
13
14 Copyright 2021 WebFactory Ltd (email: wpide@webfactoryltd.com)
15 Copyright 2011 - 2021 Simon @ WPsites
16
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License, version 2, as
19 published by the Free Software Foundation.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31 if (!defined('ABSPATH')) {
32 die();
33 }
34
35 require_once 'wf-flyout/wf-flyout.php';
36 new wf_flyout(__FILE__);
37
38 if (!class_exists('wpide')) :
39 class wpide
40 {
41
42 public $site_url, $plugin_url;
43 private $menu_hook, $version;
44
45
46 function __construct()
47 {
48
49 $this->get_plugin_version();
50
51 // add WPide to the menu
52 add_action('admin_menu', array($this, 'add_my_menu_page'));
53
54 // hook for processing incoming image saves
55 if (is_admin() && isset($_GET['wpide_save_image'])) {
56
57 // force local file method for testing - you could force other methods 'direct', 'ssh', 'ftpext' or 'ftpsockets'
58 $this->override_fs_method('direct');
59
60 add_action('admin_init', array($this, 'wpide_save_image'));
61 }
62
63 add_action('admin_init', array($this, 'setup_hooks'));
64
65 $this->site_url = get_bloginfo('url');
66 }
67
68
69 public function override_fs_method($method = 'direct')
70 {
71 if (defined('FS_METHOD')) {
72 define('WPIDE_FS_METHOD_FORCED_ELSEWHERE', FS_METHOD); //make a note of the forced method
73 } else {
74 define('FS_METHOD', $method); //force direct
75 }
76 }
77
78 function is_plugin_page()
79 {
80 $current_screen = get_current_screen();
81
82 if ($current_screen->id === $this->menu_hook) {
83 return true;
84 } else {
85 return false;
86 }
87 }
88
89 // get plugin version from header
90 function get_plugin_version()
91 {
92 $plugin_data = get_file_data(__FILE__, array('version' => 'Version'), 'plugin');
93 $this->version = $plugin_data['version'];
94
95 return $plugin_data['version'];
96 } // get_plugin_version
97
98
99 public function setup_hooks()
100 {
101 // force local file method until I've worked out how to implement the other methods
102 // main problem being password wouldn't/isn't saved between requests
103 // you could force other methods 'direct', 'ssh', 'ftpext' or 'ftpsockets'
104 $this->override_fs_method('direct');
105
106 // Will only enqueue on WPide page
107 add_action('admin_print_scripts-' . $this->menu_hook, array($this, 'add_admin_js'));
108 add_action('admin_print_styles-' . $this->menu_hook, array($this, 'add_admin_styles'));
109
110 add_action('admin_print_footer_scripts', array($this, 'print_find_dialog'));
111
112 //setup jqueryFiletree list callback
113 add_action('wp_ajax_jqueryFileTree', array($this, 'jqueryFileTree_get_list'));
114 //setup ajax function to get file contents for editing
115 add_action('wp_ajax_wpide_get_file', array($this, 'wpide_get_file'));
116 //setup ajax function to save file contents and do automatic backup if needed
117 add_action('wp_ajax_wpide_save_file', array($this, 'wpide_save_file'));
118 //setup ajax function to rename file/folder
119 add_action('wp_ajax_wpide_rename_file', array($this, 'wpide_rename_file'));
120 //setup ajax function to delete file/folder
121 add_action('wp_ajax_wpide_delete_file', array($this, 'wpide_delete_file'));
122 //setup ajax function to handle upload
123 add_action('wp_ajax_wpide_upload_file', array($this, 'wpide_upload_file'));
124 //setup ajax function to handle download
125 add_action('wp_ajax_wpide_download_file', array($this, 'wpide_download_file'));
126 //setup ajax function to unzip file
127 add_action('wp_ajax_wpide_unzip_file', array($this, 'wpide_unzip_file'));
128 //setup ajax function to zip file
129 add_action('wp_ajax_wpide_zip_file', array($this, 'wpide_zip_file'));
130 //setup ajax function to create new item (folder, file etc)
131 add_action('wp_ajax_wpide_create_new', array($this, 'wpide_create_new'));
132
133 //setup ajax function to create new item (folder, file etc)
134 add_action('wp_ajax_wpide_image_edit_key', array($this, 'wpide_image_edit_key'));
135
136 //setup ajax function for startup to get some debug info, checking permissions etc
137 add_action('wp_ajax_wpide_startup_check', array($this, 'wpide_startup_check'));
138
139 //add a warning when navigating away from WPide
140 //it has to go after WordPress scripts otherwise WP clears the binding
141 // This has been implemented in load-editor.js
142 // todo:
143 // add_action('admin_print_footer_scripts', array( $this, 'add_admin_nav_warning' ), 99);
144
145 // Add body class to collapse the wp sidebar nav
146 add_filter('admin_body_class', array($this, 'hide_wp_sidebar_nav'), 11);
147
148 //hide the update nag
149 add_action('admin_menu', array($this, 'hide_wp_update_nag'));
150
151 add_filter(
152 'plugin_action_links_' . plugin_basename(__FILE__),
153 array($this, 'plugin_action_links')
154 );
155 add_filter('admin_footer_text', array($this, 'admin_footer_text'));
156 }
157
158
159 // add settings link to plugins page
160 function plugin_action_links($links)
161 {
162 $settings_link = '<a href="' . admin_url('admin.php?page=wpide') . '" title="Manage Files">Manage Files</a>';
163
164 array_unshift($links, $settings_link);
165
166 return $links;
167 } // plugin_action_links
168
169
170 // additional powered by text in admin footer; only on WPide page
171 function admin_footer_text($text)
172 {
173 if (!$this->is_plugin_page()) {
174 return $text;
175 }
176
177 $text = '<i><a href="https://wpide.com/" title="Visit WPide\'s site for more info" target="_blank">WPide</a> v' . $this->version . ' by <a href="https://www.webfactoryltd.com/" title="Visit our site to get more great plugins" target="_blank">WebFactory Ltd</a>. Please <a target="_blank" href="https://wordpress.org/support/plugin/wpide/reviews/#new-post" title="Rate the plugin">rate the plugin <span>�
178
179
180
181
182 </span></a> to help us spread the word. Thank you!</i>';
183
184 return $text;
185 } // admin_footer_text
186
187
188 public function hide_wp_sidebar_nav($classes)
189 {
190 global $hook_suffix;
191
192 if (!$this->is_plugin_page()) {
193 return $classes;
194 }
195
196 if (apply_filters('wpide_sidebar_folded', $hook_suffix === $this->menu_hook)) {
197 return str_replace("auto-fold", "", $classes) . ' folded';
198 }
199 }
200
201 public function hide_wp_update_nag()
202 {
203 if (!$this->is_plugin_page()) {
204 return;
205 }
206
207 remove_action('admin_notices', 'update_nag', 3);
208 }
209
210 public function add_admin_nav_warning()
211 {
212 ?>
213 <script type="text/javascript">
214 jQuery(document).ready(function($) {
215 window.onbeforeunload = function() {
216 return 'You are attempting to navigate away from WPide. Make sure you have saved any changes made to your files otherwise they will be forgotten.';
217 }
218 });
219 </script>
220 <?php
221 }
222
223 public function add_admin_js()
224 {
225 $plugin_path = plugin_dir_url(__FILE__);
226 //include file tree
227 wp_enqueue_script('jquery-file-tree', plugins_url("js/jqueryFileTree.js", __FILE__));
228 //include ace
229 wp_enqueue_script('ace', plugins_url("js/ace-1.2.0/ace.js", __FILE__));
230 //include ace modes for css, javascript & php
231 wp_enqueue_script('ace-mode-css', $plugin_path . 'js/ace-1.2.0/mode-css.js');
232 wp_enqueue_script('ace-mode-less', $plugin_path . 'js/ace-1.2.0/mode-less.js');
233 wp_enqueue_script('ace-mode-javascript', $plugin_path . 'js/ace-1.2.0/mode-javascript.js');
234 wp_enqueue_script('ace-mode-php', $plugin_path . 'js/ace-1.2.0/mode-php.js');
235 //include ace theme
236 wp_enqueue_script('ace-theme', plugins_url("js/ace-1.2.0/theme-dawn.js", __FILE__)); //ambiance looks really nice for high contrast
237 // wordpress-completion tags
238 wp_enqueue_script('wpide-wordpress-completion', plugins_url("js/autocomplete/wordpress.js", __FILE__));
239 // php-completion tags
240 wp_enqueue_script('wpide-php-completion', plugins_url("js/autocomplete/php.js", __FILE__));
241 // load editor
242 wp_enqueue_script('wpide-load-editor', plugins_url("js/load-editor.js", __FILE__));
243 // load filetree menu
244 wp_enqueue_script('wpide-load-filetree-menu', plugins_url("js/load-filetree-menu.js", __FILE__));
245 // load autocomplete dropdown
246 wp_enqueue_script('wpide-dd', plugins_url("js/jquery.dd.js", __FILE__));
247
248 // load jquery ui
249 wp_enqueue_script('jquery-ui', plugins_url("js/jquery-ui-1.9.2.custom.min.js", __FILE__), array('jquery'), '1.9.2');
250
251 // load color picker
252 wp_enqueue_script('ImageColorPicker', plugins_url("js/ImageColorPicker.js", __FILE__), array('jquery'), '0.3');
253 }
254
255 public function add_admin_styles()
256 {
257 //main wpide styles
258 wp_register_style('wpide_style', plugins_url('css/wpide.css', __FILE__));
259 wp_enqueue_style('wpide_style');
260 //filetree styles
261 wp_register_style('wpide_filetree_style', plugins_url('css/jqueryFileTree.css', __FILE__));
262 wp_enqueue_style('wpide_filetree_style');
263 //autocomplete dropdown styles
264 wp_register_style('wpide_dd_style', plugins_url('css/dd.css', __FILE__));
265 wp_enqueue_style('wpide_dd_style');
266
267 //jquery ui styles
268 wp_register_style('wpide_jqueryui_style', plugins_url('css/flick/jquery-ui-1.8.20.custom.css', __FILE__));
269 wp_enqueue_style('wpide_jqueryui_style');
270 }
271
272 public function jqueryFileTree_get_list()
273 {
274 //check the user has the permissions
275 check_admin_referer('plugin-name-action_wpidenonce');
276 if (!current_user_can('edit_themes'))
277 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
278
279 //setup wp_filesystem api
280 global $wp_filesystem;
281 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
282 $form_fields = null; // for now, but at some point the login info should be passed in here
283 if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
284 // no credentials yet, just produced a form for the user to fill in
285 return true; // stop the normal page form from displaying
286 }
287
288 if (!WP_Filesystem($creds))
289 return false;
290
291 $_POST['dir'] = urldecode($_POST['dir']);
292 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
293
294 if ($wp_filesystem->exists($root . $_POST['dir'])) {
295
296 $files = $wp_filesystem->dirlist($root . $_POST['dir']);
297
298 echo "<ul class=\"jqueryFileTree\" style=\"display: none;\">";
299 if (count($files) > 0) {
300
301 //build separate arrays for folders and files
302 $dir_array = array();
303 $file_array = array();
304 foreach ($files as $file => $file_info) {
305 if ($file != '.' && $file != '..' && $file_info['type'] == 'd') {
306 $file_string = strtolower(preg_replace("[._-]", "", $file));
307 $dir_array[$file_string] = $file_info;
308 } elseif ($file != '.' && $file != '..' && $file_info['type'] == 'f') {
309 $file_string = strtolower(preg_replace("[._-]", "", $file));
310 $file_array[$file_string] = $file_info;
311 }
312 }
313
314 //shot those arrays
315 ksort($dir_array);
316 ksort($file_array);
317
318 // All dirs
319 foreach ($dir_array as $file => $file_info) {
320 echo "<li class=\"directory collapsed\" draggable=\"true\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file_info['name']) . "/\" draggable=\"false\">" . htmlentities($file_info['name']) . "</a></li>";
321 }
322 // All files
323 foreach ($file_array as $file => $file_info) {
324 $ext = preg_replace('/^.*\./', '', $file_info['name']);
325 echo "<li class=\"file ext_$ext\" draggable=\"true\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file_info['name']) . "\" draggable=\"false\">" . htmlentities($file_info['name']) . "</a></li>";
326 }
327 }
328 //output toolbar for creating new file, folder etc
329 echo "<li class=\"create_new\"><a class='new_directory' title='Create a new directory here.' href=\"#\" rel=\"{type: 'directory', path: '" . htmlentities($_POST['dir']) . "'}\"></a> <a class='new_file' title='Create a new file here.' href=\"#\" rel=\"{type: 'file', path: '" . htmlentities($_POST['dir']) . "'}\"></a><br style='clear:both;' /></li>";
330 echo "</ul>";
331 }
332
333 die(); // this is required to return a proper result
334 }
335
336
337 public function wpide_get_file()
338 {
339 //check the user has the permissions
340 check_admin_referer('plugin-name-action_wpidenonce');
341 if (!current_user_can('edit_themes'))
342 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
343
344 //setup wp_filesystem api
345 global $wp_filesystem;
346 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
347 $form_fields = null; // for now, but at some point the login info should be passed in here
348 if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
349 // no credentials yet, just produced a form for the user to fill in
350 return true; // stop the normal page form from displaying
351 }
352 if (!WP_Filesystem($creds))
353 return false;
354
355
356 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
357 $file_name = $root . stripslashes($_POST['filename']);
358 echo $wp_filesystem->get_contents($file_name);
359 die(); // this is required to return a proper result
360 }
361
362 public function wpide_image_edit_key()
363 {
364
365 //check the user has the permissions
366 check_admin_referer('plugin-name-action_wpidenonce');
367 if (!current_user_can('edit_themes')) {
368 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
369 }
370
371 //create a nonce based on the image path
372 echo wp_create_nonce('wpide_image_edit' . $_POST['file']);
373 }
374
375 public function wpide_create_new()
376 {
377 //check the user has the permissions
378 check_admin_referer('plugin-name-action_wpidenonce');
379 if (!current_user_can('edit_themes')) {
380 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
381 }
382
383 //setup wp_filesystem api
384 global $wp_filesystem;
385 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
386 $form_fields = null; // for now, but at some point the login info should be passed in here
387 if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
388 // no credentials yet, just produced a form for the user to fill in
389 return true; // stop the normal page form from displaying
390 }
391 if (!WP_Filesystem($creds))
392 return false;
393
394 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
395
396 //check all required vars are passed
397 if (strlen($_POST['path']) > 0 && strlen($_POST['type']) > 0 && strlen($_POST['file']) > 0) {
398 $filename = $_POST['file'];
399 $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", chr(0));
400 $filename = preg_replace("#\x{00a0}#siu", ' ', $filename);
401 $filename = str_replace($special_chars, '', $filename);
402 $filename = str_replace(array('%20', '+'), '-', $filename);
403 $filename = preg_replace('/[\r\n\t -]+/', '-', $filename);
404
405 $path = $_POST['path'];
406
407 if ($_POST['type'] == "directory") {
408 $write_result = $wp_filesystem->mkdir($root . $path . $filename, FS_CHMOD_DIR);
409
410 if ($write_result) {
411 die("1"); //created
412 } else {
413 echo "Problem creating directory" . $root . $path . $filename;
414 }
415 } else if ($_POST['type'] == "file") {
416 //write the file
417 $write_result = $wp_filesystem->put_contents(
418 $root . $path . $filename,
419 '',
420 FS_CHMOD_FILE // predefined mode settings for WP files
421 );
422
423 if ($write_result) {
424 die("1"); //created
425 } else {
426 echo "Problem creating file " . $root . $path . $filename;
427 }
428 }
429 //print_r($_POST);
430 }
431
432 echo "0";
433 die(); // this is required to return a proper result
434 }
435
436 public function wpide_save_file()
437 {
438 //check the user has the permissions
439 check_admin_referer('plugin-name-action_wpidenonce');
440 if (!current_user_can('edit_themes')) {
441 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
442 }
443
444 $is_php = false;
445
446 /*
447 * Check file syntax of PHP files by parsing the PHP
448 * If a site is running low on memory this PHP parser library could well tip memory usage over the edge
449 * Especially if you are editing a large PHP file.
450 * Might be worth either making this syntax check optional or it only running if memory is available.
451 * Symptoms: no response on file save, and errors in your log like "Fatal error: Allowed memory size of 8388608 bytes exhausted…"
452 */
453 if (preg_match("#\.php$#i", $_POST['filename'])) {
454
455 $is_php = true;
456
457 require('PHP-Parser/lib/bootstrap.php');
458 ini_set('xdebug.max_nesting_level', 2000);
459
460 $code = stripslashes($_POST['content']);
461
462 $parser = new PHPParser_Parser(new PHPParser_Lexer);
463
464 try {
465 $stmts = $parser->parse($code);
466 } catch (PHPParser_Error $e) {
467 echo 'Parse Error: ', $e->getMessage();
468 die();
469 }
470 }
471
472 //setup wp_filesystem api
473 global $wp_filesystem;
474 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
475 $form_fields = null; // for now, but at some point the login info should be passed in here
476 if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
477 // no credentials yet, just produced a form for the user to fill in
478 return true; // stop the normal page form from displaying
479 }
480 if (!WP_Filesystem($creds))
481 echo "Cannot initialise the WP file system API";
482
483 //save a copy of the file and create a backup just in case
484 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
485 $file_name = $root . stripslashes($_POST['filename']);
486
487 //set backup filename
488 $backup_path = 'backups' . preg_replace("#\.php$#i", "_" . date("Y-m-d-H") . ".php", $_POST['filename']);
489 $backup_path_full = plugin_dir_path(__FILE__) . $backup_path;
490 //create backup directory if not there
491 $new_file_info = pathinfo($backup_path_full);
492 if (!$wp_filesystem->is_dir($new_file_info['dirname'])) wp_mkdir_p($new_file_info['dirname']); //should use the filesytem api here but there isn't a comparable command right now
493
494 if ($is_php) {
495 //create the backup file adding some php to the file to enable direct restore
496 global $current_user;
497 get_currentuserinfo();
498 $user_md5 = md5(serialize($current_user));
499
500 $restore_php = '<?php /* start WPide restore code */
501 if ($_POST["restorewpnonce"] === "' . $user_md5 . $_POST['_wpnonce'] . '"){
502 if ( file_put_contents ( "' . $file_name . '" , preg_replace("#<\?php /\* start WPide(.*)end WPide restore code \*/ \?>#s", "", file_get_contents("' . $backup_path_full . '") ) ) ){
503 echo "Your file has been restored, overwritting the recently edited file! \n\n The active editor still contains the broken or unwanted code. If you no longer need that content then close the tab and start fresh with the restored file.";
504 }
505 }else{
506 echo "-1";
507 }
508 die();
509 /* end WPide restore code */ ?>';
510
511 file_put_contents($backup_path_full, $restore_php . file_get_contents($file_name));
512 } else {
513 //do normal backup
514 $wp_filesystem->copy($file_name, $backup_path_full);
515 }
516
517 //save file
518 if ($wp_filesystem->put_contents($file_name, stripslashes($_POST['content']))) {
519
520 //lets create an extra long nonce to make it less crackable
521 global $current_user;
522 get_currentuserinfo();
523 $user_md5 = md5(serialize($current_user));
524
525 $result = "\"" . $backup_path . ":::" . $user_md5 . "\"";
526 }
527
528 die($result); // this is required to return a proper result
529 }
530
531
532 public function wpide_rename_file()
533 {
534 global $wp_filesystem;
535
536 //check the user has the permissions
537 check_admin_referer('plugin-name-action_wpidenonce');
538 if (!current_user_can('manage_options')) {
539 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
540 }
541
542 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
543 $form_fields = null; // for now, but at some point the login info should be passed in here
544 $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
545 if (false === $creds) {
546 // no credentials yet, just produced a form for the user to fill in
547 return true; // stop the normal page form from displaying
548 }
549 if (!WP_Filesystem($creds))
550 echo "Cannot initialise the WP file system API";
551
552
553 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
554 $file_name = $root . stripslashes($_POST['filename']);
555 $new_name = dirname($file_name) . '/' . stripslashes($_POST['newname']);
556
557 if (!$wp_filesystem->exists($file_name)) {
558 echo 'The target file doesn\'t exist!';
559 exit;
560 }
561
562 if ($wp_filesystem->exists($new_name)) {
563 echo 'The destination file exists!';
564 exit;
565 }
566
567 // Move instead of rename
568 $renamed = $wp_filesystem->move($file_name, $new_name);
569
570 if (!$renamed) {
571 echo 'The file could not be renamed!';
572 }
573 exit;
574 }
575
576
577 public function wpide_delete_file()
578 {
579 global $wp_filesystem;
580
581 //check the user has the permissions
582 check_admin_referer('plugin-name-action_wpidenonce');
583 if (!current_user_can('manage_options')) {
584 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
585 }
586
587 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
588 $form_fields = null; // for now, but at some point the login info should be passed in here
589 $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
590 if (false === $creds) {
591 // no credentials yet, just produced a form for the user to fill in
592 return true; // stop the normal page form from displaying
593 }
594 if (!WP_Filesystem($creds))
595 echo "Cannot initialise the WP file system API";
596
597
598 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
599 $file_name = $root . stripslashes($_POST['filename']);
600
601 if (!$wp_filesystem->exists($file_name)) {
602 echo 'The file doesn\'t exist!';
603 exit;
604 }
605
606 $deleted = $wp_filesystem->delete($file_name);
607
608 if (!$deleted) {
609 echo 'The file couldn\'t be deleted.';
610 }
611
612 exit;
613 }
614
615 public function wpide_upload_file()
616 {
617 global $wp_filesystem;
618
619 //check the user has the permissions
620 check_admin_referer('plugin-name-action_wpidenonce');
621 if (!current_user_can('manage_options')) {
622 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
623 }
624
625 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
626 $form_fields = null; // for now, but at some point the login info should be passed in here
627 $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
628 if (false === $creds) {
629 // no credentials yet, just produced a form for the user to fill in
630 return true; // stop the normal page form from displaying
631 }
632 if (!WP_Filesystem($creds))
633 echo "Cannot initialise the WP file system API";
634
635
636 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
637 $destination_folder = $root . stripslashes($_POST['destination']);
638
639 foreach ($_FILES as $file) {
640 if (!is_uploaded_file($file['tmp_name'])) {
641 continue;
642 }
643
644 $destination = $destination_folder . $file['name'];
645
646 if ($wp_filesystem->exists($destination)) {
647 exit($file['name'] . ' already exists!');
648 }
649
650 if (!$wp_filesystem->move($file['tmp_name'], $destination)) {
651 exit($file['name'] . ' could not be moved.');
652 }
653
654 if (!$wp_filesystem->chmod($destination)) {
655 exit($file['name'] . ' could not be chmod.');
656 }
657 }
658 exit;
659 }
660
661 public function wpide_download_file()
662 {
663 global $wp_filesystem;
664
665 //check the user has the permissions
666 check_admin_referer('plugin-name-action_wpidenonce');
667 if (!current_user_can('manage_options')) {
668 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
669 }
670
671 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
672 $form_fields = null; // for now, but at some point the login info should be passed in here
673 $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
674 if (false === $creds) {
675 // no credentials yet, just produced a form for the user to fill in
676 return true; // stop the normal page form from displaying
677 }
678 if (!WP_Filesystem($creds))
679 echo "Cannot initialise the WP file system API";
680
681 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
682 $file_name = $root . stripslashes($_POST['filename']);
683
684 if (!$wp_filesystem->exists($file_name)) {
685 echo 'The file doesn\'t exist!';
686 exit;
687 }
688
689 header('Content-Description: File Transfer');
690 header('Content-Type: application/octet-stream');
691 header('Content-Disposition: filename="' . basename($file_name) . '"');
692 header('Expires: 0');
693 header('Cache-Control: must-revalidate');
694 header('Pragma: public');
695
696 echo $wp_filesystem->get_contents($file_name);
697 exit;
698 }
699
700 public function wpide_zip_file()
701 {
702 global $wp_filesystem;
703
704 //check the user has the permissions
705 check_admin_referer('plugin-name-action_wpidenonce');
706 if (!current_user_can('manage_options')) {
707 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
708 }
709
710 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
711 $file_name = $root . stripslashes($_POST['filename']);
712
713 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
714 $form_fields = null; // for now, but at some point the login info should be passed in here
715 $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
716 if (false === $creds) {
717 // no credentials yet, just produced a form for the user to fill in
718 return true; // stop the normal page form from displaying
719 }
720 if (!WP_Filesystem($creds))
721 echo "Cannot initialise the WP file system API";
722
723
724 if (!$wp_filesystem->exists($file_name)) {
725 echo 'Error: target file does not exist!';
726 exit;
727 }
728
729 $ext = '.zip';
730 switch (apply_filters('wpide_compression_method', 'zip')) {
731 case 'gz':
732 $ext = '.tar.gz';
733 break;
734 case 'tar':
735 $ext = '.tar';
736 break;
737 case 'b2z':
738 $ext = '.b2z';
739 break;
740 case 'zip':
741 $ext = '.zip';
742 break;
743 }
744
745 // Unzip a file to its current directory.
746 if ($wp_filesystem->is_dir($file_name)) {
747 $output_path = dirname($file_name) . '/' . basename($file_name) . $ext;
748 } else {
749 $output_path = $file_name;
750 $output_path = strstr($file_name, '.', true) . $ext;
751 }
752
753 $zipped = self::do_zip_file($file_name, $output_path);
754
755 if (is_wp_error($zipped)) {
756 printf('%s: %s', $zipped->get_error_code(), $zipped->get_error_message());
757 exit;
758 }
759
760 exit;
761 }
762
763 protected function do_zip_file($file, $to)
764 {
765 // Unzip can use a lot of memory, but not this much hopefully
766 @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
767
768 $method = apply_filters('wpide_compression_method', 'zip');
769
770 switch ($method) {
771 case 'gz':
772 case 'tar':
773 if (class_exists('PharData') && apply_filters('unzip_file_use_phardata', true)) {
774 exit('yes');
775 return self::_zip_archive_phardata($file, $to);
776 } else {
777 exit('figure it out');
778 }
779
780 /* if ( $method === 'gz' ) {
781 $gz = gzopen( $to );
782 }
783 */
784 break;
785 case 'b2z':
786 exit('B2Z!');
787 case 'zip':
788 default:
789 if ($method !== 'zip') {
790 trigger_error(sprintf('"%s" is not a valid compression mechanism.', $method));
791 }
792
793 if (class_exists('ZipArchive') && apply_filters('unzip_file_use_ziparchive', true)) {
794 return self::_zip_file_ziparchive($file, $to);
795 } else {
796 // Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file.
797 return self::_zip_file_pclzip($file, $to);
798 }
799 break;
800 }
801 }
802
803 protected static function _zip_file_ziparchive($file, $to)
804 {
805 $z = new ZipArchive;
806 $opened = $z->open($to, ZipArchive::CREATE);
807
808 if ($opened !== true) {
809 switch ($opened) {
810 case ZipArchive::ER_EXISTS:
811 return new WP_Error(
812 'ZipArchive Error',
813 'File already exists',
814 ZipArchive::ER_EXISTS
815 );
816 case ZipArchive::ER_INCONS:
817 return new WP_Error(
818 'ZipArchive Error',
819 'Archive inconsistent',
820 ZipArchive::ER_INCONS
821 );
822 case ZipArchive::ER_INVAL:
823 return new WP_Error(
824 'ZipArchive Error',
825 'Invalid argument',
826 ZipArchive::ER_INVAL
827 );
828 case ZipArchive::ER_MEMORY:
829 return new WP_Error(
830 'ZipArchive Error',
831 'Malloc failure',
832 ZipArchive::ER_MEMORY
833 );
834 case ZipArchive::ER_NOENT:
835 return new WP_Error(
836 'ZipArchive Error',
837 'No such file.',
838 ZipArchive::ER_NOENT
839 );
840 case ZipArchive::ER_NOZIP:
841 return new WP_Error(
842 'ZipArchive Error',
843 'Not a zip archive.',
844 ZipArchive::ER_NOZIP
845 );
846 case ZipArchive::ER_OPEN:
847 return new WP_Error(
848 'ZipArchive Error',
849 'Can\'t open file.',
850 ZipArchive::ER_OPEN
851 );
852 case ZipArchive::ER_READ:
853 return new WP_Error(
854 'ZipArchive Error',
855 'Read Error',
856 ZipArchive::ER_READ
857 );
858 case ZipArchive::ER_SEEK:
859 return new WP_Error(
860 'ZipArchive Error',
861 'Seek Error',
862 ZipArchive::ER_SEEK
863 );
864
865 default:
866 return new WP_Error(
867 'ZipArchive Error',
868 'Unknown Error',
869 $opened
870 );
871 break;
872 }
873 }
874
875 if (is_dir($file)) {
876 $base = dirname($file);
877 $file = untrailingslashit($file);
878
879 $z = self::_zip_folder_ziparchive($base, $file, $to, $z);
880 if (is_wp_error($z))
881 return $z;
882 } else {
883 $z->addFile($file, basename($file));
884 }
885
886 $z->close();
887
888 return true;
889 }
890
891 protected static function _zip_folder_ziparchive($zip_base, $folder, $to, $z)
892 {
893 $handle = opendir($folder);
894 while (1) {
895 $file = readdir($handle);
896
897 if (false === $file)
898 break;
899
900 if (($file != '.') && ($file != '..')) {
901 $filePath = "$folder/$file";
902 $filePathRel = str_replace($zip_base, '', $filePath);
903
904 if ($filePathRel[0] === '/')
905 $filePathRel = substr($filePathRel, 1);
906
907 if (is_file($filePath)) {
908 $z->addFile($filePath, $filePathRel);
909 } elseif (is_dir($filePath)) {
910 // Add sub-directory.
911 $z->addEmptyDir($filePathRel);
912 self::_zip_folder_ziparchive($zip_base, $filePath, $to, $z);
913 }
914 }
915 }
916 closedir($handle);
917
918 return $z;
919 }
920
921 protected static function _zip_file_pclzip($file, $to)
922 {
923 require_once(ABSPATH . 'wp-admin/includes/class-pclzip.php');
924
925 $pz = new PclZip($to);
926 $created = $pz->create($file, PCLZIP_OPT_REMOVE_PATH, dirname($file));
927
928 if (!$created) {
929 return new WP_Error('PclZip Error', $pz->errorInfo(true));
930 }
931
932 return true;
933 }
934
935 protected static function _zip_file_phardata($file, $to)
936 {
937 $p = new PharData($to);
938
939 if (is_dir($file)) {
940 $p->buildFromDirectory($file);
941 } else {
942 $p->addFile($file, basename($file));
943 }
944
945 return true;
946 }
947
948 public function wpide_unzip_file()
949 {
950 global $wp_filesystem;
951
952 //check the user has the permissions
953 check_admin_referer('plugin-name-action_wpidenonce');
954 if (!current_user_can('manage_options')) {
955 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
956 }
957
958 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
959 $file_name = $root . stripslashes($_POST['filename']);
960
961 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
962 $form_fields = null; // for now, but at some point the login info should be passed in here
963 $creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields);
964 if (false === $creds) {
965 // no credentials yet, just produced a form for the user to fill in
966 return true; // stop the normal page form from displaying
967 }
968 if (!WP_Filesystem($creds))
969 echo "Cannot initialise the WP file system API";
970
971
972 if (!$wp_filesystem->exists($file_name)) {
973 echo 'Error: Extraction path doesn\'t exist!';
974 exit;
975 }
976
977 $unzipped = self::do_unzip_file($file_name, dirname($file_name));
978
979 if (is_wp_error($unzipped)) {
980 printf('%s: %s', $unzipped->get_error_code(), $unzipped->get_error_message());
981 exit;
982 }
983
984 exit;
985 }
986
987 protected function do_unzip_file($from, $to)
988 {
989 if (!file_exists($from)) {
990 return new WP_Error('file-missing', 'Archive missing.');
991 }
992
993 $fp = fopen($from, 'rb');
994 $bytes = fread($fp, 2);
995 fclose($fp);
996
997 switch ($bytes) {
998 case "\37\213":
999 // gz
1000 case 'BZ':
1001 return new WP_Error('unimplemented', 'That method is not yet implemented.');
1002 break;
1003 case 'PK':
1004 return unzip_file($from, $to);
1005 default:
1006 return new WP_Error('unknown', 'Unknown archive type');
1007 }
1008 }
1009
1010 public function wpide_save_image()
1011 {
1012 $filennonce = split("::", $_POST["opt"]); //file::nonce
1013
1014 //check the user has a valid nonce
1015 //we are checking two variations of the nonce, one as-is and another that we have removed a trailing zero from
1016 //this is to get around some sort of bug where a nonce generated on another page has a trailing zero and a nonce generated/checked here doesn't have the zero
1017 if (
1018 !wp_verify_nonce($filennonce[1], 'wpide_image_edit' . $filennonce[0]) &&
1019 !wp_verify_nonce(rtrim($filennonce[1], "0"), 'wpide_image_edit' . $filennonce[0])
1020 ) {
1021 die('Security check'); //die because both checks failed
1022 }
1023 //check the user has the permissions
1024 if (!current_user_can('edit_themes')) {
1025 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
1026 }
1027
1028
1029 $_POST['content'] = base64_decode($_POST["data"]); //image content
1030 $_POST['filename'] = $filennonce[0]; //filename
1031
1032 //setup wp_filesystem api
1033 global $wp_filesystem;
1034 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
1035 $form_fields = null; // for now, but at some point the login info should be passed in here
1036 if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
1037 // no credentials yet, just produced a form for the user to fill in
1038 return true; // stop the normal page form from displaying
1039 }
1040 if (!WP_Filesystem($creds))
1041 echo "Cannot initialise the WP file system API";
1042
1043 //save a copy of the file and create a backup just in case
1044 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
1045 $file_name = $root . stripslashes($_POST['filename']);
1046
1047 //set backup filename
1048 $backup_path = 'backups' . preg_replace("#\.php$#i", "_" . date("Y-m-d-H") . ".php", $_POST['filename']);
1049 $backup_path = plugin_dir_path(__FILE__) . $backup_path;
1050
1051 //create backup directory if not there
1052 $new_file_info = pathinfo($backup_path);
1053 if (!$wp_filesystem->is_dir($new_file_info['dirname'])) wp_mkdir_p($new_file_info['dirname']); //should use the filesytem api here but there isn't a comparable command right now
1054
1055 //do backup
1056 $wp_filesystem->move($file_name, $backup_path);
1057
1058 //save file
1059 if ($wp_filesystem->put_contents($file_name, $_POST['content'])) {
1060 $result = "success";
1061 }
1062
1063 if ($result == "success") {
1064 wp_die('<p>' . __('<strong>Image saved.</strong> <br />You may <a href="JavaScript:window.close();">close this window / tab</a>.') . '</p>');
1065 } else {
1066 wp_die('<p>' . __('<strong>Problem saving image.</strong> <br /><a href="JavaScript:window.close();">Close this window / tab</a> and try editing the image again.') . '</p>');
1067 }
1068 //print_r($_POST);
1069 }
1070
1071
1072 public function wpide_startup_check()
1073 {
1074 global $wp_filesystem, $wp_version;
1075
1076 echo "\n\n\n\nWPIDE STARTUP CHECKS \n";
1077 echo "___________________ \n\n";
1078
1079 // WordPress version
1080 if ($wp_version > 5) {
1081 echo "WordPress version = " . $wp_version . "\n\n";
1082 } else {
1083 echo "WordPress version = " . $wp_version . " (which is too old to run WPide) \n\n";
1084 }
1085
1086 //check the user has the permissions
1087 check_admin_referer('plugin-name-action_wpidenonce');
1088 if (!current_user_can('edit_themes'))
1089 wp_die('<p>' . __('You do not have sufficient permissions to edit templates for this site. SORRY') . '</p>');
1090
1091 if (defined('WPIDE_FS_METHOD_FORCED_ELSEWHERE')) {
1092 echo "WordPress filesystem API has been forced to use the " . WPIDE_FS_METHOD_FORCED_ELSEWHERE . " method by another plugin/WordPress. \n\n";
1093 }
1094
1095 //setup wp_filesystem api
1096 $wpide_filesystem_before = $wp_filesystem;
1097
1098 $url = wp_nonce_url('admin.php?page=wpide', 'plugin-name-action_wpidenonce');
1099 $form_fields = null; // for now, but at some point the login info should be passed in here
1100 ob_start();
1101 if (false === ($creds = request_filesystem_credentials($url, FS_METHOD, false, false, $form_fields))) {
1102 // if we get here, then we don't have credentials yet,
1103 // but have just produced a form for the user to fill in,
1104 // so stop processing for now
1105 //return true; // stop the normal page form from displaying
1106 }
1107 ob_end_clean();
1108 if (!WP_Filesystem($creds)) {
1109
1110 echo "There has been a problem initialising the filesystem API \n\n";
1111 echo "Filesystem API before this plugin ran: \n\n" . print_r($wpide_filesystem_before, true);
1112 echo "Filesystem API now: \n\n" . print_r($wp_filesystem, true);
1113 }
1114 unset($wpide_filesystem_before);
1115
1116
1117 $root = apply_filters('wpide_filesystem_root', WP_CONTENT_DIR);
1118 if (isset($wp_filesystem)) {
1119
1120 //Running webservers user and group
1121 echo "Web server user/group = " . getenv('APACHE_RUN_USER') . ":" . getenv('APACHE_RUN_GROUP') . "\n";
1122 //wp-content user and group
1123 echo "wp-content owner/group = " . $wp_filesystem->owner($root) . ":" . $wp_filesystem->group($root) . "\n\n";
1124
1125
1126 //check we can list wp-content files
1127 if ($wp_filesystem->exists($root)) {
1128
1129 $files = $wp_filesystem->dirlist($root);
1130 if (count($files) > 0) {
1131 echo "wp-content folder exists and contains " . count($files) . " files \n";
1132 } else {
1133 echo "wp-content folder exists but we cannot read it's contents \n";
1134 }
1135 }
1136
1137 // $wp_filesystem->owner() $wp_filesystem->group() $wp_filesystem->is_writable() $wp_filesystem->is_readable()
1138 echo "\nUsing the " . $wp_filesystem->method . " method of the WP filesystem API\n";
1139
1140 //wp-content editable?
1141 echo "The wp-content folder " . ($wp_filesystem->is_readable($root) == 1 ? "IS" : "IS NOT") . " readable and " . ($wp_filesystem->is_writable($root) == 1 ? "IS" : "IS NOT") . " writable by this method \n";
1142
1143
1144 //plugins folder editable
1145 echo "The wp-content/plugins folder " . ($wp_filesystem->is_readable($root . "/plugins") == 1 ? "IS" : "IS NOT") . " readable and " . ($wp_filesystem->is_writable($root . "/plugins") == 1 ? "IS" : "IS NOT") . " writable by this method \n";
1146
1147
1148 //themes folder editable
1149 echo "The wp-content/themes folder " . ($wp_filesystem->is_readable($root . "/themes") == 1 ? "IS" : "IS NOT") . " readable and " . ($wp_filesystem->is_writable($root . "/themes") == 1 ? "IS" : "IS NOT") . " writable by this method \n";
1150 }
1151
1152 echo "___________________ \n\n\n\n";
1153
1154 echo " If the file tree to the right is empty there is a possibility that your server permissions are not compatible with this plugin. \n The startup information above may shed some light on things. \n Paste that information into the support forum for further assistance.";
1155
1156
1157 die();
1158 }
1159
1160 public function add_my_menu_page()
1161 {
1162 $this->menu_hook = add_menu_page('WPide', 'WPide', 'edit_themes', "wpide", array($this, 'my_menu_page'), 'dashicons-editor-code');
1163 }
1164
1165 public function my_menu_page()
1166 {
1167 if (!current_user_can('edit_themes')) {
1168 wp_die('<p>You do not have sufficient permissions to edit files for this site.</p>');
1169 }
1170
1171 $app_url = get_bloginfo('url'); //need to make this https if we are currently looking on the site using https (even though https for admin might not be forced it can still cause issues)
1172 if (is_ssl()) $app_url = str_replace("http:", "https:", $app_url);
1173
1174 ?>
1175 <script>
1176 var wpide_app_path = "<?php echo plugin_dir_url(__FILE__); ?>";
1177 //dont think this is needed any more.. var wpide_file_root_url = "<?php echo apply_filters("wpide_file_root_url", WP_CONTENT_URL); ?>";
1178 var user_nonce_addition = '';
1179
1180 function the_filetree() {
1181 jQuery('#wpide_file_browser').fileTree({
1182 script: ajaxurl
1183 }, function(parent, file) {
1184
1185 if (jQuery(parent).hasClass("create_new")) { //create new file/folder
1186 //to create a new item we need to know the name of it so show input
1187
1188 var item = eval('(' + file + ')');
1189
1190 //hide all inputs just incase one is selected
1191 jQuery(".new_item_inputs").hide();
1192 //show the input form for this
1193 jQuery("div.new_" + item.type).show();
1194 jQuery("div.new_" + item.type + " input[name='new_" + item.type + "']").focus();
1195 jQuery("div.new_" + item.type + " input[name='new_" + item.type + "']").attr("rel", file);
1196
1197
1198 } else if (jQuery(".wpide_tab[rel='" + file + "']").length > 0) { //focus existing tab
1199 jQuery(".wpide_tab[sessionrel='" + jQuery(".wpide_tab[rel='" + file + "']").attr("sessionrel") + "']").click(); //focus the already open tab
1200 } else { //open file
1201
1202 var image_pattern = new RegExp("(\\.jpg$|\\.gif$|\\.png$|\\.bmp$)");
1203 if (image_pattern.test(file)) {
1204 //it's an image so open it for editing
1205
1206 //using modal+iframe
1207 if ("lets not" == "use the modal for now") {
1208
1209 var NewDialog = jQuery('<div id="MenuDialog">\
1210 <iframe src="http://www.sumopaint.com/app/?key=ebcdaezjeojbfgih&target=<?php echo get_bloginfo('url') . "?action=wpide_image_save"; ?>&url=<?php echo get_bloginfo('url') . "/wp-content"; ?>' + file + '&title=Edit image&service=Save back to WPide" width="100%" height="600px"> </iframe>\
1211 </div>');
1212 NewDialog.dialog({
1213 modal: true,
1214 title: "title",
1215 show: 'clip',
1216 hide: 'clip',
1217 width: '800',
1218 height: '600'
1219 });
1220
1221 } else { //open in new tab/window
1222
1223 var data = {
1224 action: 'wpide_image_edit_key',
1225 file: file,
1226 _wpnonce: jQuery('#_wpnonce').val(),
1227 _wp_http_referer: jQuery('#_wp_http_referer').val()
1228 };
1229 var image_data = '';
1230 jQuery.ajaxSetup({
1231 async: false
1232 }); //we need to wait until we get the response before opening the window
1233 jQuery.post(ajaxurl, data, function(response) {
1234
1235 //with the response (which is a nonce), build the json data to pass to the image editor. The edit key (nonce) is only valid to edit this image
1236 image_data = file + '::' + response;
1237
1238 });
1239
1240 jQuery.ajaxSetup({
1241 async: true
1242 }); //enable async again
1243
1244
1245 window.open('http://www.sumopaint.com/app/?key=ebcdaezjeojbfgih&url=<?php echo $app_url . "/wp-content"; ?>' + file + '&opt=' + image_data + '&title=Edit image&service=Save back to WPide&target=<?php echo urlencode($app_url . "/wp-admin/admin.php?wpide_save_image=yes"); ?>');
1246
1247 }
1248
1249 } else {
1250 jQuery(parent).addClass('wait');
1251
1252 wpide_set_file_contents(file, function() {
1253
1254 //once file loaded remove the wait class/indicator
1255 jQuery(parent).removeClass('wait');
1256
1257 });
1258
1259 jQuery('#filename').val(file);
1260 }
1261
1262 }
1263
1264 });
1265 }
1266
1267
1268
1269 jQuery(document).ready(function($) {
1270
1271 // $("#fancyeditordiv").css("height", ($('body').height()-120) + 'px' );
1272
1273 // Handler for .ready() called.
1274 the_filetree();
1275
1276 //inialise the color assist
1277 $("#wpide_color_assist img").ImageColorPicker({
1278 afterColorSelected: function(event, color) {
1279 jQuery("#wpide_color_assist_input").val(color);
1280 }
1281 });
1282 $("#wpide_color_assist").hide(); //hide it until it's needed
1283
1284 $("#wpide_color_assist_send").click(function(e) {
1285 e.preventDefault();
1286 editor.insert(jQuery("#wpide_color_assist_input").val().replace('#', ''));
1287
1288 $("#wpide_color_assist").hide(); //hide it until it's needed again
1289 });
1290
1291 $(".close_color_picker a").click(function(e) {
1292 e.preventDefault();
1293 $("#wpide_color_assist").hide(); //hide it until it's needed again
1294 });
1295
1296 $("#wpide_toolbar_buttons").on('click', "a.restore", function(e) {
1297 e.preventDefault();
1298 var file_path = jQuery(".wpide_tab.active", "#wpide_toolbar").data("backup");
1299
1300 jQuery("#wpide_message").hide(); //might be shortly after a save so a message may be showing, which we don't need
1301 jQuery("#wpide_message").html('<span><strong>File available for restore</strong><p> ' + file_path + '</p><a class="button red restore now" href="' + wpide_app_path + file_path + '">Restore this file now &#10012;</a><a class="button restore cancel" href="#">Cancel &#10007;</a><br /><em class="note"><strong>note: </strong>You can browse all file backups if you navigate to the backups folder (plugins/WPide/backups/..) using the filetree.</em></span>');
1302 jQuery("#wpide_message").show();
1303 });
1304 $("#wpide_toolbar_buttons").on('click', "a.restore.now", function(e) {
1305 e.preventDefault();
1306
1307 var data = {
1308 restorewpnonce: user_nonce_addition + jQuery('#_wpnonce').val()
1309 };
1310 jQuery.post(wpide_app_path + jQuery(".wpide_tab.active", "#wpide_toolbar").data("backup"), data, function(response) {
1311
1312 if (response == -1) {
1313 alert("Problem restoring file.");
1314 } else {
1315 alert(response);
1316 jQuery("#wpide_message").hide();
1317 }
1318
1319 });
1320
1321 });
1322 $("#wpide_toolbar_buttons").on('click', "a.cancel", function(e) {
1323 e.preventDefault();
1324
1325 jQuery("#wpide_message").hide(); //might be shortly after a save so a message may be showing, which we don't need
1326 });
1327
1328 });
1329 </script>
1330
1331 <div id="poststuff" class="metabox-holder has-right-sidebar">
1332
1333 <div id="side-info-column" class="inner-sidebar">
1334
1335 <div id="wpide_info">
1336 <div id="wpide_info_content"></div>
1337 </div>
1338 <br style="clear:both;" />
1339 <div id="wpide_color_assist">
1340 <div class="close_color_picker"><a href="close-color-picker">x</a></div>
1341 <h3>Colour Assist</h3>
1342 <img src='<?php echo plugins_url("images/color-wheel.png", __FILE__); ?>' />
1343 <input type="button" class="button" id="wpide_color_assist_send" value="&lt; Send to editor" />
1344 <input type="text" id="wpide_color_assist_input" name="wpide_color_assist_input" value="" />
1345
1346 </div>
1347
1348
1349
1350 <div id="submitdiv" class="postbox ">
1351 <h3 class="hndle"><span>Files</span></h3>
1352 <div class="inside">
1353 <div class="submitbox" id="submitpost">
1354 <div id="minor-publishing">
1355 </div>
1356 <div id="major-publishing-actions">
1357 <div id="wpide_file_browser"></div>
1358 <br style="clear:both;" />
1359 <div class="new_file new_item_inputs">
1360 <label for="new_folder">File name</label><input class="has_data" name="new_file" type="text" rel="" value="" placeholder="Filename.ext" />
1361 <a href="#" id="wpide_create_new_file" class="button-primary">CREATE</a>
1362 </div>
1363 <div class="new_directory new_item_inputs">
1364 <label for="new_directory">Directory name</label><input class="has_data" name="new_directory" type="text" rel="" value="" placeholder="Filename.ext" />
1365 <a href="#" id="wpide_create_new_directory" class="button-primary">CREATE</a>
1366 </div>
1367 <div class="clear"></div>
1368 </div>
1369 </div>
1370 </div>
1371 </div>
1372
1373
1374 </div>
1375
1376 <div id="post-body">
1377 <div id="wpide_toolbar" class="quicktags-toolbar">
1378 <div id="wpide_toolbar_tabs"> </div>
1379 <div id="dialog_window_minimized_container"></div>
1380 </div>
1381
1382 <div id="wpide_toolbar_buttons">
1383 <div id="wpide_message"></div>
1384 <a class="button restore" style="display:none;" title="Restore the active tab" href="#">Restore &#10012;</a>
1385
1386 </div>
1387
1388
1389 <div id='fancyeditordiv'></div>
1390
1391 <form id="wpide_save_container" action="" method="get">
1392 <div id="wpide_footer_message"></div>
1393 <div id="wpide_footer_message_last_saved"></div>
1394 <div id="wpide_footer_message_unsaved"></div>
1395
1396 <a href="#" id="wpide_save" alt="Keyboard shortcut to save [Ctrl/Cmd + S]" title="Keyboard shortcut to save [Ctrl/Cmd + S]" class="button-primary">SAVE
1397 FILE</a>
1398
1399 <input type="hidden" id="filename" name="filename" value="" />
1400 <?php
1401 if (function_exists('wp_nonce_field'))
1402 wp_nonce_field('plugin-name-action_wpidenonce');
1403 ?>
1404 </form>
1405
1406 </div>
1407
1408 </div>
1409
1410 <?php
1411 }
1412
1413 public function print_find_dialog()
1414 {
1415 if (!$this->is_plugin_page()) {
1416 return;
1417 }
1418 ?>
1419 <div id="editor_find_dialog" title="Find..." style="padding: 0px; display: none;">
1420 <?php if (false) : ?>
1421 <ul>
1422 <li><a href="#find-inline">Text</a></li>
1423 <li><a href="#find-func">Function</a></li>
1424 </ul>
1425 <?php endif; ?>
1426 <form id="find-inline" style="position: relative; padding: 4px; margin: 0px; height: 100%; overflow: hidden; width: 400px;">
1427 <label class="left"> Find<input type="search" name="find" /></label>
1428 <label class="left"> Replace<input type="search" name="replace" /></label>
1429 <div class="clear" style="height: 33px;"></div>
1430
1431 <label><input type="checkbox" name="wrap" checked="checked" /> Wrap Around</label>
1432 <label><input type="checkbox" name="case" /> Case Sensitive</label>
1433 <label><input type="checkbox" name="whole" /> Match Whole Word</label>
1434 <label><input type="checkbox" name="regexp" /> Regular Expression</label>
1435
1436 <div class="search_direction">
1437 Direction:
1438 <label><input type="radio" name="direction" value="0" /> Up</label>
1439 <label><input type="radio" name="direction" value="1" checked="checked" /> Down</label>
1440 </div>
1441 <div class="right">
1442 <input type="submit" name="submit" value="Find" class="action_button" />
1443 <input type="button" name="replace" value="Replace" class="action_button" />
1444 <input type="button" name="replace_all" value="Replace All" class="action_button" />
1445 <input type="button" name="cancel" value="Cancel" class="action_button" />
1446 </div>
1447 </form>
1448 <?php if (false) : ?>
1449 <form id="find-func">
1450 <label class="left"> Function<input type="search" name="find" /></label>
1451 <div class="right">
1452 <input type="submit" name="submit" value="Find Function" class="action_button" />
1453 </div>
1454 </form>
1455 <?php endif; ?>
1456 </div>
1457 <div id="editor_goto_dialog" title="Go to..." style="padding: 0px; display: none;"></div>
1458 <?php
1459 }
1460 }
1461
1462 $wpide = new wpide();
1463
1464 endif; // class_exists check
1465