Writing * Deactive fixing invalidly nexted XHTML * Do NOT use this with the visual rich editor (tinyMCE) Be sure to visit the Options page as an Administrator to adjust which user groups have access to this plugin. */ //if (get_option('runPHP_use_i10n')) if (defined('WPLANG') && '' != constant('WPLANG')) load_plugin_textdomain('runPHP', 'wp-content/plugins/runPHP'); // initialization add_filter('activate_runPHP/runPHP.php', array('runPHP', 'initialize')); add_filter('deactivate_runPHP/runPHP.php', array('runPHP', 'uninstall')); add_action('profile_personal_options', array('runPHP', 'profile_options_ui')); add_action('personal_options_update', array('runPHP', 'update_user_options')); // UI add_filter('edit_form_advanced', array('runPHP', 'InsertPostUI')); add_filter('edit_page_form', array('runPHP', 'InsertPostUI')); add_filter('admin_head', array('runPHP', 'InjectJSToMoveUI')); add_action('admin_menu', array('runPHP', 'AddOptionsSubmenu')); // Saving changes add_filter('edit_post', array('runPHP', 'UpdateEvaldState')); add_filter('publish_post', array('runPHP', 'UpdateEvaldState')); add_filter('save_post', array('runPHP', 'UpdateEvaldState')); //add_filter('save_post', array('runPHP', 'AdjustPHPCodeVisibility')); // Functionality add_filter('wp_head', array('runPHP', 'DetermineAllEvaldPosts')); add_action('rss_head', array('runPHP', 'DetermineAllEvaldPosts')); add_action('rss2_head', array('runPHP', 'DetermineAllEvaldPosts')); add_action('atom_head', array('runPHP', 'DetermineAllEvaldPosts')); add_action('rdf_header', array('runPHP', 'DetermineAllEvaldPosts')); add_filter('the_content', array('runPHP', 'EvalContent'), 1); add_filter('the_content_rss', array('runPHP', 'EvalContent'), 1); add_filter('the_excerpt_rss', array('runPHP', 'EvalContent'), 1); //add_filter('format_to_edit', array('runPHP', 'StripPHPCode')); $rphp_all_evald_posts = array(); define('rphp_metakey', 'runphp'); /** * runPHP Plugin Filter Class * * All functions are static. * Only instance data used are the two items above. */ class runPHP { // set up default settings for this plugin function initialize() { global $wp_roles; $curRoles = $wp_roles->get_names(); foreach ($curRoles as $role => $roleName) { // Bug fix: Can't chain $wp_roles->get_role()->add_cap() // because that only works in PHP5, not 4 $roleObj = $wp_roles->get_role($role); if ('administrator' == $role) $roleObj->add_cap('can_runPHP', true); else $roleObj->add_cap('can_runPHP', false); } } function uninstall() { global $wp_roles; $curRoles = $wp_roles->get_names(); foreach ($curRoles as $role => $roleName) { $roleObj = $wp_roles->get_role($role); $roleObj->remove_cap('can_runPHP'); } } /* DetermineAllEvaldPosts() Mark which posts should be eval()'d for the current page. Instead of running runphp_eval_html() on the contents of *every* post we do it only on those posts marked for it. This avoids the cost of the preg_replace_callback() function. The contents of this function could be placed in any filter that is run *once* per page. (In this case, the wp_head() filter for posts.) */ function DetermineAllEvaldPosts() { global $wpdb, $rphp_all_evald_posts; $qry = "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.Post_ID AND meta_key = '" . rphp_metakey . "' AND meta_value = '1'"; $rphp_all_evald_posts = $wpdb->get_col($qry); return; } /** * InsertPostUI() * * Writes the little checkbox to the browser which allows a user to select * whether PHP code is run for this post or page. * * When called: when an Advanced Post Edit or New Page Form is being * displayed in the admin menu. * Only written if the user has permission to modify runPHP status. */ function InsertPostUI() { global $wpdb; if (!runPHP::hasPermission()) return; else { if (isset($_REQUEST['post'])) { $isEvald = runPHP::IsPostEvald($_REQUEST['post']); $checked = ('1' == $isEvald) ? ' checked="checked" ' : ''; } ?>

runPHP

