WordPress.org

Make WordPress Core


Ignore:
Timestamp:
07/24/17 22:45:55 (5 months 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.

Props westonruter, obenland, timmydcrawford for testing.
Amends [41050].
See #35243, #40951, #40907.
Fixes #41394.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/widgets/text-widget.php

    r41070 r41132  
    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.