Ticket #36638: 36638.3.patch
File 36638.3.patch, 19.7 KB (added by , 9 years ago) |
---|
-
src/wp-admin/admin-ajax.php
64 64 'parse-media-shortcode', 'destroy-sessions', 'install-plugin', 'update-plugin', 'press-this-save-post', 65 65 'press-this-add-category', 'crop-image', 'generate-password', 'save-wporg-username', 'delete-plugin', 66 66 'search-plugins', 'search-install-plugins', 'activate-plugin', 'update-theme', 'delete-theme', 67 'install-theme', 67 'install-theme', 'test_url', 68 68 ); 69 69 70 70 // Deprecated -
src/wp-admin/includes/ajax-actions.php
3832 3832 3833 3833 wp_send_json_success( $status ); 3834 3834 } 3835 3836 /** 3837 * Ajax handler for testing if an URL exists. Used in the editor. 3838 * 3839 * @since 4.6.0 3840 */ 3841 function wp_ajax_test_url() { 3842 if ( ! current_user_can( 'edit_posts' ) || ! wp_verify_nonce( $_POST['nonce'], 'wp-test-url' ) ) { 3843 wp_send_json_error(); 3844 } 3845 3846 $href = esc_url_raw( $_POST['href'] ); 3847 3848 // Relative URL 3849 if ( strpos( $href, '//' ) !== 0 && in_array( $href[0], array( '/', '#', '?' ), true ) ) { 3850 $href = get_bloginfo( 'url' ) . $href; 3851 } 3852 3853 $response = wp_safe_remote_get( $href, array( 3854 'timeout' => 15, 3855 // Use an explicit user-agent 3856 'user-agent' => 'WordPress URL Test', 3857 ) ); 3858 3859 $message = null; 3860 3861 if ( is_wp_error( $response ) ) { 3862 $error = $response->get_error_message(); 3863 3864 if ( strpos( $message, 'resolve host' ) !== false ) { 3865 $message = array( 'error' => __( 'Invalid host name.' ) ); 3866 } 3867 3868 wp_send_json_error( $message ); 3869 } 3870 3871 if ( wp_remote_retrieve_response_code( $response ) === 404 ) { 3872 wp_send_json_error( array( 'error' => __( 'Not found, HTTP error 404.' ) ) ); 3873 } 3874 3875 wp_send_json_success(); 3876 } -
src/wp-includes/class-wp-editor.php
1063 1063 'Ctrl + letter:' => __( 'Ctrl + letter:' ), 1064 1064 'Letter' => __( 'Letter' ), 1065 1065 'Action' => __( 'Action' ), 1066 'Invalid host name.' => __( 'Invalid host name.' ), 1066 1067 'To move focus to other buttons use Tab or the arrow keys. To return focus to the editor press Escape or use one of the buttons.' => 1067 1068 __( 'To move focus to other buttons use Tab or the arrow keys. To return focus to the editor press Escape or use one of the buttons.' ), 1068 1069 'When starting a new paragraph with one of these formatting shortcuts followed by a space, the formatting will be applied automatically. Press Backspace or Escape to undo.' => … … 1283 1284 </script> 1284 1285 <?php 1285 1286 1286 if ( in_array( 'wplink', self::$plugins, true ) || in_array( 'link', self::$qt_buttons, true ) ) 1287 $has_wplink = in_array( 'wplink', self::$plugins, true ); 1288 1289 if ( $has_wplink ) { 1290 echo '<input type="hidden" id="_wplink_urltest_nonce" value="' . wp_create_nonce( 'wp-test-url' ) . '" />'; 1291 } 1292 1293 if ( $has_wplink || in_array( 'link', self::$qt_buttons, true ) ) { 1287 1294 self::wp_link_dialog(); 1295 } 1288 1296 1289 1297 /** 1290 1298 * Fires after any core TinyMCE editor instances are created. -
src/wp-includes/css/editor.css
1757 1757 cursor: pointer; 1758 1758 } 1759 1759 1760 div.wp-link-preview a.wplink-url-error { 1761 color: #dc3232; 1762 } 1763 1760 1764 div.wp-link-input { 1761 1765 float: left; 1762 1766 margin: 2px; -
src/wp-includes/js/tinymce/plugins/wplink/plugin.js
93 93 var doingUndoRedo; 94 94 var doingUndoRedoTimer; 95 95 var $ = window.jQuery; 96 var urlErrors = {}; 96 97 97 98 function getSelectedLink() { 98 99 var href, html, … … 131 132 } 132 133 133 134 function removePlaceholderStrings( content, dataAttr ) { 134 if ( dataAttr ) { 135 content = content.replace( / data-wplink-edit="true"/g, '' ); 135 return content.replace( /(<a [^>]+>)([\s\S]*?)<\/a>/g, function( all, tag, text ) { 136 if ( tag.indexOf( ' href="_wp_link_placeholder"' ) > -1 ) { 137 return text; 138 } 139 140 if ( dataAttr ) { 141 tag = tag.replace( / data-wplink-edit="true"/g, '' ); 142 } 143 144 tag = tag.replace( / data-wplink-url-error="true"/g, '' ); 145 146 return tag + text + '</a>'; 147 }); 148 } 149 150 function checkLink( node ) { 151 var $link = editor.$( node ); 152 var href = $link.attr( 'href' ); 153 154 if ( ! href || typeof $ === 'undefined' ) { 155 return; 136 156 } 137 157 138 return content.replace( /<a [^>]*?href="_wp_link_placeholder"[^>]*>([\s\S]+)<\/a>/g, '$1' ); 158 // Early check 159 if ( /^http/i.test( href ) && ! /\.[a-z]{2,63}(\/|$)/i.test( href ) ) { 160 urlErrors[href] = tinymce.translate( 'Invalid host name.' ); 161 } 162 163 if ( urlErrors.hasOwnProperty( href ) ) { 164 $link.attr( 'data-wplink-url-error', 'true' ); 165 return; 166 } else { 167 $link.removeAttr( 'data-wplink-url-error' ); 168 } 169 170 $.post( 171 window.ajaxurl, { 172 action: 'test_url', 173 nonce: $( '#_wplink_urltest_nonce' ).val(), 174 href: href 175 }, 176 'json' 177 ).done( function( response ) { 178 if ( response.success ) { 179 return; 180 } 181 182 if ( response.data && response.data.error ) { 183 urlErrors[href] = response.data.error; 184 $link.attr( 'data-wplink-url-error', 'true' ); 185 186 if ( toolbar && toolbar.visible() ) { 187 toolbar.$el.find( '.wp-link-preview a' ).addClass( 'wplink-url-error' ).attr( 'title', editor.dom.encode( response.data.error ) ); 188 } 189 } 190 }); 139 191 } 140 192 141 193 editor.on( 'preinit', function() { … … 231 283 if ( ! tinymce.trim( linkNode.innerHTML ) ) { 232 284 editor.$( linkNode ).text( text || href ); 233 285 } 286 287 checkLink( linkNode ); 234 288 } 235 289 236 290 inputInstance.reset(); … … 473 527 474 528 editor.on( 'wptoolbar', function( event ) { 475 529 var linkNode = editor.dom.getParent( event.element, 'a' ), 476 $linkNode, href, edit ;530 $linkNode, href, edit, title; 477 531 478 532 if ( typeof window.wpLink !== 'undefined' && window.wpLink.modalOpen ) { 479 533 editToolbar.tempHide = true; … … 498 552 previewInstance.setURL( href ); 499 553 event.element = linkNode; 500 554 event.toolbar = toolbar; 555 title = urlErrors.hasOwnProperty( href ) ? editor.dom.encode( urlErrors[ href ] ) : null; 556 557 if ( $linkNode.attr( 'data-wplink-url-error' ) === 'true' ) { 558 toolbar.$el.find( '.wp-link-preview a' ).addClass( 'wplink-url-error' ).attr( 'title', title ); 559 } else { 560 toolbar.$el.find( '.wp-link-preview a' ).removeClass( 'wplink-url-error' ).attr( 'title', null ); 561 } 501 562 } 502 563 } 503 564 } ); … … 555 616 close: function() { 556 617 editToolbar.tempHide = false; 557 618 editor.execCommand( 'wp_link_cancel' ); 558 } 619 }, 620 checkLink: checkLink 559 621 }; 560 622 } ); 561 623 } )( window.tinymce ); -
src/wp-includes/js/tinymce/skins/wordpress/wp-content.css
205 205 visibility: hidden; 206 206 } 207 207 208 a[data-wplink-url-error], 209 a[data-wplink-url-error]:hover, 210 a[data-wplink-url-error]:focus { 211 outline: 2px dotted #dc3232; 212 position: relative; 213 } 214 215 a[data-wplink-url-error]:before { 216 content: ''; 217 display: block; 218 position: absolute; 219 top: -2px; 220 left: -2px; 221 right: -2px; 222 bottom: -2px; 223 outline: 2px dotted #fff; 224 } 225 208 226 /** 209 227 * WP Views 210 228 */ -
src/wp-includes/js/wplink.js
434 434 editor.focus(); 435 435 editor.nodeChanged(); 436 436 437 if ( link && editor.plugins.wplink ) { 438 editor.plugins.wplink.checkLink( link ); 439 } 440 437 441 // Audible confirmation message when a link has been inserted in the Editor. 438 442 wp.a11y.speak( wpLinkL10n.linkInserted ); 439 443 }, -
tests/phpunit/tests/term/query.php
3 3 /** 4 4 * @group taxonomy 5 5 */ 6 class Tests_Tax_Query extends WP_UnitTestCase { 7 protected $q; 8 9 public function setUp() { 10 parent::setUp(); 11 unset( $this->q ); 12 $this->q = new WP_Query(); 13 } 14 15 public function test_construct_with_relation_default() { 16 $tq = new WP_Tax_Query( array() ); 17 $this->assertSame( 'AND', $tq->relation ); 18 } 19 20 public function test_construct_with_relation_or_lowercase() { 21 $tq = new WP_Tax_Query( array( 22 'relation' => 'or', 23 ) ); 24 $this->assertSame( 'OR', $tq->relation ); 25 } 26 27 public function test_construct_with_relation_or_uppercase() { 28 $tq = new WP_Tax_Query( array( 29 'relation' => 'OR', 30 ) ); 31 $this->assertSame( 'OR', $tq->relation ); 32 } 33 34 public function test_construct_with_relation_other() { 35 $tq = new WP_Tax_Query( array( 36 'relation' => 'foo', 37 ) ); 38 $this->assertSame( 'AND', $tq->relation ); 39 } 40 41 public function test_construct_fill_missing_query_params() { 42 $tq = new WP_Tax_Query( array( 43 array(), 44 ) ); 45 46 $expected = array( 47 'taxonomy' => '', 48 'terms' => array(), 49 'include_children' => true, 50 'field' => 'term_id', 51 'operator' => 'IN', 52 ); 53 54 $this->assertEquals( $expected, $tq->queries[0] ); 55 } 56 57 public function test_construct_fill_missing_query_params_merge_with_passed_values() { 58 $tq = new WP_Tax_Query( array( 59 array( 60 'taxonomy' => 'foo', 61 'include_children' => false, 62 'foo' => 'bar', 63 ), 64 ) ); 65 66 $expected = array( 67 'taxonomy' => 'foo', 68 'terms' => array(), 69 'include_children' => false, 70 'field' => 'term_id', 71 'operator' => 'IN', 72 'foo' => 'bar', 73 ); 74 75 $this->assertEquals( $expected, $tq->queries[0] ); 76 } 77 78 public function test_construct_cast_terms_to_array() { 79 $tq = new WP_Tax_Query( array( 80 array( 81 'terms' => 'foo', 82 ), 83 ) ); 84 85 $this->assertEquals( array( 'foo', ), $tq->queries[0]['terms'] ); 86 } 87 6 class Tests_Term_Query extends WP_UnitTestCase { 88 7 /** 89 * @ticket 3 01178 * @ticket 37074 90 9 */ 91 public function test_construct_empty_strings_array_members_should_be_discarded() { 92 $q = new WP_Tax_Query( array( 93 '', 94 array( 95 'taxonomy' => 'post_tag', 96 'terms' => 'foo', 97 ), 98 ) ); 99 100 $this->assertSame( 1, count( $q->queries ) ); 101 } 102 103 public function test_transform_query_terms_empty() { 104 $tq = new WP_Tax_Query( array( 105 array(), 106 ) ); 107 $query = $tq->queries[0]; 108 109 $tq->transform_query( $tq->queries[0], 'term_id' ); 110 111 $this->assertSame( $query, $tq->queries[0] ); 112 } 113 114 public function test_transform_query_field_same_as_resulting_field() { 115 $tq = new WP_Tax_Query( array( 116 array( 117 'field' => 'term_id', 118 ), 119 ) ); 120 $query = $tq->queries[0]; 121 122 $tq->transform_query( $tq->queries[0], 'term_id' ); 123 124 $this->assertSame( $query, $tq->queries[0] ); 125 } 126 127 public function test_transform_query_resulting_field_sanitized() { 128 $t1 = self::factory()->category->create( array( 'slug' => 'foo', ) ); 129 $t2 = self::factory()->category->create( array( 'slug' => 'bar', ) ); 130 $p = self::factory()->post->create(); 131 wp_set_post_categories( $p, $t1 ); 132 133 $tq1 = new WP_Tax_Query( array( 134 array( 135 'terms' => array( 'foo' ), 136 'field' => 'slug', 137 ), 138 ) ); 139 $tq1->transform_query( $tq1->queries[0], 'term_taxonomy_id' ); 140 141 $tq2 = new WP_Tax_Query( array( 142 array( 143 'terms' => array( 'foo' ), 144 'field' => 'slug', 145 ), 146 ) ); 147 $tq2->transform_query( $tq2->queries[0], 'TERM_ ta%xonomy_id' ); 148 149 $this->assertSame( $tq1->queries[0], $tq2->queries[0] ); 150 } 151 152 public function test_transform_query_field_slug() { 153 $t1 = self::factory()->category->create( array( 'slug' => 'foo', ) ); 154 $p = self::factory()->post->create(); 155 $tt_ids = wp_set_post_categories( $p, $t1 ); 156 157 $tq = new WP_Tax_Query( array( 158 array( 159 'taxonomy' => 'category', 160 'terms' => array( 'foo' ), 161 'field' => 'slug', 162 ), 163 ) ); 164 $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); 165 166 $this->assertSame( $tt_ids, $tq->queries[0]['terms'] ); 167 $this->assertSame( 'term_taxonomy_id', $tq->queries[0]['field'] ); 168 } 169 170 public function test_transform_query_field_name() { 171 $t1 = self::factory()->category->create( array( 'slug' => 'foo', 'name' => 'Foo', ) ); 172 $p = self::factory()->post->create(); 173 $tt_ids = wp_set_post_categories( $p, $t1 ); 174 175 $tq = new WP_Tax_Query( array( 176 array( 177 'taxonomy' => 'category', 178 'terms' => array( 'Foo' ), 179 'field' => 'name', 180 ), 181 ) ); 182 $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); 183 184 $this->assertSame( $tt_ids, $tq->queries[0]['terms'] ); 185 $this->assertSame( 'term_taxonomy_id', $tq->queries[0]['field'] ); 186 } 187 188 public function test_transform_query_field_term_taxonomy_id() { 189 $t1 = self::factory()->category->create( array( 'slug' => 'foo', 'name' => 'Foo', ) ); 190 $p = self::factory()->post->create(); 191 $tt_ids = wp_set_post_categories( $p, $t1 ); 192 193 $tq = new WP_Tax_Query( array( 194 array( 195 'taxonomy' => 'category', 196 'terms' => $tt_ids, 197 'field' => 'term_taxonomy_id', 198 ), 199 ) ); 200 $tq->transform_query( $tq->queries[0], 'term_id' ); 201 202 $this->assertEquals( array( $t1 ), $tq->queries[0]['terms'] ); 203 $this->assertSame( 'term_id', $tq->queries[0]['field'] ); 204 } 205 206 public function test_transform_query_field_term_taxonomy_default() { 207 $t1 = self::factory()->category->create( array( 'slug' => 'foo', 'name' => 'Foo', ) ); 208 $p = self::factory()->post->create(); 209 $tt_ids = wp_set_post_categories( $p, $t1 ); 210 211 $tq = new WP_Tax_Query( array( 212 array( 213 'taxonomy' => 'category', 214 'terms' => array( $t1 ), 215 'field' => 'foo', // Anything defaults to term_id 216 ), 217 ) ); 218 $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); 219 220 $this->assertEquals( $tt_ids, $tq->queries[0]['terms'] ); 221 $this->assertSame( 'term_taxonomy_id', $tq->queries[0]['field'] ); 222 } 223 224 public function test_transform_query_nonexistent_terms() { 225 $tq = new WP_Tax_Query( array( 226 array( 227 'terms' => array( 'foo' ), 228 'field' => 'slug', 229 'operator' => 'AND', 230 ), 231 ) ); 232 $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); 233 234 $this->assertTrue( is_wp_error( $tq->queries[0] ) ); 235 } 236 237 /** 238 * @ticket 18105 239 */ 240 public function test_get_sql_relation_or_operator_in() { 241 register_taxonomy( 'wptests_tax', 'post' ); 242 243 $t1 = self::factory()->term->create( array( 244 'taxonomy' => 'wptests_tax', 245 ) ); 246 $t2 = self::factory()->term->create( array( 247 'taxonomy' => 'wptests_tax', 248 ) ); 249 $t3 = self::factory()->term->create( array( 250 'taxonomy' => 'wptests_tax', 251 ) ); 252 253 $tq = new WP_Tax_Query( array( 254 'relation' => 'OR', 255 array( 256 'taxonomy' => 'wptests_tax', 257 'field' => 'term_id', 258 'terms' => $t1, 259 ), 260 array( 261 'taxonomy' => 'wptests_tax', 262 'field' => 'term_id', 263 'terms' => $t2, 264 ), 265 array( 266 'taxonomy' => 'wptests_tax', 267 'field' => 'term_id', 268 'terms' => $t3, 269 ), 270 ) ); 271 10 public function test_term_taxonomy_id_single() { 272 11 global $wpdb; 273 $sql = $tq->get_sql( $wpdb->posts, 'ID' );274 275 // Only one JOIN is required with OR + IN.276 $this->assertSame( 1, substr_count( $sql['join'], 'JOIN' ) );277 278 _unregister_taxonomy( 'wptests_tax' );279 }280 12 281 /**282 * @ticket 18105283 */284 public function test_get_sql_relation_and_operator_in() {285 13 register_taxonomy( 'wptests_tax', 'post' ); 286 14 287 $t1 = self::factory()->term->create( array( 288 'taxonomy' => 'wptests_tax', 289 ) ); 290 $t2 = self::factory()->term->create( array( 291 'taxonomy' => 'wptests_tax', 292 ) ); 293 $t3 = self::factory()->term->create( array( 294 'taxonomy' => 'wptests_tax', 295 ) ); 296 297 $tq = new WP_Tax_Query( array( 298 'relation' => 'AND', 299 array( 300 'taxonomy' => 'wptests_tax', 301 'field' => 'term_id', 302 'terms' => $t1, 303 ), 304 array( 305 'taxonomy' => 'wptests_tax', 306 'field' => 'term_id', 307 'terms' => $t2, 308 ), 309 array( 310 'taxonomy' => 'wptests_tax', 311 'field' => 'term_id', 312 'terms' => $t3, 313 ), 314 ) ); 15 $terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) ); 315 16 316 global $wpdb; 317 $sql = $tq->get_sql( $wpdb->posts, 'ID' ); 17 // Manually change the term_taxonomy_id to something else. 18 $wpdb->update( 19 $wpdb->term_taxonomy, 20 array( 'term_taxonomy_id' => 12345 ), 21 array( 'term_id' => $terms[0] ) 22 ); 318 23 319 $this->assertSame( 3, substr_count( $sql['join'], 'JOIN' ) ); 24 $q = new WP_Term_Query( array( 25 'term_taxonomy_id' => 12345, 26 'fields' => 'ids', 27 'hide_empty' => false, 28 ) ); 320 29 321 _unregister_taxonomy( 'wptests_tax');30 $this->assertEqualSets( array( $terms[0] ), $q->terms ); 322 31 } 323 32 324 33 /** 325 * @ticket 1810534 * @ticket 37074 326 35 */ 327 public function test_get_sql_nested_relation_or_operator_in() { 328 register_taxonomy( 'wptests_tax', 'post' ); 329 330 $t1 = self::factory()->term->create( array( 331 'taxonomy' => 'wptests_tax', 332 ) ); 333 $t2 = self::factory()->term->create( array( 334 'taxonomy' => 'wptests_tax', 335 ) ); 336 $t3 = self::factory()->term->create( array( 337 'taxonomy' => 'wptests_tax', 338 ) ); 339 340 $tq = new WP_Tax_Query( array( 341 'relation' => 'OR', 342 array( 343 'taxonomy' => 'wptests_tax', 344 'field' => 'term_id', 345 'terms' => $t1, 346 ), 347 array( 348 'relation' => 'OR', 349 array( 350 'taxonomy' => 'wptests_tax', 351 'field' => 'term_id', 352 'terms' => $t2, 353 ), 354 array( 355 'taxonomy' => 'wptests_tax', 356 'field' => 'term_id', 357 'terms' => $t3, 358 ), 359 ), 360 ) ); 361 36 public function test_term_taxonomy_id_array() { 362 37 global $wpdb; 363 $sql = $tq->get_sql( $wpdb->posts, 'ID' );364 365 $this->assertSame( 2, substr_count( $sql['join'], 'JOIN' ) );366 38 367 _unregister_taxonomy( 'wptests_tax' );368 }369 370 /**371 * @ticket 29738372 */373 public function test_get_sql_operator_not_in_empty_terms() {374 39 register_taxonomy( 'wptests_tax', 'post' ); 375 40 376 $tq = new WP_Tax_Query( array( 377 'relation' => 'OR', 378 array( 379 'taxonomy' => 'wptests_tax', 380 'field' => 'term_id', 381 'operator' => 'NOT IN', 382 'terms' => array(), 383 ), 384 ) ); 41 $terms = self::factory()->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) ); 385 42 386 global $wpdb; 387 $expected = array( 388 'join' => '', 389 'where' => '', 43 // Manually change the term_taxonomy_id to something else. 44 $wpdb->update( 45 $wpdb->term_taxonomy, 46 array( 'term_taxonomy_id' => 12345 ), 47 array( 'term_id' => $terms[0] ) 390 48 ); 391 49 392 $this->assertSame( $expected, $tq->get_sql( $wpdb->posts, 'ID' ) ); 393 394 _unregister_taxonomy( 'wptests_tax' ); 395 } 396 397 /** 398 * @ticket 29738 399 */ 400 public function test_get_sql_operator_and_empty_terms() { 401 register_taxonomy( 'wptests_tax', 'post' ); 402 403 $tq = new WP_Tax_Query( array( 404 'relation' => 'OR', 405 array( 406 'taxonomy' => 'wptests_tax', 407 'field' => 'term_id', 408 'operator' => 'AND', 409 'terms' => array(), 410 ), 411 ) ); 412 413 global $wpdb; 414 $expected = array( 415 'join' => '', 416 'where' => '', 50 $wpdb->update( 51 $wpdb->term_taxonomy, 52 array( 'term_taxonomy_id' => 6789 ), 53 array( 'term_id' => $terms[2] ) 417 54 ); 418 55 419 $this->assertSame( $expected, $tq->get_sql( $wpdb->posts, 'ID' ) ); 56 $q = new WP_Term_Query( array( 57 'term_taxonomy_id' => array( 12345, 6789 ), 58 'fields' => 'ids', 59 'hide_empty' => false, 60 ) ); 420 61 421 _unregister_taxonomy( 'wptests_tax');62 $this->assertEqualSets( array( $terms[0], $terms[2] ), $q->terms ); 422 63 } 423 64 }