it-swarm.com.de

Coding Challenge - JavaScript-Osterei

Wie einige von Ihnen wissen, gibt es ein Osterei im WordPress-Nachbearbeitungssystem, das eine Nachricht aus dem Film anzeigt Die Matrix wenn Sie eine bestimmte Aktion ausführen (wenn Sie nicht wissen, werde ich die Überraschung nicht verderben ... stöbern Sie in den Post-Revisionen und sehen Sie nach, ob Sie sie finden können). Ich liebe Ostereier und dieses war ein aufregender Fund, als ich darauf stieß.

Manche Leute scheinen jedoch keine wirklichen Fans zu sein. Ich habe kürzlich von einem Kunden erfahren, dass dieses Osterei in eine Panikattacke geraten ist, weil er dachte, jemand hätte seinen Blog gehackt. Sie sind ausgeflippt, haben meinen Posteingang mit panischen Nachrichten überflutet und meine Voicemail-Quote mit "Bitte helfen Sie!" Mitteilungen.

Dies lässt mich glauben, dass einige Ostereier deaktiviert werden sollten, wenn WordPress in bestimmten Situationen bereitgestellt wird - d. H. Für wartungsintensive Clients. Geben Sie meine Idee für die erste WordPress Answers-Code-Herausforderung ein.

Der Gewinner dieser Challenge erhält zusätzlich 150 Reputationspunkte !!!

Mal sehen, wie gut Sie alle im Codieren sind ... Was würden Sie als einfachste Methode empfehlen, um dieses Osterei aus WordPress zu entfernen, ohne den Kern zu hacken? Mit anderen Worten, wenn Sie nur Aktions-Hooks, Filter und benutzerdefiniertes in die Warteschlange gestelltes JavaScript verwenden, wie würden Sie das Matrix-Osterei entfernen ?

Ich wähle die "beste" Antwort am 31. Oktober basierend auf:

  • Vollständigkeit der Antwort (Beschreibung des Codes + Beispielcode + Screenshots, falls zutreffend)
  • Die Einfachheit des Codes (aber denken Sie daran, kürzer ist nicht immer besser)
  • Vollständige Beschreibungen, wie Sie den Code auf einer Client-Site installieren würden

Übrigens wird jeder, der nur die Lösung kopiert, die ich bereits auf der WP-Hackers-Mailingliste gepostet habe, automatisch disqualifiziert. Lasst die Spiele beginnen!

3
EAMann

Das folgende Plugin verbirgt die beiden störenden Radios mithilfe von jQuery dynamisch und bricht die Selbstvergleiche von Revisionen ab.

<?php
# Plugin Name: Pest Control
# Plugin URI: http://www.semiologic.com/
# Description: Kills the Easter Bunny
# Version: 1.0
# Author: Denis de Bernardy
# License: Public Domain

class PestControl {
    public static function bootstrap() {
        add_action('admin_head-revision.php', array(__CLASS__, 'mixomatosis'));
        add_action('load-revision.php', array(__CLASS__, 'plague'));
    }

    public static function mixomatosis() {
        echo <<<EOD
<script type="text/javascript">
// <![CDATA[
jQuery(document).ready(function($) {
    var mixomatosis = function() {
        var left = $(':radio[name=left]:checked').val(),
            right = $(':radio[name=right]:checked').val();
        $(':radio[name=left], :radio[name=right]').each(function() {
            var t = $(this);
            switch (true) {
                case t.attr('name') == 'left' && t.attr('value') == right:
                case t.attr('name') == 'right' && t.attr('value') == left:
                    t.css('display', 'none');
                    break;
                default:
                    t.css('display', '');
            }
        });
    };

    mixomatosis();
    $(':radio[name=left], :radio[name=right]').change(mixomatosis);
});
// ]]>
</script>
EOD;
    }

    public static function plague() {
        if ($_GET['action'] == 'diff' && $_GET['left'] == $_GET['right']) {
            wp_die("Can't compare a revision with itself.");
        }
    }
}

PestControl::bootstrap();
?>
4

