Make WordPress Core


Ignore:
Timestamp:
07/24/2017 10:53:20 PM (7 years ago)
Author:
westonruter
Message:

Widgets: Rename Text widget's legacy mode to non-visual mode, restore boolean filter prop, and improve compatibility for widget_text filters applied in Custom HTML widget.

Merges [41132] onto 4.8 branch.
Amends [41050].
Props westonruter, obenland, timmydcrawford for testing.
See #35243, #40951, #40907.
Fixes #41394 for 4.8.1.

Location:
branches/4.8
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/4.8

  • branches/4.8/tests/phpunit/tests/widgets/text-widget.php

    r41071 r41133  
    8383            'after_widget'  => "</section>\n",
    8484        );
     85
     86        add_filter( 'widget_text_content', array( $this, 'filter_widget_text_content' ), 5, 3 );
     87        add_filter( 'widget_text', array( $this, 'filter_widget_text' ), 5, 3 );
     88
     89        // Test with filter=false, implicit legacy mode.
     90        $this->widget_text_content_args = null;
     91        ob_start();
    8592        $instance = array(
    8693            'title'  => 'Foo',
     
    8895            'filter' => false,
    8996        );
    90 
    91         add_filter( 'widget_text_content', array( $this, 'filter_widget_text_content' ), 5, 3 );
    92         add_filter( 'widget_text', array( $this, 'filter_widget_text' ), 5, 3 );
    93 
    94         // Test with filter=false.
    95         ob_start();
    9697        $widget->widget( $args, $instance );
    9798        $output = ob_get_clean();
     
    103104        $this->assertNotContains( '[filter:widget_text_content]', $output );
    104105
    105         // Test with filter=true.
    106         $instance['filter'] = true;
     106        // Test with filter=true, implicit legacy mode.
     107        $this->widget_text_content_args = null;
     108        $instance = array(
     109            'title'  => 'Foo',
     110            'text'   => $text,
     111            'filter' => true,
     112        );
    107113        ob_start();
    108114        $widget->widget( $args, $instance );
     
    118124        $this->assertNotContains( '[filter:widget_text_content]', $output );
    119125
    120         // Test with filter=content, the upgraded widget.
    121         $instance['filter'] = 'content';
     126        // Test with filter=content, the upgraded widget, in 4.8.0 only.
     127        $this->widget_text_content_args = null;
     128        $instance = array(
     129            'title'  => 'Foo',
     130            'text'   => $text,
     131            'filter' => 'content',
     132        );
     133        $expected_instance = array_merge( $instance, array(
     134            'filter' => true,
     135            'visual' => true,
     136        ) );
    122137        ob_start();
    123138        $widget->widget( $args, $instance );
     
    126141        $this->assertContains( '<br />', $output );
    127142        $this->assertCount( 3, $this->widget_text_args );
    128         $this->assertEquals( $instance['text'], $this->widget_text_args[0] );
    129         $this->assertEquals( $instance, $this->widget_text_args[1] );
     143        $this->assertEquals( $expected_instance['text'], $this->widget_text_args[0] );
     144        $this->assertEquals( $expected_instance, $this->widget_text_args[1] );
    130145        $this->assertEquals( $widget, $this->widget_text_args[2] );
    131146        $this->assertCount( 3, $this->widget_text_content_args );
    132         $this->assertEquals( $instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
    133         $this->assertEquals( $instance, $this->widget_text_content_args[1] );
     147        $this->assertEquals( $expected_instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
     148        $this->assertEquals( $expected_instance, $this->widget_text_content_args[1] );
    134149        $this->assertEquals( $widget, $this->widget_text_content_args[2] );
    135         $this->assertContains( wpautop( $instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
     150        $this->assertContains( wpautop( $expected_instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
     151
     152        // Test with filter=true&visual=true, the upgraded widget, in 4.8.1 and above.
     153        $this->widget_text_content_args = null;
     154        $instance = array(
     155            'title'  => 'Foo',
     156            'text'   => $text,
     157            'filter' => true,
     158            'visual' => true,
     159        );
     160        $expected_instance = $instance;
     161        ob_start();
     162        $widget->widget( $args, $instance );
     163        $output = ob_get_clean();
     164        $this->assertContains( '<p>', $output );
     165        $this->assertContains( '<br />', $output );
     166        $this->assertCount( 3, $this->widget_text_args );
     167        $this->assertEquals( $expected_instance['text'], $this->widget_text_args[0] );
     168        $this->assertEquals( $expected_instance, $this->widget_text_args[1] );
     169        $this->assertEquals( $widget, $this->widget_text_args[2] );
     170        $this->assertCount( 3, $this->widget_text_content_args );
     171        $this->assertEquals( $expected_instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
     172        $this->assertEquals( $expected_instance, $this->widget_text_content_args[1] );
     173        $this->assertEquals( $widget, $this->widget_text_content_args[2] );
     174        $this->assertContains( wpautop( $expected_instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
     175
     176        // Test with filter=true&visual=true, the upgraded widget, in 4.8.1 and above.
     177        $this->widget_text_content_args = null;
     178        $instance = array(
     179            'title'  => 'Foo',
     180            'text'   => $text,
     181            'filter' => true,
     182            'visual' => false,
     183        );
     184        $expected_instance = $instance;
     185        ob_start();
     186        $widget->widget( $args, $instance );
     187        $output = ob_get_clean();
     188        $this->assertContains( '<p>', $output );
     189        $this->assertContains( '<br />', $output );
     190        $this->assertCount( 3, $this->widget_text_args );
     191        $this->assertEquals( $expected_instance['text'], $this->widget_text_args[0] );
     192        $this->assertEquals( $expected_instance, $this->widget_text_args[1] );
     193        $this->assertEquals( $widget, $this->widget_text_args[2] );
     194        $this->assertNull( $this->widget_text_content_args );
     195        $this->assertContains( wpautop( $expected_instance['text'] . '[filter:widget_text]' ), $output );
     196
     197        // Test with filter=false&visual=false, the upgraded widget, in 4.8.1 and above.
     198        $this->widget_text_content_args = null;
     199        $instance = array(
     200            'title'  => 'Foo',
     201            'text'   => $text,
     202            'filter' => false,
     203            'visual' => false,
     204        );
     205        $expected_instance = $instance;
     206        ob_start();
     207        $widget->widget( $args, $instance );
     208        $output = ob_get_clean();
     209        $this->assertNotContains( '<p>', $output );
     210        $this->assertNotContains( '<br />', $output );
     211        $this->assertCount( 3, $this->widget_text_args );
     212        $this->assertEquals( $expected_instance['text'], $this->widget_text_args[0] );
     213        $this->assertEquals( $expected_instance, $this->widget_text_args[1] );
     214        $this->assertEquals( $widget, $this->widget_text_args[2] );
     215        $this->assertNull( $this->widget_text_content_args );
     216        $this->assertContains( $expected_instance['text'] . '[filter:widget_text]', $output );
    136217    }
    137218
     
    251332
    252333        $instance = array_merge( $base_instance, array(
    253             'legacy' => true,
    254         ) );
    255         $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when legacy prop is present.' );
     334            'visual' => false,
     335        ) );
     336        $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when visual=false prop is present.' );
     337
     338        $instance = array_merge( $base_instance, array(
     339            'visual' => true,
     340        ) );
     341        $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when visual=true prop is present.' );
    256342
    257343        $instance = array_merge( $base_instance, array(
    258344            'filter' => 'content',
    259345        ) );
    260         $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when filter is explicitly content.' );
     346        $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when filter is explicitly content (in WP 4.8.0 only).' );
    261347
    262348        $instance = array_merge( $base_instance, array(
     
    365451            'text' => 'Text',
    366452            'filter' => false,
    367             'legacy' => true,
     453            'visual' => false,
    368454        );
    369455        $this->assertTrue( $widget->is_legacy_instance( $instance ) );
     
    371457        $widget->form( $instance );
    372458        $form = ob_get_clean();
    373         $this->assertContains( 'class="legacy"', $form );
     459        $this->assertContains( 'class="visual" type="hidden" value=""', $form );
     460        $this->assertNotContains( 'class="visual" type="hidden" value="1"', $form );
    374461
    375462        $instance = array(
     
    382469        $widget->form( $instance );
    383470        $form = ob_get_clean();
    384         $this->assertNotContains( 'class="legacy"', $form );
     471        $this->assertContains( 'class="visual" type="hidden" value="1"', $form );
     472        $this->assertNotContains( 'class="visual" type="hidden" value=""', $form );
     473
     474        $instance = array(
     475            'title' => 'Title',
     476            'text' => 'Text',
     477            'filter' => true,
     478        );
     479        $this->assertFalse( $widget->is_legacy_instance( $instance ) );
     480        ob_start();
     481        $widget->form( $instance );
     482        $form = ob_get_clean();
     483        $this->assertContains( 'class="visual" type="hidden" value="1"', $form );
     484        $this->assertNotContains( 'class="visual" type="hidden" value=""', $form );
     485
     486        $instance = array(
     487            'title' => 'Title',
     488            'text' => 'Text',
     489            'filter' => true,
     490            'visual' => true,
     491        );
     492        $this->assertFalse( $widget->is_legacy_instance( $instance ) );
     493        ob_start();
     494        $widget->form( $instance );
     495        $form = ob_get_clean();
     496        $this->assertContains( 'class="visual" type="hidden" value="1"', $form );
     497        $this->assertNotContains( 'class="visual" type="hidden" value=""', $form );
    385498    }
    386499
     
    395508            'title' => "The\nTitle",
    396509            'text'  => "The\n\nText",
    397             'filter' => 'content',
     510            'filter' => true,
     511            'visual' => true,
    398512        );
    399513
     
    402516        ) ) );
    403517
    404         // Should return valid instance in legacy mode since filter=false and there are line breaks.
    405518        $expected = array(
    406519            'title'  => sanitize_text_field( $instance['title'] ),
    407520            'text'   => $instance['text'],
    408             'filter' => 'content',
     521            'filter' => true,
     522            'visual' => true,
    409523        );
    410524        $result = $widget->update( $instance, array() );
     
    412526        $this->assertTrue( ! empty( $expected['filter'] ), 'Expected filter prop to be truthy, to handle case where 4.8 is downgraded to 4.7.' );
    413527
    414         // Make sure KSES is applying as expected.
    415528        add_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ), 10, 2 );
    416529        $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     
    418531        $expected['text'] = $instance['text'];
    419532        $result = $widget->update( $instance, array() );
    420         $this->assertEquals( $expected, $result );
     533        $this->assertEquals( $expected, $result, 'KSES should apply as expected.' );
    421534        remove_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ) );
    422535
     
    426539        $expected['text'] = wp_kses_post( $instance['text'] );
    427540        $result = $widget->update( $instance, array() );
    428         $this->assertEquals( $expected, $result );
     541        $this->assertEquals( $expected, $result, 'KSES should not apply since user can unfiltered_html.' );
    429542        remove_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10 );
    430543    }
     
    438551        $widget = new WP_Widget_Text();
    439552
    440         // Updating a widget with explicit filter=true persists with legacy mode.
     553        // --
    441554        $instance = array(
    442555            'title' => 'Legacy',
    443556            'text' => 'Text',
    444             'filter' => true,
    445         );
    446         $result = $widget->update( $instance, array() );
    447         $expected = array_merge( $instance, array(
    448             'legacy' => true,
    449             'filter' => true,
    450         ) );
    451         $this->assertEquals( $expected, $result );
    452 
    453         // Updating a widget with explicit filter=false persists with legacy mode.
    454         $instance['filter'] = false;
    455         $result = $widget->update( $instance, array() );
    456         $expected = array_merge( $instance, array(
    457             'legacy' => true,
    458             'filter' => false,
    459         ) );
    460         $this->assertEquals( $expected, $result );
    461 
    462         // Updating a widget in legacy form results in filter=false when checkbox not checked.
    463         $instance['filter'] = true;
    464         $result = $widget->update( $instance, array() );
    465         $expected = array_merge( $instance, array(
    466             'legacy' => true,
    467             'filter' => true,
    468         ) );
    469         $this->assertEquals( $expected, $result );
    470 
    471         // Updating a widget that previously had legacy form results in filter persisting.
    472         unset( $instance['legacy'] );
    473         $instance['filter'] = true;
    474         $result = $widget->update( $instance, array(
    475             'legacy' => true,
    476         ) );
    477         $expected = array_merge( $instance, array(
    478             'legacy' => true,
    479             'filter' => true,
    480         ) );
    481         $this->assertEquals( $expected, $result );
     557            'filter' => false,
     558        );
     559        $result = $widget->update( $instance, array() );
     560        $this->assertEquals( $instance, $result, 'Updating a widget without visual prop and explicit filter=false leaves visual prop absent' );
     561
     562        // --
     563        $instance = array(
     564            'title' => 'Legacy',
     565            'text' => 'Text',
     566            'filter' => true,
     567        );
     568        $result = $widget->update( $instance, array() );
     569        $this->assertEquals( $instance, $result, 'Updating a widget without visual prop and explicit filter=true leaves legacy prop absent.' );
     570
     571        // --
     572        $instance = array(
     573            'title' => 'Legacy',
     574            'text' => 'Text',
     575            'visual' => true,
     576        );
     577        $old_instance = array_merge( $instance, array(
     578            'filter' => false,
     579        ) );
     580        $expected = array_merge( $instance, array(
     581            'filter' => true,
     582        ) );
     583        $result = $widget->update( $instance, $old_instance );
     584        $this->assertEquals( $expected, $result, 'Updating a pre-existing widget with visual mode forces filter to be true.' );
     585
     586        // --
     587        $instance = array(
     588            'title' => 'Legacy',
     589            'text' => 'Text',
     590            'filter' => true,
     591        );
     592        $old_instance = array_merge( $instance, array(
     593            'visual' => true,
     594        ) );
     595        $result = $widget->update( $instance, $old_instance );
     596        $expected = array_merge( $instance, array(
     597            'visual' => true,
     598        ) );
     599        $this->assertEquals( $expected, $result, 'Updating a pre-existing visual widget retains visual mode when updated.' );
     600
     601        // --
     602        $instance = array(
     603            'title' => 'Legacy',
     604            'text' => 'Text',
     605        );
     606        $old_instance = array_merge( $instance, array(
     607            'visual' => true,
     608        ) );
     609        $result = $widget->update( $instance, $old_instance );
     610        $expected = array_merge( $instance, array(
     611            'visual' => true,
     612            'filter' => true,
     613        ) );
     614        $this->assertEquals( $expected, $result, 'Updating a pre-existing visual widget retains visual=true and supplies missing filter=true.' );
     615
     616        // --
     617        $instance = array(
     618            'title' => 'Legacy',
     619            'text' => 'Text',
     620            'visual' => true,
     621        );
     622        $expected = array_merge( $instance, array(
     623            'filter' => true,
     624        ) );
     625        $result = $widget->update( $instance, array() );
     626        $this->assertEquals( $expected, $result, 'Updating a widget with explicit visual=true and absent filter prop causes filter to be set to true.' );
     627
     628        // --
     629        $instance = array(
     630            'title' => 'Legacy',
     631            'text' => 'Text',
     632            'visual' => false,
     633        );
     634        $result = $widget->update( $instance, array() );
     635        $expected = array_merge( $instance, array(
     636            'filter' => false,
     637        ) );
     638        $this->assertEquals( $expected, $result, 'Updating a widget in legacy mode results in filter=false as if checkbox not checked.' );
     639
     640        // --
     641        $instance = array(
     642            'title' => 'Title',
     643            'text' => 'Text',
     644            'filter' => false,
     645        );
     646        $old_instance = array_merge( $instance, array(
     647            'visual' => false,
     648            'filter' => true,
     649        ) );
     650        $result = $widget->update( $instance, $old_instance );
     651        $expected = array_merge( $instance, array(
     652            'visual' => false,
     653            'filter' => false,
     654        ) );
     655        $this->assertEquals( $expected, $result, 'Updating a widget that previously had legacy form results in filter allowed to be false.' );
     656
     657        // --
     658        $instance = array(
     659            'title' => 'Title',
     660            'text' => 'Text',
     661            'filter' => 'content',
     662        );
     663        $result = $widget->update( $instance, array() );
     664        $expected = array_merge( $instance, array(
     665            'filter' => true,
     666            'visual' => true,
     667        ) );
     668        $this->assertEquals( $expected, $result, 'Updating a widget that had \'content\' as its filter value persists non-legacy mode. This only existed in WP 4.8.0.' );
     669
     670        // --
     671        $instance = array(
     672            'title' => 'Title',
     673            'text' => 'Text',
     674        );
     675        $old_instance = array_merge( $instance, array(
     676            'filter' => 'content',
     677        ) );
     678        $result = $widget->update( $instance, $old_instance );
     679        $expected = array_merge( $instance, array(
     680            'visual' => true,
     681            'filter' => true,
     682        ) );
     683        $this->assertEquals( $expected, $result, 'Updating a pre-existing widget with the filter=content prop in WP 4.8.0 upgrades to filter=true&visual=true.' );
     684
     685        // --
     686        $instance = array(
     687            'title' => 'Title',
     688            'text' => 'Text',
     689            'filter' => 'content',
     690        );
     691        $result = $widget->update( $instance, array() );
     692        $expected = array_merge( $instance, array(
     693            'filter' => true,
     694            'visual' => true,
     695        ) );
     696        $this->assertEquals( $expected, $result, 'Updating a widget with filter=content (from WP 4.8.0) upgrades to filter=true&visual=true.' );
    482697    }
    483698
Note: See TracChangeset for help on using the changeset viewer.