PluginProbe
WPIDE – File Manager & Code Editor / 2.6
WPIDE – File Manager & Code Editor v2.6
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.6, at wpide.php

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