Meine Lösung funktioniert auf zwei Arten: Sie deaktiviert die Auswahl von zwei identischen Revisionen durch Ändern der list-revisions Javascript-Datei , und wenn auf irgendeine Weise zwei identische Revisionen ausgewählt werden Es bietet eine echte Fehlermeldung.

Dieser Screenshot gibt Ihnen einen schnellen Überblick über die Fehlermeldung und die Wirkung des neuen Javascript. Wie Sie sehen, ist es nicht mehr möglich, dieselbe Revision zweimal auszuwählen. Wenn Sie den Effekt sehen möchten, müssen Sie entweder Javascript deaktivieren (add_action(('wp_default_scripts', ... auskommentieren) oder die URL manuell ändern.

Comparison of the old and new revision screens

Es ist als Plugin geschrieben. Bei einer Installation mit mehreren Standorten können Sie sie möglicherweise in mu-plugins ablegen und die Initialisierung von einer Datenbankkonfigurationsoption abhängen lassen. Auf diese Weise können Sie es für verschiedene Clients aktivieren oder deaktivieren.

Kommentare zu meinem Plugin-Schreibstil sind willkommen. Ich habe versucht, den Code in drei logische Blöcke zu unterteilen.

Haupt-Plugin-Datei. Diese Datei ersetzt die list-revisions Javascript-Datei durch eine "sicherere" Version, die die zweimalige Auswahl derselben Revision verhindert. Es überprüft auch die admin_action_diff-Aktion und Verknüpfungen zu einer eigenen Seite mit einer Fehlermeldung, wenn die beiden Revisionen gleich sind. Die neue Seite ist in ui-identical.php geschrieben, um Code und Layout zu trennen.

<?php
/*
Plugin Name: Myxomatosis
Plugin URI: http://www.monkeyman.be/
Description: Kill the Easter Bunny and his eggs!
Version: 1.0
Author: Jan Fabry
*/

class Myxomatosis
{
    function __construct()
    {
        add_action('admin_action_diff', array(&$this, 'checkEqualDiff'));
        add_action('wp_default_scripts', array(&$this, 'loadSafeListRevisions'), 20);
    }

    function checkEqualDiff()
    {
        global $left, $right;
        if (!array_key_exists('left', $_REQUEST) || !array_key_exists('right', $_REQUEST)) {
            return;
        }
        $left = absint($_REQUEST['left']);
        $right = absint($_REQUEST['right']);

        if (!$left || !$right || $left != $right) {
            // Nothing wrong, they are not equal
            return;
        }

        // They are equal. Set up globals so UI can be included
        // Which globals do I need here?
        global $title, $hook_suffix, $pagenow, $is_iphone, $current_screen, $user_identity, $post, $wp_locale;

        $post = get_post($left);
        if ($post->post_parent) {
            $post = get_post($post->post_parent);
        }

        require_once(plugin_dir_path(__FILE__) . 'ui-identical.php');
        exit();
    }

    function loadSafeListRevisions(&$scripts)
    {
        $scripts->remove('list-revisions');
        $scripts->add('list-revisions', plugin_dir_url(__FILE__) . 'safe-list-revisions.dev.js', null, '20101026' );
    }
}

$myxomatosis_instance = new Myxomatosis();

Datei ui-identical.php im Plugin-Verzeichnis. Dadurch wird die Seite erstellt, auf der angezeigt wird, ob die beiden Überarbeitungen identisch sind. Die Revisionsliste wird wieder angezeigt.

<?php
wp_enqueue_script('list-revisions');

$post_title = '<a href="' . get_edit_post_link() . '">' . get_the_title() . '</a>';
$h2 = sprintf( __( 'Compare Revisions of &#8220;%1$s&#8221;' ), $post_title );
$title = __( 'Revisions' );

require_once(ABSPATH . '/wp-admin/admin-header.php');
?>
<div class="wrap">
    <h2 class="long-header"><?php echo $h2; ?></h2>

    <div class="error"><p><?php _e( 'You selected two identical revisions' ); ?></p></div>

<h2><?php echo $title; ?></h2>

<?php

$args = array( 'format' => 'form-table', 'parent' => true, 'right' => $right, 'left' => $left );
if ( ! WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions') )
    $args['type'] = 'autosave';

wp_list_post_revisions( $post, $args );
?>

</div>
<?php
require_once(ABSPATH . '/wp-admin/admin-footer.php');

Datei safe-list-revisions.dev.js im Plugin-Verzeichnis. Die Logik ist in zwei Schleifen unterteilt: eine zum Lesen der aktuell aktivierten Schaltflächen und eine zum Ausblenden und Anzeigen der anderen. Dies ist möglicherweise einfacher als die ursprüngliche Version und ermöglicht einige Optimierungen in der Mitte.

(function(w) {
    var init = function() {
        var pr = document.getElementById('post-revisions'),
        var inputs = pr ? pr.getElementsByTagName('input') : [];
        if (inputs.length <= 2) {
            // Sanity check: if there is only one revision, hide nothing
            // Not that we should get here...
            return;
        }
        // For simplicity, only one click handler is registered on the whole #post-revisions table
        pr.onclick = function() {
            var i, checkCount = 0, side;
            var checkedIdx = {};
            for (i = 0; i < inputs.length; i++) {
                if (inputs[i].checked) {
                    side = inputs[i].getAttribute('name');
                    checkedIdx[side] = i;
                }
            }
            if (checkedIdx['left'] + 1 == checkedIdx['right']) {
                // The same revisions are checked
                // Move left down (or right up, if left is at the bottom)
                // There should always be at least two revisions (see sanity check above)
                if (checkedIdx['left'] + 2 < inputs.length) {
                    checkedIdx['left'] += 2;
                    inputs[checkedIdx['left']].checked = true;
                } else {
                    checkedIdx['right'] -= 2;
                    inputs[checkedIdx['right']].checked = true;
                }
            }
            if (checkedIdx['left'] < checkedIdx['right']) {
                // 'Old' is newer than 'New', so switch them
                // We sometimes get this - don't know why
                var origLeft = checkedIdx['left'];
                checkedIdx['left'] = checkedIdx['right'] - 1;
                checkedIdx['right'] = origLeft + 1;

                inputs[checkedIdx['left']].checked = true;
                inputs[checkedIdx['right']].checked = true;
            }
            // Loop again, hide what we should not see
            // 'left' buttons should be hidden until we see a checked 'right' button
            // 'right' buttons should be visible until we see a checked 'left' button
            for (i = 0; i < inputs.length; i++) {
                side = inputs[i].getAttribute('name');
                if ('left' == side) {
                    inputs[i].style.visibility = (i < checkedIdx['right'] ? 'hidden' : 'visible');
                } else if ('right' == side) {
                    inputs[i].style.visibility = (checkedIdx['left'] < i ? 'hidden' : 'visible');
                }
            }
        }
        pr.onclick();
    }
    if ( w && w.addEventListener )
        w.addEventListener('load', init, false);
    else if ( w && w.attachEvent )
        w.attachEvent('onload', init);
})(window);
4
Jan Fabry

Ich mag es sehr, wie Code überflüssig wird, um Osterei in verschleierter und unflexibler Weise einzubeziehen. :(

Ich lutsche mit dem Admin-Bereich, also ist hier mein Code, der viel mehr Fragen in meinem Kopf aufwirft als beantwortet:

add_filter( 'get_edit_post_link', 'Hijack_revision_easter_Egg' );

function Hijack_revision_easter_Egg( $input ) {

    global $action, $left, $right;


    if( 'diff' != $action )
    return $input;

    if( $left == $right ) {

    $revision = wp_get_post_revision( $left );

    if( $revision->post_parent )
        wp_redirect ( site_url( "/wp-admin/revision.php?revision={$left}&action=view" ) );
    else
        wp_redirect( str_replace( 'amp;', '', $input ) );

    exit;
    }

    return $input;
}

Keine Ahnung, warum verschlüsseltes kaufmännisches Und-Zeichen die Umleitung unterbricht ... Hatte keine Ahnung, was für einen admin_action_-Hook dies wirklich verwenden sollte, anstatt sich unordentlich in harmlosen get_edit_post_link einzumischen ...

Ich habe versucht, zur Revisionsansicht umzuleiten, aber dies scheint für die letzte Revision nicht möglich zu sein.

0
Rarst