WordPress.org

Make WordPress Core

Ticket #9798: spellchecker.patch

File spellchecker.patch, 14.3 KB (added by bforchhammer, 5 years ago)
  • wp-admin/includes/admin.php

     
    3333/** WordPress Post Administration API */ 
    3434require_once(ABSPATH . 'wp-admin/includes/post.php'); 
    3535 
     36/** WordPress Spellchecking API */ 
     37require_once(ABSPATH . 'wp-admin/includes/spellchecker.php'); 
     38 
    3639/** WordPress Taxonomy Administration API */ 
    3740require_once(ABSPATH . 'wp-admin/includes/taxonomy.php'); 
    3841 
  • wp-admin/includes/class-wp-googlespell.php

     
     1<?php 
     2/** 
     3 * File contains a wordpress adapted version of TinyMCE's GoogleSpell class. 
     4 * 
     5 * @package WordPress 
     6 * @author Benedikt Forchhammer <b.forchhammer@mind2.de> 
     7 * @since       2.9.0 
     8 */ 
     9 
     10// The SpellChecking Engine that we want to extend 
     11require_once( MCE_SPELLCHECKER_DIR . "/classes/GoogleSpell.php" ); 
     12 
     13/** 
     14 * Extension of TinyMCE GoogleSpell class for Wordpress 
     15 *  
     16 * WP_GoogleSpell extends TinyMCE's GoogleSpell class. It overrides the way in which the  
     17 * http request to google is executed and uses wp_remote_post() instead of curl/fsockopen. 
     18 * 
     19 * @link http://trac.wordpress.org/ticket/9798 Request for proxy support for spellchecking 
     20 * @since       2.9.0 
     21 */ 
     22class WP_GoogleSpell extends GoogleSpell { 
     23 
     24        function &_getMatches($lang, $str) { 
     25                if (function_exists('wp_remote_post')) { 
     26                        // request url 
     27                        $url = "https://www.google.com/tbproxy/spell?lang=" . $lang . "&hl=en"; 
     28                         
     29                        // Setup XML request 
     30                        $xml = '<?xml version="1.0" encoding="utf-8" ?><spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>' . $str . '</text></spellrequest>'; 
     31                         
     32                        // set up request arguments. 
     33                        $args = array( 'body' => $xml, 'sslverify' => false ); 
     34 
     35                        // execute request and get response 
     36                        $response = wp_remote_post($url, $args); 
     37                         
     38                        if (is_wp_error($response)) { 
     39                                wp_spellcheck_rpc_error(implode("\n", $response->get_error_messages())); 
     40                        } 
     41                        else { 
     42                                // Grab and parse content 
     43                                $matches = array(); 
     44                                preg_match_all('/<c o="([^"]*)" l="([^"]*)" s="([^"]*)">([^<]*)<\/c>/', wp_remote_retrieve_body($response), $matches, PREG_SET_ORDER); 
     45                         
     46                                return $matches; 
     47                        } 
     48                } 
     49                else { 
     50                        wp_spellcheck_rpc_error('wp_remote_post() function has not been loaded.'); 
     51                } 
     52        } 
     53         
     54        /** 
     55         * Use wordpress function unhtmlentities() 
     56         * 
     57         * @see http://core.trac.wordpress.org/ticket/8689 
     58         * @see http://core.trac.wordpress.org/ticket/9805 
     59         */ 
     60        function _unhtmlentities($string) { 
     61                if (function_exists('unhtmlentities')) return unhtmlentities($string); 
     62                else return parent::_unhtmlentities($string); 
     63        } 
     64} 
     65?> 
     66 No newline at end of file 
  • wp-admin/includes/post.php

     
    12991299                'theme_advanced_buttons4' => "$mce_buttons_4", 
    13001300                'language' => "$mce_locale", 
    13011301                'spellchecker_languages' => "$mce_spellchecker_languages", 
     1302                'spellchecker_rpc_url' => get_bloginfo('url') . '/wp-admin/admin-ajax.php?action=spellcheck', 
    13021303                'theme_advanced_toolbar_location' => 'top', 
    13031304                'theme_advanced_toolbar_align' => 'left', 
    13041305                'theme_advanced_statusbar_location' => 'bottom', 
  • wp-admin/includes/spellchecker.php

     
     1<?php 
     2/** 
     3 * This File contains functions used to handle Ajax spellchecking requests. 
     4 * 
     5 * @package WordPress 
     6 * @author      Benedikt Forchhammer <b.forchhammer@mind2.de> 
     7 * @since       2.9.0 
     8 */ 
     9 
     10/** 
     11 * Allows for the tinymce SpellChecker plugin directory to be moved from the default location. 
     12 * 
     13 * @since       2.9.0 
     14 */ 
     15if ( !defined('MCE_SPELLCHECKER_DIR') ) 
     16        define( 'MCE_SPELLCHECKER_DIR', ABSPATH . WPINC . '/js/tinymce/plugins/spellchecker'); 
     17 
     18add_action('wp_ajax_spellcheck', 'wp_spellcheck_ajax'); 
     19add_filter('wp_spellcheck_engine_config','wp_spellcheck_engine_replacements'); 
     20 
     21/** 
     22 * Changes config to use WP_GoogleSpell instead of GoogleSpell. 
     23 *  
     24 * @param       array   $config         Config array for SpellChecker 
     25 * @since       2.9.0 
     26 * @return      array 
     27 */ 
     28function wp_spellcheck_engine_replacements($config) { 
     29        // replace GoogleSpell with WP_GoogleSpell 
     30        if ($config['general.engine'] == 'GoogleSpell') { 
     31                $config['general.engine'] = 'WP_GoogleSpell'; 
     32                $config['general.engine.path'] =  ABSPATH . 'wp-admin/includes/class-wp-googlespell.php'; 
     33        } 
     34        return $config; 
     35} 
     36 
     37/** 
     38 * Handle ajax request for "spellcheck" action. 
     39 * 
     40 * This function is called by the action hook "wp_ajax_spellcheck". 
     41 * 
     42 * @uses        apply_filters   wp_spellcheck_rpc_request 
     43 * @uses        do_action               wp_spellcheck_rpc_result 
     44 * @since       2.9.0 
     45 * @return      void 
     46 */ 
     47function wp_spellcheck_ajax() { 
     48 
     49        // set headers at this point so that they are set fatal error responses as well. 
     50        wp_spellcheck_rpc_response_headers(); 
     51 
     52        // get request data 
     53        $request = wp_spellcheck_rpc_get_request(); 
     54        if (is_wp_error($request)) { 
     55                wp_spellcheck_rpc_error($request->get_error_message()); 
     56        } 
     57        $request = apply_filters('wp_spellcheck_rpc_request', $request); 
     58         
     59        // execute and return spellcheck 
     60        $result = wp_spellcheck_do_spellcheck($request['method'], $request['params']); 
     61        if (is_wp_error($result)) { 
     62                wp_spellcheck_rpc_error($result->get_error_message()); 
     63        } 
     64        do_action_ref_array('wp_spellcheck_rpc_result', array( $request, &$result )); 
     65         
     66        wp_spellcheck_rpc_send_response($request['id'], $result); 
     67} 
     68 
     69/** 
     70 * Calls a method on the SpellChecking Engine and returns the result. 
     71 * 
     72 * This function calls the method specified in $request['method'] 
     73 * with the parameters specified in $request['params'] on the configured 
     74 * SpellChecker Engine. 
     75 * 
     76 * The two methods which are available by default are: 
     77 * 
     78 * <ul> 
     79 * <li><strong>checkWords<strong>: checks an array of words for misspellings and returns array of misspelled words</li> 
     80 * <li><strong>getSuggestions</strong>: retrieves a list of suggestions for a given misspelled word</li> 
     81 * </ul> 
     82 * 
     83 * @param       string  $method         name of method 
     84 * @param       array   $params         parameters 
     85 * @since       2.9.0 
     86 * @return      mixed   The spellchecking result or WP_Error object 
     87 */ 
     88function wp_spellcheck_do_spellcheck ($method, $params = array()) { 
     89        $spellchecker =& wp_spellcheck_get_engine(); 
     90         
     91        if (is_wp_error($spellchecker)) { 
     92                return $spellchecker; 
     93        } 
     94         
     95        if (!is_object($spellchecker)) { 
     96                return new WP_Error('wp-spellcheck-engine-null', __('Failed to get SpellChecker engine instance.')); 
     97        } 
     98                 
     99        if (!method_exists($spellchecker, $method)) { 
     100                // Either invalid method name or incomplete spellchecker class 
     101                return new WP_Error('wp-spellcheck-engine-method-notfound', __('Failed to call method on spellchecking engine. '));  
     102        } 
     103         
     104        if (!is_array($params)) { 
     105                $params = array($params); 
     106        } 
     107         
     108        $result = call_user_func_array(array($spellchecker, $method), $params); 
     109         
     110        return $result; 
     111} 
     112 
     113/** 
     114 * Get spellcheck request data. 
     115 * 
     116 * @since       2.9.0 
     117 * @return      mixed    
     118 */ 
     119function wp_spellcheck_rpc_get_request() { 
     120 
     121        // try to get raw data 
     122        $raw = wp_spellcheck_rpc_raw_input(); 
     123        if (empty($raw)) { 
     124                return new WP_Error("wp-spellcheck-request-empty", __("Could not get raw post data.")); 
     125        } 
     126         
     127        // try to parse data as json 
     128        $request = wp_spellcheck_json_decode($raw); 
     129         
     130        // check we have good request data 
     131        if (!is_array($request)) { 
     132                return new WP_Error("wp-spellcheck-request-malformed", __("Failed parsing request as JSON: ") . print_r($request, 1) ); 
     133        } 
     134        if (empty($request['method'])) { 
     135                return new WP_Error("wp-spellcheck-request-malformed", __("Malformed JSON: missing \"method\" parameter.")); 
     136        } 
     137        if (empty($request['params'])) { 
     138                $request['params'] = array(); 
     139        } 
     140         
     141        return $request; 
     142} 
     143 
     144/** 
     145 * Retrieves the raw request data for spellchecking request. 
     146 * 
     147 * The function tries the following sources and returns the 
     148 * first non-empty one found: 
     149 * 
     150 * <ul> 
     151 * <li>$_POST[json_data]</li> 
     152 * <li>$_GLOBALS[HTTP_RAW_POST_DATA]</li> 
     153 * <li>$HTTP_RAW_POST_DATA</li> 
     154 * <li>file_get_contents("php://input")</li> 
     155 * <li>fopen("php://input", "r");</li> 
     156 * </ul> 
     157 * 
     158 * @link        http://core.trac.wordpress.org/browser/trunk/wp-includes/js/tinymce/plugins/spellchecker/rpc.php Roughly based on respective code in this file. 
     159 * @since       2.9.0 
     160 * @return      string Raw request data (json encoded) 
     161 */ 
     162function wp_spellcheck_rpc_raw_input() { 
     163        $raw = ""; 
     164 
     165        // Try param 
     166        if (isset($_POST["json_data"])) { 
     167                $raw = $_POST["json_data"]; 
     168        } 
     169 
     170        // Try globals array 
     171        if (!$raw && isset($_GLOBALS) && isset($_GLOBALS["HTTP_RAW_POST_DATA"])) { 
     172                $raw = $_GLOBALS["HTTP_RAW_POST_DATA"]; 
     173        } 
     174 
     175        // Try globals variable 
     176        if (!$raw && isset($HTTP_RAW_POST_DATA)) { 
     177                $raw = $HTTP_RAW_POST_DATA; 
     178        } 
     179                 
     180        // Try stream 
     181        if (!$raw) { 
     182                if (!function_exists('file_get_contents')) { 
     183                        $fp = fopen("php://input", "r"); 
     184                        if ($fp) { 
     185                                $raw = ""; 
     186 
     187                                while (!feof($fp)) $raw = fread($fp, 1024); 
     188                                fclose($fp); 
     189                        } 
     190                } 
     191                else { 
     192                        $raw = "" . file_get_contents("php://input"); 
     193                } 
     194        } 
     195 
     196        return $raw; 
     197} 
     198 
     199/** 
     200 * Send the given result to client. This will stop all execution. 
     201 * 
     202 * @param       string  $id             Request id which was passed to the server in the request. 
     203 * @param       array   $result Result of the request 
     204 * @since       2.9.0 
     205 * @return      void 
     206 */ 
     207function wp_spellcheck_rpc_send_response($request_id, $result) { 
     208 
     209        // Request and response id should always be the same 
     210        $output = array( 
     211                "id" => $request_id, 
     212                "result" => $result, 
     213                "error" => null 
     214        ); 
     215         
     216        // Return JSON encoded string 
     217        echo wp_spellcheck_json_encode($output); 
     218        exit(); 
     219} 
     220 
     221/** 
     222 * Set headers for the spellcheck rpc response 
     223 * 
     224 * @uses        do_action       wp_spellcheck_rpc_headers  
     225 * @since       2.9.0 
     226 * @return      void 
     227 */ 
     228function wp_spellcheck_rpc_response_headers() { 
     229        header('Content-Type: text/plain'); 
     230        header('Content-Encoding: UTF-8'); 
     231        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 
     232        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
     233        header("Cache-Control: no-store, no-cache, must-revalidate"); 
     234        header("Cache-Control: post-check=0, pre-check=0", false); 
     235        header("Pragma: no-cache");      
     236         
     237        do_action('wp_spellcheck_rpc_headers'); 
     238} 
     239 
     240/** 
     241 * Send json encoded error message to client. This will stop all execution. 
     242 * 
     243 * Note: this is a clone of TinyMCE's throwError() function in the 
     244 * SpellChecker class (spellchecker plugin). 
     245 * 
     246 * @param       string  $msg    Message to send back to user. 
     247 * @since       2.9.0 
     248 * @return      void 
     249 */ 
     250function wp_spellcheck_rpc_error($msg) { 
     251        die('{"result":null,"id":null,"error":{"errstr":"' . addslashes($msg) . '","errfile":"","errline":null,"errcontext":"","level":"FATAL"}}'); 
     252} 
     253 
     254/** 
     255 * Get the SpellChecker Engine Object 
     256 * 
     257 * @uses        apply_filters   wp_spellcheck_engine_class 
     258 * @uses        apply_filters   wp_spellcheck_engine_path 
     259 * @since       2.9.0 
     260 * @return      SpellChecker    spell checking engine 
     261 */ 
     262function &wp_spellcheck_get_engine() { 
     263        static $spellchecker = null; 
     264         
     265        if ($spellchecker === null) { 
     266                // load base class for all spellcheckers 
     267                if ( !class_exists('SpellChecker') ) { 
     268                        require_once( MCE_SPELLCHECKER_DIR . "/classes/SpellChecker.php" ); 
     269                } 
     270                 
     271                $config = wp_spellcheck_get_engine_config(); 
     272                 
     273                // get engine class name 
     274                $engine_class = apply_filters('wp_spellcheck_engine_class', $config['general.engine']); 
     275 
     276                // try to load engine class if necessary 
     277                if ( !class_exists($engine_class) ) { 
     278 
     279                        // determine engine file path 
     280                        $engine_path = $config['general.engine.path']; 
     281                        if (empty($engine_path)) { 
     282                                $engine_path = MCE_SPELLCHECKER_DIR . "/classes/$engine_class.php"; 
     283                        } 
     284                        $engine_path = apply_filters('wp_spellcheck_engine_path', $engine_path, $engine_class); 
     285                         
     286                        if ( !file_exists($engine_path) ) { 
     287                                return new WP_Error('wp-spellcheck-engine-not-found', __('Cannot load SpellChecker Engine; class file not found: ') . $engine_path ); 
     288                        } 
     289                        require_once( $engine_path ); 
     290                         
     291                        if (!class_exists($engine_class)) { 
     292                                return new WP_Error('wp-spellcheck-engine-not-found', __('Cannot load SpellChecker Engine; class not found: ') . $engine_class ); 
     293                        } 
     294                } 
     295                 
     296                $spellchecker = new $engine_class($config); 
     297        } 
     298         
     299        return $spellchecker; 
     300} 
     301 
     302/** 
     303 * Get configuration values for the SpellChecker Engine. 
     304 * 
     305 * @uses        apply_filters   wp_spellcheck_engine_config 
     306 * @since       2.9.0 
     307 * @return      Array   array of config values 
     308 */ 
     309function wp_spellcheck_get_engine_config() { 
     310        $config = array(); 
     311        $config['general.engine'] = 'GoogleSpell'; 
     312         
     313        // load default tinymce config 
     314        require_once( MCE_SPELLCHECKER_DIR . "/config.php" ); 
     315         
     316        return apply_filters('wp_spellcheck_engine_config', $config); 
     317} 
     318 
     319/** 
     320 * Encodes a php object into json 
     321 *  
     322 * @param       mixed   the thing to encode 
     323 * @since       2.9.0 
     324 * @return      string  json string 
     325 */ 
     326function wp_spellcheck_json_encode($thing) { 
     327        $json =& wp_spellcheck_json_object(); 
     328        return $json->encode($thing); 
     329} 
     330 
     331/** 
     332 * Decodes a json string into the respective php object 
     333 *  
     334 * @param       string  json string 
     335 * @since       2.9.0 
     336 * @return      mixed   json decoded thing 
     337 */ 
     338function wp_spellcheck_json_decode($string) { 
     339        $json =& wp_spellcheck_json_object(); 
     340        return $json->decode($string); 
     341} 
     342 
     343/** 
     344 * Returns an object of the moxiecode json encoder/transcoder class. 
     345 * 
     346 * @link http://core.trac.wordpress.org/browser/trunk/wp-includes/js/tinymce/plugins/spellchecker/classes/utils/JSON.php Moxiecode JSON Class 
     347 * @since       2.9.0 
     348 * @return      Moxiecode_JSON  JSON Encoder/Transcoder Object 
     349 */ 
     350function &wp_spellcheck_json_object() { 
     351        static $json = null; 
     352        if ($json == null) { 
     353                require_once( MCE_SPELLCHECKER_DIR . "/classes/utils/JSON.php" ); 
     354                $json = new Moxiecode_JSON(); 
     355        } 
     356        return $json; 
     357} 
     358 
     359?> 
     360 No newline at end of file