2 // some code below is from:
4 * $Id: tiny_mce_gzip.php 315 2007-10-25 14:03:43Z spocke $
7 * @copyright Copyright © 2005-2006, Moxiecode Systems AB, All rights reserved.
9 * This file compresses the TinyMCE JavaScript using GZip.
12 // Discard any buffers
13 while ( @ob_end_clean() );
15 @ require('../../../wp-config.php');
17 function getFileContents($path) {
19 if ( function_exists('realpath') )
20 $path = realpath($path);
22 if ( ! $path || ! @is_file($path) )
25 if ( function_exists('file_get_contents') )
26 return @file_get_contents($path);
29 $fp = @fopen($path, 'r');
34 $content .= fgets($fp);
40 function putFileContents( $path, $content ) {
41 if ( function_exists('file_put_contents') )
42 return @file_put_contents( $path, $content );
45 $fp = @fopen( $path, 'wb' );
47 $newfile = fwrite( $fp, $content );
53 // Set up init variables
54 $https = ( isset($_SERVER['HTTPS']) && 'on' == strtolower($_SERVER['HTTPS']) ) ? true : false;
56 $baseurl = get_option('siteurl') . '/wp-includes/js/tinymce';
57 if ( $https ) $baseurl = str_replace('http://', 'https://', $baseurl);
59 $mce_css = $baseurl . '/wordpress.css';
60 $mce_css = apply_filters('mce_css', $mce_css);
61 if ( $https ) $mce_css = str_replace('http://', 'https://', $mce_css);
63 $mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1
66 The following filter allows localization scripts to change the languages displayed in the spellchecker's drop-down menu.
67 By default it uses Google's spellchecker API, but can be configured to use PSpell/ASpell if installed on the server.
68 The + sign marks the default language. More information:
69 http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker
71 $mce_spellchecker_languages = apply_filters('mce_spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv');
73 $plugins = array( 'safari', 'inlinepopups', 'autosave', 'spellchecker', 'paste', 'wordpress', 'media', 'fullscreen' );
76 The following filter takes an associative array of external plugins for TinyMCE in the form 'plugin_name' => 'url'.
77 It adds the plugin's name to TinyMCE's plugins init and the call to PluginManager to load the plugin.
78 The url should be absolute and should include the js file name to be loaded. Example:
79 array( 'myplugin' => 'http://my-site.com/wp-content/plugins/myfolder/mce_plugin.js' )
80 If the plugin uses a button, it should be added with one of the "$mce_buttons" filters.
82 $mce_external_plugins = apply_filters('mce_external_plugins', array());
85 if ( ! empty($mce_external_plugins) ) {
88 The following filter loads external language files for TinyMCE plugins.
89 It takes an associative array 'plugin_name' => 'path', where path is the
90 include path to the file. The language file should follow the same format as
91 /tinymce/langs/wp-langs.php and should define a variable $strings that
92 holds all translated strings. Example:
93 $strings = 'tinyMCE.addI18n("' . $mce_locale . '.mypluginname_dlg",{tab_general:"General", ... })';
95 $mce_external_languages = apply_filters('mce_external_languages', array());
97 $loaded_langs = array();
100 if ( ! empty($mce_external_languages) ) {
101 foreach ( $mce_external_languages as $name => $path ) {
102 if ( is_file($path) && is_readable($path) ) {
104 $ext_plugins .= $strings;
105 $loaded_langs[] = $name;
110 foreach ( $mce_external_plugins as $name => $url ) {
112 if ( $https ) $url = str_replace('http://', 'https://', $url);
114 $plugins[] = '-' . $name;
116 if ( in_array($name, $loaded_langs) ) {
117 $plugurl = dirname($url);
118 $ext_plugins .= 'tinyMCEPreInit.load_ext("' . $plugurl . '", "' . $mce_locale . '");' . "\n";
120 $ext_plugins .= 'tinymce.PluginManager.load("' . $name . '", "' . $url . '");' . "\n";
123 $plugins = implode($plugins, ',');
125 $mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', '|', 'bullist', 'numlist', 'blockquote', '|', 'justifyleft', 'justifycenter', 'justifyright', '|', 'link', 'unlink', 'image', 'wp_more', '|', 'spellchecker', 'fullscreen', 'wp_adv' ));
126 $mce_buttons = implode($mce_buttons, ',');
128 $mce_buttons_2 = apply_filters('mce_buttons_2', array('formatselect', 'underline', 'justifyfull', 'forecolor', '|', 'pastetext', 'pasteword', 'removeformat', '|', 'media', 'charmap', '|', 'outdent', 'indent', '|', 'undo', 'redo', 'wp_help' ));
129 $mce_buttons_2 = implode($mce_buttons_2, ',');
131 $mce_buttons_3 = apply_filters('mce_buttons_3', array());
132 $mce_buttons_3 = implode($mce_buttons_3, ',');
134 $mce_buttons_4 = apply_filters('mce_buttons_4', array());
135 $mce_buttons_4 = implode($mce_buttons_4, ',');
137 // TinyMCE init settings
140 'onpageload' => 'wpEditorInit',
142 'theme' => 'advanced',
143 'skin' => 'wp_theme',
144 'theme_advanced_buttons1' => "$mce_buttons",
145 'theme_advanced_buttons2' => "$mce_buttons_2",
146 'theme_advanced_buttons3' => "$mce_buttons_3",
147 'theme_advanced_buttons4' => "$mce_buttons_4",
148 'language' => "$mce_locale",
149 'spellchecker_languages' => "$mce_spellchecker_languages",
150 'theme_advanced_toolbar_location' => 'top',
151 'theme_advanced_toolbar_align' => 'left',
152 'theme_advanced_statusbar_location' => 'bottom',
153 'theme_advanced_resizing' => true,
154 'theme_advanced_resize_horizontal' => false,
155 'dialog_type' => 'modal',
156 'relative_urls' => false,
157 'remove_script_host' => false,
158 'convert_urls' => false,
159 'apply_source_formatting' => false,
160 'remove_linebreaks' => true,
161 'paste_convert_middot_lists' => true,
162 'paste_remove_spans' => true,
163 'paste_remove_styles' => true,
164 'gecko_spellcheck' => true,
165 'entities' => '38,amp,60,lt,62,gt',
166 'accessibility_focus' => false,
167 'tab_focus' => ':next',
168 'content_css' => "$mce_css",
169 'save_callback' => 'switchEditors.saveCallback',
170 'plugins' => "$plugins",
171 // pass-through the settings for compression and caching, so they can be changed with "tiny_mce_before_init"
172 'disk_cache' => true,
174 'old_cache_max' => '1' // number of cache files to keep
177 // For people who really REALLY know what they're doing with TinyMCE
178 // You can modify initArray to add, remove, change elements of the config before tinyMCE.init (changed from action to filter)
179 $initArray = apply_filters('tiny_mce_before_init', $initArray);
181 // Setting "valid_elements", "invalid_elements" and "extended_valid_elements" can be done through "tiny_mce_before_init".
182 // Best is to use the default cleanup by not specifying valid_elements, as TinyMCE contains full set of XHTML 1.0.
184 // support for deprecated actions
186 do_action('mce_options');
187 $mce_deprecated = ob_get_contents();
190 $mce_deprecated = (string) $mce_deprecated;
191 if ( strlen( $mce_deprecated ) < 10 || ! strpos( $mce_deprecated, ':' ) || ! strpos( $mce_deprecated, ',' ) )
192 $mce_deprecated = '';
194 // Settings for the gzip compression and cache
195 $disk_cache = ( ! isset($initArray['disk_cache']) || false == $initArray['disk_cache'] ) ? false : true;
196 $compress = ( ! isset($initArray['compress']) || false == $initArray['compress'] ) ? false : true;
197 $old_cache_max = ( isset($initArray['old_cache_max']) ) ? (int) $initArray['old_cache_max'] : 0;
199 $initArray['disk_cache'] = $initArray['compress'] = $initArray['old_cache_max'] = null;
200 unset( $initArray['disk_cache'], $initArray['compress'], $initArray['old_cache_max'] );
202 // Anybody still using IE5/5.5? It can't handle gzip compressed js well.
203 if ( $msie = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') ) {
204 $ie_ver = (int) substr( $_SERVER['HTTP_USER_AGENT'] , $msie + 5, 3 );
205 if ( $ie_ver && $ie_ver < 6 ) $compress = false;
208 // Cache path, this is where the .gz files will be stored
209 $cache_path = ABSPATH . 'wp-content/uploads/js_cache';
210 if ( $disk_cache && ! is_dir($cache_path) )
211 $disk_cache = wp_mkdir_p($cache_path);
214 $plugins = explode( ',', $initArray['plugins'] );
215 $theme = ( 'simple' == $initArray['theme'] ) ? 'simple' : 'advanced';
216 $language = isset($initArray['language']) ? substr( $initArray['language'], 0, 2 ) : 'en';
217 $cacheKey = $mce_options = '';
219 // Check if browser supports gzip
220 if ( $compress && isset($_SERVER['HTTP_ACCEPT_ENCODING']) ) {
221 if ( ( false !== strpos( strtolower($_SERVER['HTTP_ACCEPT_ENCODING']), 'gzip') || isset($_SERVER['---------------']) ) && function_exists('gzencode') && ! ini_get('zlib.output_compression') ) {
229 $cacheKey = apply_filters('tiny_mce_version', '20080414');
231 foreach ( $initArray as $v )
234 if ( ! empty($mce_external_plugins) ) {
235 foreach ( $mce_external_plugins as $n => $v )
239 $cacheKey = md5( $cacheKey );
240 $cache_file = $cache_path . '/tinymce_' . $cacheKey . $cache_ext;
243 $expiresOffset = 864000; // 10 days
244 header( 'Content-Type: application/x-javascript; charset=UTF-8' );
245 header( 'Vary: Accept-Encoding' ); // Handle proxies
246 header( 'Expires: ' . gmdate( "D, d M Y H:i:s", time() + $expiresOffset ) . ' GMT' );
248 // Use cached file if exists
249 if ( $disk_cache && is_file($cache_file) && is_readable($cache_file) ) {
251 $mtime = gmdate("D, d M Y H:i:s", filemtime($cache_file)) . " GMT";
253 if ( isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $mtime ) {
254 header('HTTP/1.1 304 Not Modified');
257 header("Last-Modified: " . $mtime);
258 header("Cache-Control: must-revalidate", false);
260 $content = getFileContents( $cache_file );
262 if ( '.gz' == $cache_ext )
263 header( 'Content-Encoding: gzip' );
269 foreach ( $initArray as $k => $v )
270 $mce_options .= $k . ':"' . $v . '",';
272 if ( $mce_deprecated ) $mce_options .= $mce_deprecated;
274 $mce_options = rtrim( trim($mce_options), '\n\r,' );
276 $content = 'var tinyMCEPreInit = { settings : { themes : "' . $theme . '", plugins : "' . $initArray['plugins'] . '", languages : "' . $language . '", debug : false }, base : "' . $baseurl . '", suffix : "" };';
279 $content .= getFileContents( 'tiny_mce_ext.js' );
282 $content .= getFileContents( 'tiny_mce.js' );
284 // Patch loading functions
285 $content .= 'tinyMCEPreInit.start();';
287 // Add all languages (WP)
288 include_once( dirname(__FILE__).'/langs/wp-langs.php' );
289 $content .= $strings;
292 $content .= getFileContents( 'themes/' . $theme . '/editor_template.js' );
295 foreach ( $plugins as $plugin )
296 $content .= getFileContents( 'plugins/' . $plugin . '/editor_plugin.js' );
298 // Add external plugins and init
299 $content .= $ext_plugins . 'tinyMCE.init({' . $mce_options . '});';
301 // Generate GZIP'd content
302 if ( '.gz' == $cache_ext ) {
303 header('Content-Encoding: gzip');
304 $content = gzencode( $content, 9, FORCE_GZIP );
311 if ( '' != $cacheKey && is_dir($cache_path) && is_readable($cache_path) ) {
313 $old_cache = array();
314 $handle = opendir($cache_path);
315 while ( false !== ( $file = readdir($handle) ) ) {
316 if ( $file == '.' || $file == '..' ) continue;
317 $saved = filectime("$cache_path/$file");
318 if ( strpos($file, 'tinymce_') !== false && substr($file, -3) == $cache_ext ) $old_cache["$saved"] = $file;
323 if ( 1 >= $old_cache_max ) $del_cache = $old_cache;
324 else $del_cache = array_slice( $old_cache, ($old_cache_max - 1) );
326 foreach ( $del_cache as $key )
327 @unlink("$cache_path/$key");
329 putFileContents( $cache_file, $content );