// '; } } /** * UpdateEvaldState($id) * * Update the post's meta information to reflect it's current eval()'d state. * When called: every time a post or a page is saved or published. * * Only takes action if the user hasPermission() to modify runPHP status. * * If $id is not an integer, then this function will return early and not * take any action. This was done as an additional safety measure against * SQL injection attacks. * * @param integer * Primary key of the post to update. * @thanks Benajmin Flesch of mybeNi websecurity */ function UpdateEvaldState($id) { global $wpdb; if (!runPHP::hasPermission()) return; if (!wp_verify_nonce($_POST['runphp-verify-key'], 'runphp')) return; if (!isset($id)) $id = $_REQUEST['post_ID']; // sanity check - id should _always_ be a number // todo: notify site owner? if (!is_numeric($id)) { die ("error: id is $id"); $id = 0; return; } if (isset($_REQUEST['runphp_eval'])) { $qry = "DELETE FROM {$wpdb->postmeta} WHERE Post_ID = " . $wpdb->escape($id) . " AND meta_key = '" . rphp_metakey . "';"; $wpdb->query($qry); $qry = "INSERT INTO {$wpdb->postmeta} (Post_ID, meta_key, meta_value) VALUES (" . $wpdb->escape($id) . ", '" . rphp_metakey . "', '1');"; $wpdb->query($qry); } else { $qry = "DELETE FROM {$wpdb->postmeta} WHERE Post_ID = " . $wpdb->escape($id) . " AND meta_key = '" . rphp_metakey . "';"; $wpdb->query($qry); } } /** * Not implemented yet. * Idea in future is to help adjust whether an editor "sees" PHP code when * editing a post. */ function AdjustPHPCodeVisibility($id) { } function StripPHPCode($content) { global $post; global $rphp_all_evald_posts; if (runPHP::hasPermission()) return $content; if (runPHP::IsPostEvald($_REQUEST['post'])) { //$content = "\n

eval'ing post {$post->ID}

\n" . $content; $content = $content; return runPHP::StripPHP($content); } else return $content; } // eval() the code in this post if it is marked in our $rphp_all_evald_posts array function EvalContent($content) { global $post; global $rphp_all_evald_posts; if (is_array($rphp_all_evald_posts) && in_array($post->ID, $rphp_all_evald_posts)) { //$content = "\n

eval'ing post {$post->ID}

\n" . $content; return runPHP::EvalHtml($content); } else return $content; } function AddOptionsSubmenu() { if (!current_user_can('manage_options')) return; $minUserLevel = 1; // doesn't look like the function actually uses this // see code in admin-functions.php if (function_exists('add_options_page')) { add_options_page('runPHP', 'runPHP', $minUserLevel, basename(__FILE__), array('runphp', 'options_ui')); } } function options_ui() { include_once('runPHP_options_ui.inc.php'); } // echo the UI necessary for personal profile options function profile_options_ui() { if (!current_user_can('manage_options') && !current_user_can('can_runPHP')) return; if (current_user_can('can_runPHP')) $checked = ' checked="checked"'; else $checked = ''; echo '

'; } // Saved changes when 'Update Profile' is pressed. function update_user_options() { global $current_user; if (!isset($_POST['can_runPHP'])) $_POST['can_runPHP'] = false; $current_user->add_cap('can_runPHP', $_POST['can_runPHP']); } /** * Determine whether the current post should be eval()'d or not. * */ function IsPostEvald($postID) { global $wpdb; if (!is_numeric($postID)) { //return false; die("Error from runPHP: postID ($postID) must be an integer. Aborting."); } return $wpdb->get_var("SELECT meta_value FROM {$wpdb->postmeta} WHERE Post_ID = " . $wpdb->escape($postID) . " AND meta_key = '" . rphp_metakey . "';"); } // Returns true if the current user has the requested capability function hasPermission($perm = 'can_runPHP') { return current_user_can($perm); } /* Functions to evaluate the PHP in a bunch of HTML These come from the PHP manual: http://www.php.net/eval */ function EvalHtml($string) { return preg_replace_callback("/(<\?php|<\?|< \?php)(.*?)\?>/si", array('runPHP', 'EvalBuffer'), $string); } // Runs (evals()) a '$string' of PHP code. function EvalBuffer($string) { ob_start(); eval("$string[2];"); $ret = ob_get_contents(); ob_end_clean(); return $ret; } /* Not used yet. Plan for future version to block out PHP code from editors who don't have the minimum user level to use runPHP. */ function StripPHP($string) { return preg_replace("/(<\?php|<\?|< \?php)(.*?)\?>/si", '', $string); } } ?>