1<?php 2/** 3 * MoaiEditor plugin for DokuWiki 4 */ 5# Constants 6const MOAIED_FAKE_MESSAGES = false; # Create fake messages (info, error, success, notify) to test template compatibilty 7 8//include_once('/var/www/html/zdebug/inc.php'); 9 10use dokuwiki\Extension\Plugin; 11 12if(!defined('DOKU_INC')) die(); 13 14class action_plugin_moaieditor extends DokuWiki_Action_Plugin { 15 16 // Register hook function 17 public function register(Doku_Event_Handler $controller) { 18 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'moaieditor_main'); 19 } 20 // Main function 21 public function moaieditor_main (Doku_Event &$event, $param) { 22 global $ACT, $INFO, $conf, $lang; 23 24 // Exit if not in edit mode 25 if (!in_array($ACT, ['edit'])) { 26 return; 27 } 28 // Load the JS files in 'templates/' and 'user_templates/' 29 $info = $this->getInfo(); 30 $version = str_replace('-', '', $info['date']); 31 $plugin_path = DOKU_PLUGIN.'moaieditor'; 32 $plugin_url = DOKU_BASE.'lib/plugins/moaieditor'; 33 $t = $this->scanTemplateDir ($plugin_url, $plugin_path, "templates"); 34 $u = $this->scanTemplateDir ($plugin_url, $plugin_path, "user_templates"); 35 $templates = array_merge($t, $u); 36 foreach ($templates as $template) 37 $event->data['script'][] = array( 38 'type' => 'text/javascript', 39 'charset' => 'utf-8', 40 'src' => $plugin_url.'/'.$template['folder'].'/'.$template['name'].".js?v=$version", 41 'defer' => 'defer', 42 ); 43 // Pass some data to Javascript 44 $jsinfo = array( 45 // Configuration options 46 'base_url' => $plugin_url, 47 'templates' => $templates, 48 'hide_editor_by_default' => $this->getConf('hide_editor_by_default'), 49 'editor_width_side_by_side' => $this->getConf('editor_width_side_by_side'), 50 'editor_width_top_bottom' => $this->getConf('editor_width_top_bottom'), 51 'editor_width_single_pane' => $this->getConf('editor_width_single_pane'), 52 // Docinfo 53 'docinfo' => $this->getDocinfo(), 54 // Editor intro message 55 'intromsg' => $this->getEditorIntroMessage(), 56 ); 57 $event->data['script'][] = array( 58 'type' => 'text/javascript', 59 '_data' => 'JSINFO.plugin_moaieditor = ' . json_encode($jsinfo), 60 ); 61 // Simulate template messages (for testing template compatibility) 62 if( isset($_GET['fakemsg']) || MOAIED_FAKE_MESSAGES) 63 $this->simulate_template_messages(); 64 } 65 // ─────────────────────────────────────────── 66 // Scan template dir 67 public function scanTemplateDir ($plugin_url, $plugin_path, $folder) { 68 $files = []; 69 foreach (scandir("$plugin_path/$folder") as $filename) 70 if (str_ends_with($filename, '.js')) 71 if (!str_ends_with($filename, 'default.js')) { 72 $name = pathinfo($filename, PATHINFO_FILENAME); 73 $css = Null; 74 if (file_exists("$plugin_path/$folder/$name.css")) 75 $css = "$plugin_url/$folder/$name.css"; 76 $files[] = ['name'=>$name, 'folder'=>$folder, 'css'=>$css]; 77 } 78 return $files; 79 } 80 // ─────────────────────────────────────────── 81 // Get the intro message shown by DokuWiki in editor mode (whether we show it or not will depend on user settings) 82 public function getEditorIntroMessage () { 83 # The editor intro message is rendered here: inc/Ui/Editor.php -> show() 84 # In editor mode, it can be of two types: 'editrev' or 'edit' 85 # /inc/lang/en/edit.txt "**You've loaded an old revision of the document!** If you save it, you will create a new version with this data." 86 # /inc/lang/en/editrev.txt "Edit the page and hit ''Save''. See [[wiki:syntax]] for Wiki syntax. Please edit the page only if you can **improve** it. If you want to test some things, learn to make your first steps on the [[playground:playground|playground]]." 87 global $REV; 88 global $INFO; 89 $wr = $INFO['writable'] && !$INFO['locked']; 90 if (!$wr) 91 return null; 92 $type = ($REV) ? 'editrev' : 'edit'; // intro locale text (edit, rditrev, or read) 93 $html = p_locale_xhtml($type); 94 return ['type'=>$type, 'html'=>$html]; 95 } 96 // ─────────────────────────────────────────── 97 // Get document info (mostly copied from 'tpl_pageinfo' but we want to format the data differently) 98 public function getDocinfo () { 99 global $conf, $lang, $INFO, $ID; 100 101 // Document info will not exist when creating a new page 102 if (!$INFO['exists']) 103 return null; 104 105 // Document path on disk 106 $fn = $INFO['filepath']; 107 if (!$conf['fullpath']) { 108 if ($INFO['rev']) 109 $fn = str_replace($conf['olddir'] . '/', '', $fn); 110 else 111 $fn = str_replace($conf['datadir'] . '/', '', $fn); 112 } 113 $fn = utf8_decodeFN($fn); 114 115 // Last modification time 116 $dateLocal = dformat($INFO['lastmod']); 117 $dateIso = date(DATE_ISO8601, $INFO['lastmod']); 118 119 // Edited by 120 if ($INFO['editor']) 121 $by = $lang['by'].' <bdi><b>'.editorinfo($INFO['editor']).'</b></bdi>'; 122 else 123 $by = '('.$lang['external_edit'].')'; 124 125 // Return it 126 return [ 127 'labelPath' => 'Document path on disk', 128 'labelMod' => $lang['lastmod'], 129 'path' => "<bdi><i>data/pages/</i><b>$fn</b></bdi>", 130 'time' => "<time datetime='$dateIso'><b>$dateLocal</b></time>", 131 'by' => $by 132 ]; 133 } 134 // ─────────────────────────────────────────── 135 // Function to create fake messages intended to facilitate testing of templates 136 public function simulate_template_messages () { 137 global $MSG; 138 $MSG[] = ['msg'=>'Error message (-1)', 'lvl'=>'error', 'allow'=>0, 'line'=>'', 'file'=>'']; 139 $MSG[] = ['msg'=>'Info message (0)', 'lvl'=>'info', 'allow'=>0, 'line'=>'', 'file'=>'']; 140 $MSG[] = ['msg'=>'Success message (1)', 'lvl'=>'success', 'allow'=>0, 'line'=>'', 'file'=>'']; 141 $MSG[] = ['msg'=>'Notify message (2)', 'lvl'=>'notify', 'allow'=>0, 'line'=>'', 'file'=>'']; 142 } 143 144} // End class 145