Ticket #37013: 37013.6.diff
File 37013.6.diff, 379.2 KB (added by , 7 years ago) |
---|
-
.travis.yml
diff --git a/.travis.yml b/.travis.yml index 8196d39..e6c8ec7 100644
a b cache: 4 4 apt: true 5 5 directories: 6 6 - node_modules 7 - vendor 8 - $HOME/.composer/cache 7 9 env: 8 10 global: 9 11 - WP_TRAVISCI=travis:phpunit 10 12 matrix: 11 13 include: 12 - php: 7. 014 - php: 7.1 13 15 env: WP_TRAVISCI=travis:js 14 - php: 5.2 15 - php: 5.3 16 - php: 5.4 17 - php: 5.5 16 - php: 7.1 17 - php: 7.0 18 18 - php: 5.6 19 19 - php: 5.6 20 20 env: WP_TRAVIS_OBJECT_CACHE=true 21 21 services: memcached 22 - php: hhvm 23 sudo: required 24 dist: trusty 25 group: edge 26 addons: 27 apt: 28 packages: 29 - mysql-server-5.6 30 - mysql-client-core-5.6 31 - mysql-client-5.6 32 - php: 7.0 33 - php: 7.1 22 - php: 5.5 23 - php: 5.4 24 - php: 5.3 25 - php: 5.2 34 26 - php: nightly 35 27 allow_failures: 36 - php: hhvm37 28 - php: nightly 38 29 before_install: 39 30 - | … … before_install: 43 34 sed -i "s/youremptytestdbnamehere/wordpress_tests/" wp-tests-config.php 44 35 sed -i "s/yourusernamehere/root/" wp-tests-config.php 45 36 sed -i "s/yourpasswordhere//" wp-tests-config.php 46 svn checkout https://plugins.svn.wordpress.org/wordpress-importer/t runktests/phpunit/data/plugins/wordpress-importer37 svn checkout https://plugins.svn.wordpress.org/wordpress-importer/tags/0.6.3/ tests/phpunit/data/plugins/wordpress-importer 47 38 fi 48 39 - | 49 40 if [[ "$WP_TRAVIS_OBJECT_CACHE" == "true" ]]; then 50 c url https://raw.githubusercontent.com/tollmanz/wordpress-pecl-memcached-object-cache/584392b56dc4adbe52bd2c7b86f875e23a3e5f75/object-cache.php >src/wp-content/object-cache.php41 cp tests/phpunit/includes/object-cache.php src/wp-content/object-cache.php 51 42 echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini 52 43 fi 53 44 before_script: 54 45 - | 55 # Remove Xdebug for a huge performance increase, but not from nightly or hhvm:46 # Remove Xdebug for a huge performance increase, but not from nightly: 56 47 stable='^[0-9\.]+$' 57 48 if [[ "$TRAVIS_PHP_VERSION" =~ $stable ]]; then 58 49 phpenv config-rm xdebug.ini … … before_script: 67 58 # Install the specified version of PHPUnit depending on the PHP version: 68 59 if [[ "$WP_TRAVISCI" == "travis:phpunit" ]]; then 69 60 case "$TRAVIS_PHP_VERSION" in 70 7.1|7.0| hhvm|nightly)71 echo "Using PHPUnit 5.7"72 composer global require "phpunit/phpunit= 5.7.*"61 7.1|7.0|nightly) 62 echo "Using PHPUnit 6.1" 63 composer global require "phpunit/phpunit=6.1.*" 73 64 ;; 74 65 5.6|5.5|5.4|5.3) 75 66 echo "Using PHPUnit 4.8" … … before_script: 94 85 - mysql --version 95 86 - phpenv versions 96 87 - php --version 97 - | 98 # Debug PHP extensions, but not on HHVM because the command hangs indefinitely: 99 if [[ "$TRAVIS_PHP_VERSION" != 'hhvm' ]]; then 100 php -m 101 fi 88 - php -m 102 89 - npm --version 103 90 - node --version 104 91 - which phpunit … … before_script: 107 94 - grunt --version 108 95 - git --version 109 96 - svn --version 97 - locale -a 110 98 script: grunt $WP_TRAVISCI 111 99 notifications: 112 100 slack: -
Gruntfile.js
diff --git a/Gruntfile.js b/Gruntfile.js index 80e2968..14e558f 100644
a b module.exports = function(grunt) { 426 426 phpunit: { 427 427 'default': { 428 428 cmd: 'phpunit', 429 args: ['- c', 'phpunit.xml.dist']429 args: ['--verbose', '-c', 'phpunit.xml.dist'] 430 430 }, 431 431 ajax: { 432 432 cmd: 'phpunit', 433 args: ['- c', 'phpunit.xml.dist', '--group', 'ajax']433 args: ['--verbose', '-c', 'phpunit.xml.dist', '--group', 'ajax'] 434 434 }, 435 435 multisite: { 436 436 cmd: 'phpunit', 437 args: ['- c', 'tests/phpunit/multisite.xml']437 args: ['--verbose', '-c', 'tests/phpunit/multisite.xml'] 438 438 }, 439 439 'external-http': { 440 440 cmd: 'phpunit', 441 args: ['- c', 'phpunit.xml.dist', '--group', 'external-http']441 args: ['--verbose', '-c', 'phpunit.xml.dist', '--group', 'external-http'] 442 442 }, 443 443 'restapi-jsclient': { 444 444 cmd: 'phpunit', 445 args: ['- c', 'phpunit.xml.dist', '--group', 'restapi-jsclient']445 args: ['--verbose', '-c', 'phpunit.xml.dist', '--group', 'restapi-jsclient'] 446 446 } 447 447 }, 448 448 uglify: { -
phpunit.xml.dist
diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 415ec76..0bb6491 100644
a b 2 2 bootstrap="tests/phpunit/includes/bootstrap.php" 3 3 backupGlobals="false" 4 4 colors="true" 5 beStrictAboutTestsThatDoNotTestAnything="true" 5 6 > 6 7 <testsuites> 7 8 <!-- Default test suite to run all tests --> … … 23 24 <exclude> 24 25 <group>ajax</group> 25 26 <group>ms-files</group> 27 <group>ms-required</group> 26 28 <group>external-http</group> 27 29 </exclude> 28 30 </groups> -
src/wp-admin/css/color-picker.css
diff --git a/src/wp-admin/css/color-picker.css b/src/wp-admin/css/color-picker.css index baa1d94..30dec29 100644
a b 133 133 box-shadow: 134 134 0 0 0 1px #5b9dd9, 135 135 0 0 2px 1px rgba(30, 140, 190, .8); 136 } 137 No newline at end of file 136 } 137 138 @media screen and ( max-width: 782px ) { 139 .wp-picker-container input[type="text"].wp-color-picker { 140 margin-right: 6px; 141 padding: 3px 5px; 142 } 143 } -
src/wp-admin/css/common.css
diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index d06bebe..9074743 100644
a b hr { 865 865 border-bottom: 1px solid #fafafa; 866 866 } 867 867 868 .widget-control-remove,869 .widget-control-remove:focus,870 868 .row-actions span.delete a, 871 869 .row-actions span.trash a, 872 870 .row-actions span.spam a, … … span.required, 893 891 #media-items a.delete:hover, 894 892 #media-items a.delete-permanently:hover, 895 893 #nav-menu-footer .menu-delete:hover { 896 color: # f00;894 color: #dc3232; 897 895 border: none; 898 896 } 899 897 900 .widget-control-remove:hover {901 color: #f00;902 }903 904 898 /*------------------------------------------------------------------------------ 905 899 3.0 - Actions 906 900 ------------------------------------------------------------------------------*/ … … img { 3086 3080 /* Metabox collapse arrow indicators */ 3087 3081 .js .sidebar-name .sidebar-name-arrow:before, 3088 3082 .js .meta-box-sortables .postbox .toggle-indicator:before, 3089 .bulk-action-notice .toggle-indicator:before {3090 content: "\f142"; 3083 .bulk-action-notice .toggle-indicator:before, 3084 .js .accordion-section .handlediv .sidebar-name-arrow:before { 3091 3085 display: inline-block; 3092 3086 font: normal 20px/1 dashicons; 3093 3087 speak: none; … … img { 3096 3090 text-decoration: none !important; 3097 3091 } 3098 3092 3093 /* Open state */ 3094 .js .sidebar-name .sidebar-name-arrow:before, 3095 .js .meta-box-sortables .postbox .toggle-indicator:before, 3096 .bulk-action-notice .toggle-indicator:before, 3097 .js .accordion-section.open .handlediv .sidebar-name-arrow:before { 3098 content: "\f142"; 3099 } 3100 3101 /* Closed state */ 3099 3102 .js .widgets-holder-wrap.closed .sidebar-name-arrow:before, 3100 3103 .js .meta-box-sortables .postbox.closed .handlediv .toggle-indicator:before, 3101 .bulk-action-notice .bulk-action-errors-collapsed .toggle-indicator:before { 3104 .bulk-action-notice .bulk-action-errors-collapsed .toggle-indicator:before, 3105 .js .accordion-section .handlediv .sidebar-name-arrow:before { 3102 3106 content: "\f140"; 3103 3107 } 3104 3108 3105 .js .sidebar-name .sidebar-name-arrow:before {3106 padding: 10px;3107 left: 0;3108 }3109 3110 3109 .js #widgets-left .sidebar-name .sidebar-name-arrow { 3111 3110 display: none; 3112 3111 } … … img { 3149 3148 0 0 2px 1px rgba(30, 140, 190, .8); 3150 3149 } 3151 3150 3151 .js .metabox-holder .accordion-section .accordion-section-title:after { 3152 content: none; 3153 } 3154 3155 .js .metabox-holder .accordion-section .handlediv { 3156 float: right; 3157 position: relative; 3158 top: 11px; 3159 margin-right: 11px; 3160 z-index: 2; 3161 } 3162 3163 .js .metabox-holder .accordion-section .handlediv .sidebar-name-arrow:before { 3164 width: 20px; 3165 border-radius: 50%; 3166 text-indent: -1px; /* account for the dashicon alignment */ 3167 } 3168 3169 .js .metabox-holder .accordion-section .handlediv:focus { 3170 outline: none; 3171 border: none; 3172 box-shadow: none; 3173 } 3174 3175 .js .metabox-holder .accordion-section .handlediv:focus .sidebar-name-arrow:before { 3176 box-shadow: 3177 0 0 0 1px #5b9dd9, 3178 0 0 2px 1px rgba(30, 140, 190, .8); 3179 } 3180 3152 3181 /* @todo: appears to be Press This only and overridden */ 3153 3182 #photo-add-url-div input[type="text"] { 3154 3183 width: 300px; … … img { 3244 3273 3245 3274 /* @todo: can we use a common class for these? */ 3246 3275 .nav-menus-php .item-edit:before, 3247 .widget-top a.widget-action:after,3276 .widget-top .widget-action .toggle-indicator:before, 3248 3277 .control-section .accordion-section-title:after, 3249 .accordion-section-title:after { 3278 .accordion-section-title:after, 3279 .accordion-section-arrow:after { 3250 3280 right: 0; 3251 3281 content: "\f140"; 3252 border: none;3253 background: none;3254 3282 font: normal 20px/1 dashicons; 3255 3283 speak: none; 3256 3284 display: block; 3257 padding: 0;3258 text-indent: 0;3259 text-align: center;3260 position: relative;3261 3285 -webkit-font-smoothing: antialiased; 3262 3286 -moz-osx-font-smoothing: grayscale; 3263 3287 text-decoration: none !important; 3264 3288 } 3265 3289 3290 .widget-top .widget-action .toggle-indicator:before { 3291 padding: 1px 2px 1px 0px; 3292 -webkit-border-radius: 50%; 3293 border-radius: 50%; 3294 } 3295 3266 3296 .handlediv, 3267 3297 .postbox .handlediv.button-link, 3268 3298 .item-edit, … … img { 3288 3318 color: #23282d; 3289 3319 } 3290 3320 3291 .widget-top a.widget-action:after { 3292 padding: 1px 2px 1px 0px; 3293 margin-top: 10px; 3294 margin-right: 10px; 3295 -webkit-border-radius: 50%; 3296 border-radius: 50%; 3297 } 3298 3299 .widget-top a.widget-action:focus:after { 3321 .widget-top .widget-action:focus .toggle-indicator:before { 3300 3322 -webkit-box-shadow: 3301 3323 0 0 0 1px #5b9dd9, 3302 3324 0 0 2px 1px rgba(30,140,190,.8); … … img { 3315 3337 .control-section.open .accordion-section-title:after, 3316 3338 #customize-info.open .accordion-section-title:after, 3317 3339 .nav-menus-php .menu-item-edit-active .item-edit:before, 3318 .widget.open .widget-top a.widget-action:after { 3340 .widget.open .widget-top .widget-action .toggle-indicator:before, 3341 .open .accordion-section-arrow:after { 3319 3342 content: "\f142"; 3320 3343 } 3321 3344 … … img { 3594 3617 /* @todo: evaluate - most of these were likely replaced by dashicons */ 3595 3618 .curtime #timestamp, 3596 3619 #screen-meta-links a.show-settings, 3597 .widget-top a.widget-action,3598 .widget-top a.widget-action:hover,3620 .widget-top .widget-action, 3621 .widget-top .widget-action:hover, 3599 3622 .sidebar-name-arrow, 3600 3623 .sidebar-name:hover .sidebar-name-arrow, 3601 3624 .meta-box-sortables .postbox:hover .handlediv, -
src/wp-admin/css/customize-controls.css
diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css index fbcfe64..d033b89 100644
a b p.customize-section-description { 617 617 618 618 .customize-control select { 619 619 width: 100%; 620 max-width: 300px;621 620 height: 28px; 622 621 line-height: 28px; 623 622 } … … p.customize-section-description { 744 743 745 744 .customize-control-dropdown-pages .new-content-item { 746 745 width: 100%; 747 max-width: 300px;748 746 padding: 5px 0 5px 1px; 749 747 position: relative; 750 748 } … … p.customize-section-description { 1189 1187 .customize-section-description-container + #customize-control-custom_css:last-child { 1190 1188 margin-left: -12px; 1191 1189 width: 299px; 1190 width: -webkit-calc( 100% + 24px ); 1191 width: calc( 100% + 24px ); 1192 1192 margin-bottom: -12px; 1193 1193 } 1194 1194 1195 1195 @media screen and ( max-width: 640px ) { 1196 1196 .customize-section-description-container + #customize-control-custom_css:last-child { 1197 margin-left: 0;1198 1197 margin-right: 0; 1199 width: 100%;1200 1198 } 1201 1199 .customize-section-description-container + #customize-control-custom_css:last-child textarea { 1202 1200 height: -webkit-calc( 100vh - 140px ); 1203 1201 height: calc( 100vh - 140px ); 1204 width: 100%;1205 border: solid 1px #ddd;1206 1202 } 1207 1203 } 1208 1204 -
src/wp-admin/css/customize-nav-menus.css
diff --git a/src/wp-admin/css/customize-nav-menus.css b/src/wp-admin/css/customize-nav-menus.css index c42fa54..f2186fb 100644
a b 153 153 text-align: center; 154 154 } 155 155 156 .wp-customizer .menu-item.menu-item-edit-active .item-edit .toggle-indicator: after{156 .wp-customizer .menu-item.menu-item-edit-active .item-edit .toggle-indicator:before { 157 157 content: "\f142"; 158 158 } 159 159 … … 271 271 display: inline-block; 272 272 font-size: 20px; 273 273 line-height: 1; 274 text-indent: -1px; /* account for the dashicon alignment */275 274 } 276 275 277 276 .rtl .wp-customizer .toggle-indicator { 278 277 text-indent: 1px; /* account for the dashicon alignment */ 279 278 } 280 279 281 .wp-customizer .toggle-indicator:after { 280 .wp-customizer .menu-item .item-edit .toggle-indicator:before, 281 #available-menu-items .accordion-section-title .toggle-indicator:before { 282 282 content: "\f140"; 283 display: block; 284 padding: 1px 2px 1px 0px; 283 285 speak: none; 284 vertical-align: top;285 286 -webkit-border-radius: 50%; 286 287 border-radius: 50%; 287 288 color: #72777c; … … 494 495 content: none !important; 495 496 } 496 497 497 #available-menu-items .accordion-section-title:hover .toggle-indicator: after,498 #available-menu-items .button-link:hover .toggle-indicator: after,499 #available-menu-items .button-link:focus .toggle-indicator: after{498 #available-menu-items .accordion-section-title:hover .toggle-indicator:before, 499 #available-menu-items .button-link:hover .toggle-indicator:before, 500 #available-menu-items .button-link:focus .toggle-indicator:before { 500 501 color: #23282d; 501 502 } 502 503 503 #available-menu-items .open .accordion-section-title .toggle-indicator: after{504 #available-menu-items .open .accordion-section-title .toggle-indicator:before { 504 505 content: "\f142"; 505 506 color: #23282d; 506 507 } … … li.assigned-to-menu-location .add-new-menu-item { 837 838 .wp-customizer .menu-item .submitbox .submitdelete:focus, 838 839 .customize-screen-options-toggle:focus:before, 839 840 #customize-controls .customize-info .customize-help-toggle:focus:before, 840 .wp-customizer button:focus .toggle-indicator: after,841 .wp-customizer button:focus .toggle-indicator:before, 841 842 .menu-delete:focus, 842 843 .menu-item-bar .item-delete:focus:before, 843 844 #available-menu-items .item-add:focus:before { -
src/wp-admin/css/customize-widgets.css
diff --git a/src/wp-admin/css/customize-widgets.css b/src/wp-admin/css/customize-widgets.css index 687c9f8..428c455 100644
a b 89 89 line-height: 16px; 90 90 } 91 91 92 .customize-control-widget_form.expanded a.widget-action:after{92 .customize-control-widget_form.expanded .widget-action .toggle-indicator:before { 93 93 content: "\f142"; 94 94 } 95 95 96 .customize-control-widget_form.wide-widget-control a.widget-action:after{96 .customize-control-widget_form.wide-widget-control .widget-action .toggle-indicator:before { 97 97 content: "\f139"; 98 98 } 99 99 100 .customize-control-widget_form.wide-widget-control.expanded a.widget-action:after{100 .customize-control-widget_form.wide-widget-control.expanded .widget-action .toggle-indicator:before { 101 101 content: "\f141"; 102 102 } 103 103 … … body.adding-widget #customize-preview { 438 438 .last-widget { 439 439 margin-bottom: 15px; 440 440 } 441 /* This rule reduces the widgets titles height. */ 441 442 .widget-title h3 { 442 443 padding: 13px 15px; 443 444 } 445 .widget-top .widget-action { 446 padding-bottom: 8px; 447 } 444 448 .widget-reorder-nav span { 445 449 height: 39px; 446 450 } -
src/wp-admin/css/dashboard.css
diff --git a/src/wp-admin/css/dashboard.css b/src/wp-admin/css/dashboard.css index d467f0c..98fb993 100644
a b 308 308 padding: 0; 309 309 } 310 310 311 #dashboard_primary .widget-loading, 312 #dashboard_primary .dashboard-widget-control-form { 311 #dashboard_primary .widget-loading { 313 312 padding: 12px 12px 0; 313 margin-bottom: 1em !important; /* Needs to override `.postbox .inside > p:last-child` in common.css */ 314 314 } 315 315 316 body #dashboard-widgets .postbox form .submit { 316 /* Notice when JS is off. */ 317 #dashboard_primary .inside .notice { 317 318 margin: 0; 318 319 } 319 320 320 .dashboard-widget-control-form{321 overflow: hidden;321 body #dashboard-widgets .postbox form .submit { 322 margin: 0; 322 323 } 323 324 325 /* Used only for configurable widgets. */ 324 326 .dashboard-widget-control-form p { 325 327 margin-top: 0; 326 328 } -
src/wp-admin/css/themes.css
diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index a18a89a..86fc133 100644
a b body.full-overlay-active { 1332 1332 -moz-box-sizing: border-box; 1333 1333 box-sizing: border-box; 1334 1334 position: fixed; 1335 width: 300px; 1335 min-width: 300px; 1336 max-width: 600px; 1337 width: 18%; 1336 1338 height: 100%; 1337 1339 top: 0; 1338 1340 bottom: 0; … … body.full-overlay-active { 1361 1363 margin-left: -300px; 1362 1364 } 1363 1365 1366 @media screen and (min-width: 1667px) { 1367 .wp-full-overlay.expanded { 1368 margin-left: 18%; 1369 } 1370 1371 .wp-full-overlay.collapsed .wp-full-overlay-sidebar { 1372 margin-left: -18%; 1373 } 1374 } 1375 1376 @media screen and (min-width: 3333px) { 1377 .wp-full-overlay.expanded { 1378 margin-left: 600px; 1379 } 1380 1381 .wp-full-overlay.collapsed .wp-full-overlay-sidebar { 1382 margin-left: -600px; 1383 } 1384 } 1385 1364 1386 .wp-full-overlay-sidebar:after { 1365 1387 content: ""; 1366 1388 display: block; … … body.full-overlay-active { 1520 1542 box-shadow: none !important; 1521 1543 -webkit-border-radius: 0 !important; 1522 1544 border-radius: 0 !important; 1523 z-index: -1; /* Below device buttons */1524 1545 } 1525 1546 1526 1547 .wp-core-ui .wp-full-overlay .collapse-sidebar:hover, … … body.full-overlay-active { 1616 1637 position: fixed; 1617 1638 bottom: 0; 1618 1639 left: 0; 1619 width: 299px; 1640 min-width: 299px; 1641 max-width: 599px; 1642 width: 18%; 1620 1643 height: 45px; 1621 1644 border-top: 1px solid #ddd; 1622 1645 background: #eee; 1623 1646 } 1624 1647 1625 .wp-full-overlay-footer .devices {1648 .wp-full-overlay-footer .devices-wrapper { 1626 1649 float: right; 1650 } 1651 1652 .wp-full-overlay-footer .devices { 1653 position: relative; 1627 1654 background: #eee; 1628 1655 -webkit-box-shadow: -20px 0 10px -5px #eee; 1629 1656 box-shadow: -20px 0 10px -5px #eee; -
src/wp-admin/css/widgets.css
diff --git a/src/wp-admin/css/widgets.css b/src/wp-admin/css/widgets.css index f0be076..bc794e5 100644
a b 14 14 background: #f7f7f7; 15 15 } 16 16 17 .widget-top a.widget-action, 18 .widget-top a.widget-action:hover { 19 -webkit-box-shadow: none; 20 box-shadow: none; 17 .widget-top .widget-action { 18 border: 0; 19 margin: 0; 20 padding: 10px; 21 background: none; 22 cursor: pointer; 21 23 outline: none; 22 text-decoration: none;23 24 } 24 25 25 26 .widget-title h3, … … 50 51 } 51 52 52 53 .deleting .widget-title, 53 .deleting .widget-top a.widget-action:after{54 .deleting .widget-top .widget-action .toggle-indicator:before { 54 55 color: #a0a5aa; 55 56 } 56 57 … … 91 92 box-sizing: border-box; 92 93 } 93 94 94 .sidebar-name-arrow { 95 position: absolute; 96 top: 0; 97 right: 0; 98 bottom: 0; 95 .js .sidebar-name .handlediv { 96 float: right; 97 width: 32px; 98 height: 32px; 99 padding: 0; 100 } 101 102 .js .sidebar-name .handlediv:focus { 103 box-shadow: none; 104 outline: none; 105 } 106 107 .js #widgets-left .sidebar-name .handlediv:focus .sidebar-name-arrow { 108 display: block; 109 } 110 111 .js .sidebar-name .handlediv:focus .sidebar-name-arrow:before { 112 box-shadow: 113 0 0 0 1px #5b9dd9, 114 0 0 2px 1px rgba(30, 140, 190, .8); 115 } 116 117 .js .sidebar-name .sidebar-name-arrow:before { 118 margin-top: 14px; 119 width: 20px; 120 border-radius: 50%; 121 text-indent: -1px; /* account for the dashicon alignment */ 122 } 123 124 .js .widget-liquid-left .sidebar-name .sidebar-name-arrow:before { 125 margin-top: 7px; 99 126 } 100 127 101 128 .js .sidebar-name { … … div#widgets-left .sidebar-name h3 { 156 183 margin: 0 10px 0 0; 157 184 } 158 185 159 #widgets-left .sidebar-name .sidebar-name-arrow:before {160 padding: 9px;161 }162 163 186 #widgets-left .widgets-holder-wrap, 164 187 div#widgets-left .widget-holder { 165 188 background: transparent; … … div#widgets-right .sidebar-name h3 { 249 272 padding: 15px 7px; 250 273 } 251 274 252 div#widgets-right .sidebar-name .sidebar-name-arrow:before {253 top: 2px;254 }255 256 275 div#widgets-right .widget-top { 257 276 padding: 0; 258 277 } -
src/wp-admin/customize.php
diff --git a/src/wp-admin/customize.php b/src/wp-admin/customize.php index f1e66ff..b6c1e63 100644
a b 171 171 </div> 172 172 173 173 <div id="customize-footer-actions" class="wp-full-overlay-footer"> 174 <?php $previewable_devices = $wp_customize->get_previewable_devices(); ?>175 <?php if ( ! empty( $previewable_devices ) ) : ?>176 <div class="devices">177 <?php foreach ( (array) $previewable_devices as $device => $settings ) : ?>178 <?php179 if ( empty( $settings['label'] ) ) {180 continue;181 }182 $active = ! empty( $settings['default'] );183 $class = 'preview-' . $device;184 if ( $active ) {185 $class .= ' active';186 }187 ?>188 <button type="button" class="<?php echo esc_attr( $class ); ?>" aria-pressed="<?php echo esc_attr( $active ) ?>" data-device="<?php echo esc_attr( $device ); ?>">189 <span class="screen-reader-text"><?php echo esc_html( $settings['label'] ); ?></span>190 </button>191 <?php endforeach; ?>192 </div>193 <?php endif; ?>194 174 <button type="button" class="collapse-sidebar button" aria-expanded="true" aria-label="<?php echo esc_attr( _x( 'Hide Controls', 'label for hide controls button without length constraints' ) ); ?>"> 195 175 <span class="collapse-sidebar-arrow"></span> 196 176 <span class="collapse-sidebar-label"><?php _ex( 'Hide Controls', 'short (~12 characters) label for hide controls button' ); ?></span> 197 177 </button> 178 <?php $previewable_devices = $wp_customize->get_previewable_devices(); ?> 179 <?php if ( ! empty( $previewable_devices ) ) : ?> 180 <div class="devices-wrapper"> 181 <div class="devices"> 182 <?php foreach ( (array) $previewable_devices as $device => $settings ) : ?> 183 <?php 184 if ( empty( $settings['label'] ) ) { 185 continue; 186 } 187 $active = ! empty( $settings['default'] ); 188 $class = 'preview-' . $device; 189 if ( $active ) { 190 $class .= ' active'; 191 } 192 ?> 193 <button type="button" class="<?php echo esc_attr( $class ); ?>" aria-pressed="<?php echo esc_attr( $active ) ?>" data-device="<?php echo esc_attr( $device ); ?>"> 194 <span class="screen-reader-text"><?php echo esc_html( $settings['label'] ); ?></span> 195 </button> 196 <?php endforeach; ?> 197 </div> 198 </div> 199 <?php endif; ?> 198 200 </div> 199 201 </form> 200 202 <div id="customize-preview" class="wp-full-overlay-main"></div> -
src/wp-admin/includes/ajax-actions.php
diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index 90a9dd1..3342cad 100644
a b function wp_ajax_wp_link_ajax() { 1497 1497 1498 1498 $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1; 1499 1499 1500 require(ABSPATH . WPINC . '/class-wp-editor.php'); 1500 if ( ! class_exists( '_WP_Editors', false ) ) { 1501 require( ABSPATH . WPINC . '/class-wp-editor.php' ); 1502 } 1503 1501 1504 $results = _WP_Editors::wp_link_query( $args ); 1502 1505 1503 1506 if ( ! isset( $results ) ) -
src/wp-admin/includes/dashboard.php
diff --git a/src/wp-admin/includes/dashboard.php b/src/wp-admin/includes/dashboard.php index b763d43..be0b201 100644
a b function wp_add_dashboard_widget( $widget_id, $widget_name, $callback, $control_ 191 191 * @param array $meta_box 192 192 */ 193 193 function _wp_dashboard_control_callback( $dashboard, $meta_box ) { 194 echo '<form method="post" class="dashboard-widget-control-form ">';194 echo '<form method="post" class="dashboard-widget-control-form wp-clearfix">'; 195 195 wp_dashboard_trigger_widget_control( $meta_box['id'] ); 196 196 wp_nonce_field( 'edit-dashboard-widget_' . $meta_box['id'], 'dashboard-widget-nonce' ); 197 197 echo '<input type="hidden" name="widget_id" value="' . esc_attr($meta_box['id']) . '" />'; … … function wp_dashboard_rss_output( $widget_id ) { 968 968 * @return bool False on failure. True on success. 969 969 */ 970 970 function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) { 971 $loading = '<p class="widget-loading hide-if-no-js">' . __( 'Loading…' ) . '</p>< p class="hide-if-js">' . __( 'This widget requires JavaScript.' ) . '</p>';971 $loading = '<p class="widget-loading hide-if-no-js">' . __( 'Loading…' ) . '</p><div class="hide-if-js notice notice-error inline"><p>' . __( 'This widget requires JavaScript.' ) . '</p></div>'; 972 972 $doing_ajax = wp_doing_ajax(); 973 973 974 974 if ( empty($check_urls) ) { -
src/wp-admin/includes/meta-boxes.php
diff --git a/src/wp-admin/includes/meta-boxes.php b/src/wp-admin/includes/meta-boxes.php index 23ca247..ba43c7d 100644
a b function post_submit_meta_box( $post, $args = array() ) { 50 50 <?php 51 51 $preview_link = esc_url( get_preview_post_link( $post ) ); 52 52 if ( 'publish' == $post->post_status ) { 53 $preview_button = __( 'Preview Changes' );53 $preview_button_text = __( 'Preview Changes' ); 54 54 } else { 55 $preview_button = __( 'Preview' );55 $preview_button_text = __( 'Preview' ); 56 56 } 57 58 $preview_button = sprintf( '%1$s<span class="screen-reader-text"> %2$s</span>', 59 $preview_button_text, 60 /* translators: accessibility text */ 61 __( '(link opens in a new window)' ) 62 ); 57 63 ?> 58 64 <a class="preview button" href="<?php echo $preview_link; ?>" target="wp-preview-<?php echo (int) $post->ID; ?>" id="post-preview"><?php echo $preview_button; ?></a> 59 65 <input type="hidden" name="wp-preview" id="wp-preview" value="" /> -
src/wp-admin/includes/ms.php
diff --git a/src/wp-admin/includes/ms.php b/src/wp-admin/includes/ms.php index 6a4ca9d..939d0d0 100644
a b function mu_dropdown_languages( $lang_files = array(), $current = '' ) { 785 785 function site_admin_notice() { 786 786 global $wp_db_version, $pagenow; 787 787 788 if ( ! is_super_admin() ) {788 if ( ! current_user_can( 'upgrade_network' ) ) { 789 789 return false; 790 790 } 791 791 -
src/wp-admin/includes/options.php
diff --git a/src/wp-admin/includes/options.php b/src/wp-admin/includes/options.php index 95d9964..14c175d 100644
a b function options_general_add_js() { 53 53 if ( "date_format_custom_radio" != $(this).attr("id") ) 54 54 $( "input[name='date_format_custom']" ).val( $( this ).val() ).siblings( '.example' ).text( $( this ).parent( 'label' ).children( '.format-i18n' ).text() ); 55 55 }); 56 $( "input[name='date_format_custom']").focus(function(){56 $( 'input[name="date_format_custom"]' ).on( 'click input', function() { 57 57 $( '#date_format_custom_radio' ).prop( 'checked', true ); 58 58 }); 59 59 … … function options_general_add_js() { 61 61 if ( "time_format_custom_radio" != $(this).attr("id") ) 62 62 $( "input[name='time_format_custom']" ).val( $( this ).val() ).siblings( '.example' ).text( $( this ).parent( 'label' ).children( '.format-i18n' ).text() ); 63 63 }); 64 $( "input[name='time_format_custom']").focus(function(){64 $( 'input[name="time_format_custom"]' ).on( 'click input', function() { 65 65 $( '#time_format_custom_radio' ).prop( 'checked', true ); 66 66 }); 67 67 $("input[name='date_format_custom'], input[name='time_format_custom']").change( function() { -
src/wp-admin/includes/post.php
diff --git a/src/wp-admin/includes/post.php b/src/wp-admin/includes/post.php index 1054f2b..8055a7b 100644
a b function _wp_post_thumbnail_html( $thumbnail_id = null, $post = null ) { 1448 1448 * 1449 1449 * @since 2.5.0 1450 1450 * 1451 * @param int $post_id ID of the post to check for editing 1452 * @return integer False: not locked or locked by current user. Int: user ID of user with lock. 1451 * @param int $post_id ID of the post to check for editing. 1452 * @return int|false ID of the user with lock. False if the post does not exist, post is not locked, 1453 * the user with lock does not exist, or the post is locked by current user. 1453 1454 */ 1454 1455 function wp_check_post_lock( $post_id ) { 1455 if ( ! $post = get_post( $post_id ) )1456 if ( ! $post = get_post( $post_id ) ) { 1456 1457 return false; 1458 } 1457 1459 1458 if ( ! $lock = get_post_meta( $post->ID, '_edit_lock', true ) )1460 if ( ! $lock = get_post_meta( $post->ID, '_edit_lock', true ) ) { 1459 1461 return false; 1462 } 1460 1463 1461 1464 $lock = explode( ':', $lock ); 1462 1465 $time = $lock[0]; 1463 1466 $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true ); 1464 1467 1468 if ( ! get_userdata( $user ) ) { 1469 return false; 1470 } 1471 1465 1472 /** This filter is documented in wp-admin/includes/ajax-actions.php */ 1466 1473 $time_window = apply_filters( 'wp_check_post_lock_window', 150 ); 1467 1474 1468 if ( $time && $time > time() - $time_window && $user != get_current_user_id() ) 1475 if ( $time && $time > time() - $time_window && $user != get_current_user_id() ) { 1469 1476 return $user; 1477 } 1478 1470 1479 return false; 1471 1480 } 1472 1481 … … function wp_check_post_lock( $post_id ) { 1475 1484 * 1476 1485 * @since 2.5.0 1477 1486 * 1478 * @param int $post_id ID of the post to being edited1479 * @return bool|array Returns false if the post doesn't exist of there is no current user, or1480 * an array of the lock time and the user ID.1487 * @param int $post_id ID of the post being edited. 1488 * @return array|false Array of the lock time and user ID. False if the post does not exist, or 1489 * there is no current user. 1481 1490 */ 1482 1491 function wp_set_post_lock( $post_id ) { 1483 if ( ! $post = get_post( $post_id ) )1492 if ( ! $post = get_post( $post_id ) ) { 1484 1493 return false; 1485 if ( 0 == ($user_id = get_current_user_id()) ) 1494 } 1495 1496 if ( 0 == ( $user_id = get_current_user_id() ) ) { 1486 1497 return false; 1498 } 1487 1499 1488 1500 $now = time(); 1489 1501 $lock = "$now:$user_id"; 1490 1502 1491 1503 update_post_meta( $post->ID, '_edit_lock', $lock ); 1504 1492 1505 return array( $now, $user_id ); 1493 1506 } 1494 1507 -
src/wp-admin/includes/schema.php
diff --git a/src/wp-admin/includes/schema.php b/src/wp-admin/includes/schema.php index 70b4686..64ec6b7 100644
a b function populate_network( $network_id = 1, $domain = '', $email = '', $site_nam 951 951 952 952 if ( !is_multisite() ) { 953 953 $site_admins = array( $site_user->user_login ); 954 $users = get_users( array( 'fields' => array( 'ID', 'user_login' ) ) ); 954 $users = get_users( array( 955 'fields' => array( 'user_login' ), 956 'role' => 'administrator', 957 ) ); 955 958 if ( $users ) { 956 959 foreach ( $users as $user ) { 957 if ( is_super_admin( $user->ID ) && !in_array( $user->user_login, $site_admins ) ) 958 $site_admins[] = $user->user_login; 960 $site_admins[] = $user->user_login; 959 961 } 962 963 $site_admins = array_unique( $site_admins ); 960 964 } 961 965 } else { 962 966 $site_admins = get_site_option( 'site_admins' ); -
src/wp-admin/includes/template.php
diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index a4672fd..f568e39 100644
a b function do_accordion_sections( $screen, $context, $object ) { 1161 1161 } 1162 1162 ?> 1163 1163 <li class="control-section accordion-section <?php echo $hidden_class; ?> <?php echo $open_class; ?> <?php echo esc_attr( $box['id'] ); ?>" id="<?php echo esc_attr( $box['id'] ); ?>"> 1164 <h3 class="accordion-section-title hndle" tabindex="0"> 1164 <button type="button" class="handlediv button-link" aria-expanded="true"> 1165 <span class="screen-reader-text"><?php echo sprintf( __( 'Toggle panel: %s' ), esc_html( $box['title'] ) ); ?></span> 1166 <span class="sidebar-name-arrow" aria-hidden="true"></span> 1167 </button> 1168 <h3 class="accordion-section-title hndle"> 1165 1169 <?php echo esc_html( $box['title'] ); ?> 1166 <span class="screen-reader-text"><?php _e( 'Press return or enter to open this section' ); ?></span>1167 1170 </h3> 1168 1171 <div class="accordion-section-content <?php postbox_classes( $box['id'], $page ); ?>"> 1169 1172 <div class="inside"> -
src/wp-admin/includes/widgets.php
diff --git a/src/wp-admin/includes/widgets.php b/src/wp-admin/includes/widgets.php index fe2a957..408165c 100644
a b function wp_list_widget_controls( $sidebar, $sidebar_name = '' ) { 80 80 if ( $sidebar_name ) { 81 81 ?> 82 82 <div class="sidebar-name"> 83 <div class="sidebar-name-arrow"><br /></div> 83 <button type="button" class="handlediv button-link" aria-expanded="true"> 84 <span class="screen-reader-text"><?php echo sprintf( __( 'Toggle panel: %s' ), $sidebar_name ); ?></span> 85 <span class="sidebar-name-arrow" aria-hidden="true"></span> 86 </button> 84 87 <h2><?php echo esc_html( $sidebar_name ); ?> <span class="spinner"></span></h2> 85 88 </div> 86 89 <?php … … function wp_widget_control( $sidebar_args ) { 219 222 echo $sidebar_args['before_widget']; ?> 220 223 <div class="widget-top"> 221 224 <div class="widget-title-action"> 222 <a class="widget-action hide-if-no-js" href="#available-widgets"></a> 225 <button type="button" class="widget-action hide-if-no-js" aria-expanded="false"> 226 <span class="screen-reader-text"><?php printf( __( 'Edit widget: %s' ), $widget_title ); ?></span> 227 <span class="toggle-indicator" aria-hidden="true"></span> 228 </button> 223 229 <a class="widget-control-edit hide-if-js" href="<?php echo esc_url( add_query_arg( $query_arg ) ); ?>"> 224 230 <span class="edit"><?php _ex( 'Edit', 'widget' ); ?></span> 225 231 <span class="add"><?php _ex( 'Add', 'widget' ); ?></span> … … function wp_widget_control( $sidebar_args ) { 250 256 251 257 <div class="widget-control-actions"> 252 258 <div class="alignleft"> 253 <a class="widget-control-remove" href="#remove"><?php _e('Delete'); ?></a> |254 <a class="widget-control-close" href="#close"><?php _e('Close'); ?></a>259 <button type="button" class="button-link button-link-delete widget-control-remove"><?php _e( 'Delete' ); ?></button> | 260 <button type="button" class="button-link widget-control-close"><?php _e( 'Close' ); ?></button> 255 261 </div> 256 262 <div class="alignright<?php if ( 'noform' === $has_form ) echo ' widget-control-noform'; ?>"> 257 263 <?php submit_button( __( 'Save' ), 'primary widget-control-save right', 'savewidget', false, array( 'id' => 'widget-' . esc_attr( $id_format ) . '-savewidget' ) ); ?> -
src/wp-admin/js/accordion.js
diff --git a/src/wp-admin/js/accordion.js b/src/wp-admin/js/accordion.js index af62815..6eb919a 100644
a b 33 33 $( document ).ready( function () { 34 34 35 35 // Expand/Collapse accordion sections on click. 36 $( '.accordion-container' ).on( 'click keydown', '.accordion-section-title ', function( e ) {36 $( '.accordion-container' ).on( 'click keydown', '.accordion-section-title, .handlediv', function( e ) { 37 37 if ( e.type === 'keydown' && 13 !== e.which ) { // "return" key 38 38 return; 39 39 } -
src/wp-admin/js/customize-controls.js
diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index e038dcc..d340a1b 100644
a b 4762 4762 */ 4763 4763 populateChangesetUuidParam = function( isIncluded ) { 4764 4764 var urlParser, queryParams; 4765 4766 // Abort on IE9 which doesn't support history management. 4767 if ( ! history.replaceState ) { 4768 return; 4769 } 4770 4765 4771 urlParser = document.createElement( 'a' ); 4766 4772 urlParser.href = location.href; 4767 4773 queryParams = api.utils.parseQueryString( urlParser.search.substr( 1 ) ); … … 4780 4786 history.replaceState( {}, document.title, urlParser.href ); 4781 4787 }; 4782 4788 4783 if ( history.replaceState ) { 4784 changesetStatus.bind( function( newStatus ) { 4785 populateChangesetUuidParam( '' !== newStatus && 'publish' !== newStatus ); 4786 } ); 4787 } 4789 changesetStatus.bind( function( newStatus ) { 4790 populateChangesetUuidParam( '' !== newStatus && 'publish' !== newStatus ); 4791 } ); 4788 4792 4789 4793 // Expose states to the API. 4790 4794 api.state = state; -
src/wp-admin/js/customize-widgets.js
diff --git a/src/wp-admin/js/customize-widgets.js b/src/wp-admin/js/customize-widgets.js index b482e8d..df4c8d7 100644
a b 952 952 var self = this, $removeBtn, replaceDeleteWithRemove; 953 953 954 954 // Configure remove button 955 $removeBtn = this.container.find( ' a.widget-control-remove' );955 $removeBtn = this.container.find( '.widget-control-remove' ); 956 956 $removeBtn.on( 'click', function( e ) { 957 957 e.preventDefault(); 958 958 … … 988 988 } ); 989 989 990 990 replaceDeleteWithRemove = function() { 991 $removeBtn.text( l10n.removeBtnLabel ); // wp_widget_control() outputs the linkas "Delete"991 $removeBtn.text( l10n.removeBtnLabel ); // wp_widget_control() outputs the button as "Delete" 992 992 $removeBtn.attr( 'title', l10n.removeBtnTooltip ); 993 993 }; 994 994 … … 1367 1367 * @param {Object} args merged on top of this.defaultActiveArguments 1368 1368 */ 1369 1369 onChangeExpanded: function ( expanded, args ) { 1370 var self = this, $widget, $inside, complete, prevComplete, expandControl ;1370 var self = this, $widget, $inside, complete, prevComplete, expandControl, $toggleBtn; 1371 1371 1372 1372 self.embedWidgetControl(); // Make sure the outer form is embedded so that the expanded state can be set in the UI. 1373 1373 if ( expanded ) { … … 1386 1386 1387 1387 $widget = this.container.find( 'div.widget:first' ); 1388 1388 $inside = $widget.find( '.widget-inside:first' ); 1389 $toggleBtn = this.container.find( '.widget-top button.widget-action' ); 1389 1390 1390 1391 expandControl = function() { 1391 1392 … … 1399 1400 complete = function() { 1400 1401 self.container.removeClass( 'expanding' ); 1401 1402 self.container.addClass( 'expanded' ); 1403 $toggleBtn.attr( 'aria-expanded', 'true' ); 1402 1404 self.container.trigger( 'expanded' ); 1403 1405 }; 1404 1406 if ( args.completeCallback ) { … … 1428 1430 expandControl(); 1429 1431 } 1430 1432 } else { 1431 1432 1433 complete = function() { 1433 1434 self.container.removeClass( 'collapsing' ); 1434 1435 self.container.removeClass( 'expanded' ); 1436 $toggleBtn.attr( 'aria-expanded', 'false' ); 1435 1437 self.container.trigger( 'collapsed' ); 1436 1438 }; 1437 1439 if ( args.completeCallback ) { -
src/wp-admin/js/editor.js
diff --git a/src/wp-admin/js/editor.js b/src/wp-admin/js/editor.js index a63a51c..917721a 100644
a b 1 window.wp = window.wp || {}; 2 3 ( function( $, wp ) { 4 wp.editor = wp.editor || {}; 1 5 2 ( function( $ ) {3 6 /** 4 7 * @summary Utility functions for the editor. 5 8 * … … 484 487 } ); 485 488 } 486 489 487 window.wp = window.wp || {}; 488 window.wp.editor = window.wp.editor || {}; 489 window.wp.editor.autop = wpautop; 490 window.wp.editor.removep = pre_wpautop; 490 wp.editor.autop = wpautop; 491 wp.editor.removep = pre_wpautop; 491 492 492 493 exports = { 493 494 go: switchEditor, … … 505 506 * Expose the switch editors to be used globally. 506 507 */ 507 508 window.switchEditors = new SwitchEditors(); 508 }( window.jQuery )); 509 510 /** 511 * Initialize TinyMCE and/or Quicktags. For use with wp_enqueue_editor() (PHP). 512 * 513 * Intended for use with an existing textarea that will become the Text editor tab. 514 * The editor width will be the width of the textarea container, height will be adjustable. 515 * 516 * Settings for both TinyMCE and Quicktags can be passed on initialization, and are "filtered" 517 * with custom jQuery events on the document element, wp-before-tinymce-init and wp-before-quicktags-init. 518 * 519 * @since 4.8 520 * 521 * @param {string} id The HTML id of the textarea that is used for the editor. 522 * Has to be jQuery compliant. No brackets, special chars, etc. 523 * @param {object} settings Example: 524 * settings = { 525 * // See https://www.tinymce.com/docs/configure/integration-and-setup/. 526 * // Alternatively set to `true` to use the defaults. 527 * tinymce: { 528 * setup: function( editor ) { 529 * console.log( 'Editor initialized', editor ); 530 * } 531 * } 532 * 533 * // Alternatively set to `true` to use the defaults. 534 * quicktags: { 535 * buttons: 'strong,em,link' 536 * } 537 * } 538 */ 539 wp.editor.initialize = function( id, settings ) { 540 var init; 541 var defaults; 542 543 if ( ! $ || ! id || ! wp.editor.getDefaultSettings ) { 544 return; 545 } 546 547 defaults = wp.editor.getDefaultSettings(); 548 549 // Initialize TinyMCE by default 550 if ( ! settings ) { 551 settings = { 552 tinymce: true 553 }; 554 } 555 556 // Add wrap and the Visual|Text tabs. 557 if ( settings.tinymce && settings.quicktags ) { 558 var $textarea = $( '#' + id ); 559 var $wrap = $( '<div>' ).attr( { 560 'class': 'wp-core-ui wp-editor-wrap tmce-active', 561 id: 'wp-' + id + '-wrap' 562 } ); 563 var $editorContainer = $( '<div class="wp-editor-container">' ); 564 var $button = $( '<button>' ).attr( { 565 type: 'button', 566 'data-wp-editor-id': id 567 } ); 568 569 $wrap.append( 570 $( '<div class="wp-editor-tools">' ) 571 .append( $( '<div class="wp-editor-tabs">' ) 572 .append( $button.clone().attr({ 573 id: id + '-tmce', 574 'class': 'wp-switch-editor switch-tmce' 575 }).text( window.tinymce.translate( 'Visual' ) ) ) 576 .append( $button.attr({ 577 id: id + '-html', 578 'class': 'wp-switch-editor switch-html' 579 }).text( window.tinymce.translate( 'Text' ) ) ) 580 ).append( $editorContainer ) 581 ); 582 583 $textarea.after( $wrap ); 584 $editorContainer.append( $textarea ); 585 } 586 587 if ( window.tinymce && settings.tinymce ) { 588 if ( typeof settings.tinymce !== 'object' ) { 589 settings.tinymce = {}; 590 } 591 592 init = $.extend( {}, defaults.tinymce, settings.tinymce ); 593 init.selector = '#' + id; 594 595 $( document ).trigger( 'wp-before-tinymce-init', init ); 596 window.tinymce.init( init ); 597 598 if ( ! window.wpActiveEditor ) { 599 window.wpActiveEditor = id; 600 } 601 } 602 603 if ( window.quicktags && settings.quicktags ) { 604 if ( typeof settings.quicktags !== 'object' ) { 605 settings.quicktags = {}; 606 } 607 608 init = $.extend( {}, defaults.quicktags, settings.quicktags ); 609 init.id = id; 610 611 $( document ).trigger( 'wp-before-quicktags-init', init ); 612 window.quicktags( init ); 613 614 if ( ! window.wpActiveEditor ) { 615 window.wpActiveEditor = init.id; 616 } 617 } 618 }; 619 620 /** 621 * Get the editor content. 622 * 623 * Intended for use with editors that were initialized with wp.editor.initialize(). 624 * 625 * @since 4.8 626 * 627 * @param {string} id The HTML id of the editor textarea. 628 * @return The editor content. 629 */ 630 wp.editor.getContent = function( id ) { 631 var editor; 632 633 if ( ! $ || ! id ) { 634 return; 635 } 636 637 if ( window.tinymce ) { 638 editor = window.tinymce.get( id ); 639 640 if ( editor && ! editor.isHidden() ) { 641 editor.save(); 642 } 643 } 644 645 return $( '#' + id ).val(); 646 }; 647 648 }( window.jQuery, window.wp )); -
src/wp-admin/js/widgets.js
diff --git a/src/wp-admin/js/widgets.js b/src/wp-admin/js/widgets.js index aa439ea..77cf8f9 100644
a b wpWidgets = { 41 41 $(document.body).bind('click.widgets-toggle', function(e) { 42 42 var target = $(e.target), 43 43 css = { 'z-index': 100 }, 44 widget, inside, targetWidth, widgetWidth, margin; 44 widget, inside, targetWidth, widgetWidth, margin, 45 toggleBtn = target.closest( '.widget' ).find( '.widget-top button.widget-action' ); 45 46 46 47 if ( target.parents('.widget-top').length && ! target.parents('#available-widgets').length ) { 47 48 widget = target.closest('div.widget'); … … wpWidgets = { 60 61 css[ margin ] = widgetWidth - ( targetWidth + 30 ) + 'px'; 61 62 widget.css( css ); 62 63 } 63 widget.addClass( 'open' ); 64 inside.slideDown('fast'); 64 /* 65 * Don't change the order of attributes changes and animation: 66 * it's important for screen readers, see ticket #31476. 67 */ 68 toggleBtn.attr( 'aria-expanded', 'true' ); 69 inside.slideDown( 'fast', function() { 70 widget.addClass( 'open' ); 71 }); 65 72 } else { 66 inside.slideUp('fast', function() { 73 /* 74 * Don't change the order of attributes changes and animation: 75 * it's important for screen readers, see ticket #31476. 76 */ 77 toggleBtn.attr( 'aria-expanded', 'false' ); 78 inside.slideUp( 'fast', function() { 67 79 widget.attr( 'style', '' ); 68 80 widget.removeClass( 'open' ); 69 81 }); … … wpWidgets = { 78 90 } else if ( target.hasClass('widget-control-close') ) { 79 91 widget = target.closest('div.widget'); 80 92 widget.removeClass( 'open' ); 93 toggleBtn.attr( 'aria-expanded', 'false' ); 81 94 wpWidgets.close( widget ); 82 95 e.preventDefault(); 83 96 } else if ( target.attr( 'id' ) === 'inactive-widgets-control-remove' ) { … … wpWidgets = { 92 105 wpWidgets.appendTitle( this ); 93 106 94 107 if ( $this.find( 'p.widget-error' ).length ) { 95 $this.find( ' a.widget-action' ).trigger('click');108 $this.find( '.widget-action' ).trigger( 'click' ).attr( 'aria-expanded', 'true' ); 96 109 } 97 110 }); 98 111 … … wpWidgets = { 182 195 183 196 if ( inside.css('display') === 'block' ) { 184 197 ui.item.removeClass('open'); 198 ui.item.find( '.widget-top button.widget-action' ).attr( 'aria-expanded', 'false' ); 185 199 inside.hide(); 186 200 $(this).sortable('refreshPositions'); 187 201 } … … wpWidgets = { 254 268 } 255 269 256 270 if ( addNew ) { 257 $widget.find( ' a.widget-action' ).trigger('click');271 $widget.find( '.widget-action' ).trigger( 'click' ); 258 272 } else { 259 273 wpWidgets.saveOrder( $sidebar.attr('id') ); 260 274 } … … wpWidgets = { 492 506 493 507 close : function(widget) { 494 508 widget.children('.widget-inside').slideUp('fast', function() { 495 widget.attr( 'style', '' ); 509 widget.attr( 'style', '' ) 510 .find( '.widget-top button.widget-action' ) 511 .attr( 'aria-expanded', 'false' ) 512 .focus(); 496 513 }); 497 514 }, 498 515 -
src/wp-admin/network/menu.php
diff --git a/src/wp-admin/network/menu.php b/src/wp-admin/network/menu.php index 41281e7..e4cc786 100644
a b 19 19 $submenu['index.php'][10] = array( __( 'Updates' ), 'update_core', 'update-core.php' ); 20 20 } 21 21 22 $submenu['index.php'][15] = array( __( 'Upgrade Network' ), ' manage_network', 'upgrade.php' );22 $submenu['index.php'][15] = array( __( 'Upgrade Network' ), 'upgrade_network', 'upgrade.php' ); 23 23 24 24 $menu[4] = array( '', 'read', 'separator1', '', 'wp-menu-separator' ); 25 25 -
src/wp-admin/network/site-new.php
diff --git a/src/wp-admin/network/site-new.php b/src/wp-admin/network/site-new.php index 0be051e..f36dffb 100644
a b 13 13 /** WordPress Translation Install API */ 14 14 require_once( ABSPATH . 'wp-admin/includes/translation-install.php' ); 15 15 16 if ( ! current_user_can( ' manage_sites' ) )16 if ( ! current_user_can( 'create_sites' ) ) { 17 17 wp_die( __( 'Sorry, you are not allowed to add sites to this network.' ) ); 18 } 18 19 19 20 get_current_screen()->add_help_tab( array( 20 21 'id' => 'overview', -
src/wp-admin/network/upgrade.php
diff --git a/src/wp-admin/network/upgrade.php b/src/wp-admin/network/upgrade.php index 5c2d3f9..46c6a94 100644
a b 32 32 33 33 require_once( ABSPATH . 'wp-admin/admin-header.php' ); 34 34 35 if ( ! current_user_can( ' manage_network' ) )35 if ( ! current_user_can( 'upgrade_network' ) ) { 36 36 wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 ); 37 } 37 38 38 39 echo '<div class="wrap">'; 39 40 echo '<h1>' . __( 'Upgrade Network' ) . '</h1>'; -
src/wp-admin/options-reading.php
diff --git a/src/wp-admin/options-reading.php b/src/wp-admin/options-reading.php index 69c425f..baa9f75 100644
a b 22 22 'title' => __('Overview'), 23 23 'content' => '<p>' . __('This screen contains the settings that affect the display of your content.') . '</p>' . 24 24 '<p>' . sprintf(__('You can choose what’s displayed on the front page of your site. It can be posts in reverse chronological order (classic blog), or a fixed/static page. To set a static home page, you first need to create two <a href="%s">Pages</a>. One will become the front page, and the other will be where your posts are displayed.'), 'post-new.php?post_type=page') . '</p>' . 25 '<p>' . __('You can also control the display of your content in RSS feeds, including the maximum number sof posts to display and whether to show full text or a summary.') . '</p>' .25 '<p>' . __('You can also control the display of your content in RSS feeds, including the maximum number of posts to display and whether to show full text or a summary.') . '</p>' . 26 26 '<p>' . __('You must click the Save Changes button at the bottom of the screen for new settings to take effect.') . '</p>', 27 27 ) ); 28 28 -
src/wp-admin/widgets.php
diff --git a/src/wp-admin/widgets.php b/src/wp-admin/widgets.php index db4459b..ade84bb 100644
a b 387 387 <div id="widgets-left"> 388 388 <div id="available-widgets" class="widgets-holder-wrap"> 389 389 <div class="sidebar-name"> 390 <div class="sidebar-name-arrow"><br /></div> 390 <button type="button" class="handlediv button-link" aria-expanded="true"> 391 <span class="screen-reader-text">Toggle panel: <?php _e( 'Available Widgets' ); ?></span> 392 <span class="sidebar-name-arrow" aria-hidden="true"></span> 393 </button> 391 394 <h2><?php _e( 'Available Widgets' ); ?> <span id="removing-widget"><?php _ex( 'Deactivate', 'removing-widget' ); ?> <span></span></span></h2> 392 395 </div> 393 396 <div class="widget-holder"> -
src/wp-content/themes/twentyseventeen/README.txt
diff --git a/src/wp-content/themes/twentyseventeen/README.txt b/src/wp-content/themes/twentyseventeen/README.txt index 5f1cfb7..9360fc7 100644
a b 2 2 Contributors: the WordPress team 3 3 Requires at least: WordPress 4.7 4 4 Tested up to: WordPress 4.7 5 Version: 1. 15 Version: 1.2 6 6 License: GPLv2 or later 7 7 License URI: http://www.gnu.org/licenses/gpl-2.0.html 8 8 Tags: one-column, two-columns, right-sidebar, flexible-header, accessibility-ready, custom-colors, custom-header, custom-menu, custom-logo, editor-style, featured-images, footer-widgets, post-formats, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready … … Source: https://unsplash.com/@englr?photo=bIhpiQA009k 60 60 61 61 == Changelog == 62 62 63 = 1.2 = 64 * Released: April 18, 2017 65 66 https://codex.wordpress.org/Twenty_Seventeen_Theme_Changelog#Version_1.2 67 63 68 = 1.1 = 64 69 * Released: January 6, 2017 65 70 66 - Fix incorrect $content_width value in theme 67 - Ensure functions in customize-controls.js don't count on Customizer sections always being present 68 - Deprecate page_home nav menu item starter content in favor of link_home 69 - Introduce a theme-specific filter twentyseventeen_starter_content for customizing the starter content array 71 https://codex.wordpress.org/Twenty_Seventeen_Theme_Changelog#Version_1.1 70 72 71 73 = 1.0 = 72 74 * Released: December 6, 2016 -
src/wp-content/themes/twentyseventeen/footer.php
diff --git a/src/wp-content/themes/twentyseventeen/footer.php b/src/wp-content/themes/twentyseventeen/footer.php index c21cfb7..504f573 100644
a b 9 9 * @package WordPress 10 10 * @subpackage Twenty_Seventeen 11 11 * @since 1.0 12 * @version 1. 012 * @version 1.2 13 13 */ 14 14 15 15 ?> -
src/wp-content/themes/twentyseventeen/style.css
diff --git a/src/wp-content/themes/twentyseventeen/style.css b/src/wp-content/themes/twentyseventeen/style.css index da3791d..37ec33f 100644
a b Theme URI: https://wordpress.org/themes/twentyseventeen/ 4 4 Author: the WordPress team 5 5 Author URI: https://wordpress.org/ 6 6 Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a focus on business sites, it features multiple sections on the front page as well as widgets, navigation and social menus, a logo, and more. Personalize its asymmetrical grid with a custom color scheme and showcase your multimedia content with post formats. Our default theme for 2017 works great in many languages, for any abilities, and on any device. 7 Version: 1. 17 Version: 1.2 8 8 License: GNU General Public License v2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 10 Text Domain: twentyseventeen … … h1 { 451 451 font-weight: 300; 452 452 } 453 453 454 h2 { 454 h2, 455 .home.blog .entry-title { 455 456 color: #666; 456 457 font-size: 20px; 457 458 font-size: 1.25rem; … … object { 3153 3154 } 3154 3155 3155 3156 h2, 3157 .home.blog .entry-title, 3156 3158 .page .panel-content .recent-posts .entry-title { 3157 3159 font-size: 26px; 3158 3160 font-size: 1.625rem; -
src/wp-content/themes/twentyseventeen/template-parts/navigation/navigation-top.php
diff --git a/src/wp-content/themes/twentyseventeen/template-parts/navigation/navigation-top.php b/src/wp-content/themes/twentyseventeen/template-parts/navigation/navigation-top.php index be7e426..2c2115e 100644
a b 5 5 * @package WordPress 6 6 * @subpackage Twenty_Seventeen 7 7 * @since 1.0 8 * @version 1. 08 * @version 1.2 9 9 */ 10 10 11 11 ?> -
src/wp-content/themes/twentyseventeen/template-parts/post/content-audio.php
diff --git a/src/wp-content/themes/twentyseventeen/template-parts/post/content-audio.php b/src/wp-content/themes/twentyseventeen/template-parts/post/content-audio.php index cf17889..63cf2e5 100644
a b 7 7 * @package WordPress 8 8 * @subpackage Twenty_Seventeen 9 9 * @since 1.0 10 * @version 1. 010 * @version 1.2 11 11 */ 12 12 13 13 ?> … … 33 33 34 34 if ( is_single() ) { 35 35 the_title( '<h1 class="entry-title">', '</h1>' ); 36 } elseif ( is_front_page() && is_home() ) { 37 the_title( '<h3 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h3>' ); 36 38 } else { 37 39 the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' ); 38 40 } -
src/wp-content/themes/twentyseventeen/template-parts/post/content-excerpt.php
diff --git a/src/wp-content/themes/twentyseventeen/template-parts/post/content-excerpt.php b/src/wp-content/themes/twentyseventeen/template-parts/post/content-excerpt.php index 4ddc28c..a552fba 100644
a b 9 9 * @package WordPress 10 10 * @subpackage Twenty_Seventeen 11 11 * @since 1.0 12 * @version 1. 012 * @version 1.2 13 13 */ 14 14 15 15 ?> … … 30 30 </div><!-- .entry-meta --> 31 31 <?php endif; ?> 32 32 33 <?php the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); ?> 33 <?php if ( is_front_page() && ! is_home() ) { 34 35 // The excerpt is being displayed within a front page section, so it's a lower hierarchy than h2. 36 the_title( sprintf( '<h3 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h3>' ); 37 } else { 38 the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); 39 } ?> 34 40 </header><!-- .entry-header --> 35 41 36 42 <div class="entry-summary"> -
src/wp-content/themes/twentyseventeen/template-parts/post/content-gallery.php
diff --git a/src/wp-content/themes/twentyseventeen/template-parts/post/content-gallery.php b/src/wp-content/themes/twentyseventeen/template-parts/post/content-gallery.php index e46e7c5..f5934e1 100644
a b 7 7 * @package WordPress 8 8 * @subpackage Twenty_Seventeen 9 9 * @since 1.0 10 * @version 1. 010 * @version 1.2 11 11 */ 12 12 13 13 ?> … … 33 33 34 34 if ( is_single() ) { 35 35 the_title( '<h1 class="entry-title">', '</h1>' ); 36 } elseif ( is_front_page() && is_home() ) { 37 the_title( '<h3 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h3>' ); 36 38 } else { 37 39 the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' ); 38 40 } -
src/wp-content/themes/twentyseventeen/template-parts/post/content-image.php
diff --git a/src/wp-content/themes/twentyseventeen/template-parts/post/content-image.php b/src/wp-content/themes/twentyseventeen/template-parts/post/content-image.php index 8568d92..91c6545 100644
a b 7 7 * @package WordPress 8 8 * @subpackage Twenty_Seventeen 9 9 * @since 1.0 10 * @version 1. 010 * @version 1.2 11 11 */ 12 12 13 13 ?> … … 33 33 34 34 if ( is_single() ) { 35 35 the_title( '<h1 class="entry-title">', '</h1>' ); 36 } elseif ( is_front_page() && is_home() ) { 37 the_title( '<h3 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h3>' ); 36 38 } else { 37 39 the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' ); 38 40 } -
src/wp-content/themes/twentyseventeen/template-parts/post/content-video.php
diff --git a/src/wp-content/themes/twentyseventeen/template-parts/post/content-video.php b/src/wp-content/themes/twentyseventeen/template-parts/post/content-video.php index 1c3ef49..dad681f 100644
a b 7 7 * @package WordPress 8 8 * @subpackage Twenty_Seventeen 9 9 * @since 1.0 10 * @version 1. 010 * @version 1.2 11 11 */ 12 12 13 13 ?> … … 33 33 34 34 if ( is_single() ) { 35 35 the_title( '<h1 class="entry-title">', '</h1>' ); 36 } elseif ( is_front_page() && is_home() ) { 37 the_title( '<h3 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h3>' ); 36 38 } else { 37 39 the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' ); 38 40 } -
src/wp-content/themes/twentyseventeen/template-parts/post/content.php
diff --git a/src/wp-content/themes/twentyseventeen/template-parts/post/content.php b/src/wp-content/themes/twentyseventeen/template-parts/post/content.php index a87f646..90c3a4d 100644
a b 7 7 * @package WordPress 8 8 * @subpackage Twenty_Seventeen 9 9 * @since 1.0 10 * @version 1. 010 * @version 1.2 11 11 */ 12 12 13 13 ?> … … 33 33 34 34 if ( is_single() ) { 35 35 the_title( '<h1 class="entry-title">', '</h1>' ); 36 } elseif ( is_front_page() && is_home() ) { 37 the_title( '<h3 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h3>' ); 36 38 } else { 37 39 the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' ); 38 40 } -
src/wp-includes/capabilities.php
diff --git a/src/wp-includes/capabilities.php b/src/wp-includes/capabilities.php index 0e766b1..abd87257 100644
a b function map_meta_cap( $cap, $user_id ) { 478 478 case 'manage_network_plugins': 479 479 case 'manage_network_themes': 480 480 case 'manage_network_options': 481 case 'upgrade_network': 481 482 $caps[] = $cap; 482 483 break; 483 484 case 'setup_network': -
src/wp-includes/class-walker-nav-menu.php
diff --git a/src/wp-includes/class-walker-nav-menu.php b/src/wp-includes/class-walker-nav-menu.php index 4c1a1f2..c97188b 100644
a b public function start_lvl( &$output, $depth = 0, $args = array() ) { 58 58 $n = "\n"; 59 59 } 60 60 $indent = str_repeat( $t, $depth ); 61 $output .= "{$n}{$indent}<ul class=\"sub-menu\">{$n}"; 61 62 /** 63 * Filters the CSS class(es) applied to a menu list element. 64 * 65 * @since 4.8.0 66 * 67 * @param array $classes The CSS classes that are applied to the menu `<ul>` element. 68 * @param stdClass $args An object of `wp_nav_menu()` arguments. 69 * @param int $depth Depth of menu item. Used for padding. 70 */ 71 72 $classes = array( 'sub-menu' ); 73 $classes = apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ); 74 $class_names = join( ' ', $classes ); 75 76 $output .= "{$n}{$indent}<ul class='" . esc_attr( $class_names ) . "'>{$n}"; 62 77 } 63 78 64 79 /** -
src/wp-includes/class-walker-page.php
diff --git a/src/wp-includes/class-walker-page.php b/src/wp-includes/class-walker-page.php index 30831bb..8bec66f 100644
a b public function start_el( &$output, $page, $depth = 0, $args = array(), $current 160 160 $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before']; 161 161 $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after']; 162 162 163 $atts = array(); 164 $atts['href'] = get_permalink( $page->ID ); 165 166 /** 167 * Filters the HTML attributes applied to a page menu item's anchor element. 168 * 169 * @since 4.8.0 170 * 171 * @param array $atts { 172 * The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored. 173 * 174 * @type string $href The href attribute. 175 * } 176 * @param WP_Post $page Page data object. 177 * @param int $depth Depth of page, used for padding. 178 * @param array $args An array of arguments. 179 * @param int $current_page ID of the current page. 180 */ 181 $atts = apply_filters( 'page_menu_link_attributes', $atts, $page, $depth, $args, $current_page ); 182 183 $attributes = ''; 184 foreach ( $atts as $attr => $value ) { 185 if ( ! empty( $value ) ) { 186 $value = esc_attr( $value ); 187 $attributes .= ' ' . $attr . '="' . $value . '"'; 188 } 189 } 190 163 191 $output .= $indent . sprintf( 164 '<li class="%s"><a href="%s">%s%s%s</a>',192 '<li class="%s"><a%s>%s%s%s</a>', 165 193 $css_classes, 166 get_permalink( $page->ID ),194 $attributes, 167 195 $args['link_before'], 168 196 /** This filter is documented in wp-includes/post-template.php */ 169 197 apply_filters( 'the_title', $page->post_title, $page->ID ), -
src/wp-includes/class-wp-editor.php
diff --git a/src/wp-includes/class-wp-editor.php b/src/wp-includes/class-wp-editor.php index 83777cf..21353c6 100644
a b 27 27 private static $drag_drop_upload = false; 28 28 private static $old_dfw_compat = false; 29 29 private static $translation; 30 private static $tinymce_scripts_printed = false; 31 private static $link_dialog_printed = false; 30 32 31 33 private function __construct() {} 32 34 … … public static function editor_settings($editor_id, $set) { 350 352 if ( self::$this_tinymce ) { 351 353 352 354 if ( empty( self::$first_init ) ) { 353 self::$baseurl = includes_url( 'js/tinymce' ); 354 355 $mce_locale = get_user_locale(); 356 self::$mce_locale = $mce_locale = empty( $mce_locale ) ? 'en' : strtolower( substr( $mce_locale, 0, 2 ) ); // ISO 639-1 357 358 /** This filter is documented in wp-admin/includes/media.php */ 359 $no_captions = (bool) apply_filters( 'disable_captions', '' ); 355 $baseurl = self::get_baseurl(); 356 $mce_locale = self::get_mce_locale(); 360 357 $ext_plugins = ''; 361 $shortcut_labels = array();362 363 foreach ( self::get_translation() as $name => $value ) {364 if ( is_array( $value ) ) {365 $shortcut_labels[$name] = $value[1];366 }367 }368 358 369 359 if ( $set['teeny'] ) { 370 360 … … public static function editor_settings($editor_id, $set) { 376 366 * @param array $plugins An array of teenyMCE plugins. 377 367 * @param string $editor_id Unique editor identifier, e.g. 'content'. 378 368 */ 379 self::$plugins =$plugins = apply_filters( 'teeny_mce_plugins', array( 'colorpicker', 'lists', 'fullscreen', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id );369 $plugins = apply_filters( 'teeny_mce_plugins', array( 'colorpicker', 'lists', 'fullscreen', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id ); 380 370 } else { 381 371 382 372 /** … … public static function editor_settings($editor_id, $set) { 521 511 self::$plugins = $plugins; 522 512 self::$ext_plugins = $ext_plugins; 523 513 524 self::$first_init = array( 525 'theme' => 'modern', 526 'skin' => 'lightgray', 527 'language' => self::$mce_locale, 528 'formats' => '{' . 529 'alignleft: [' . 530 '{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"left"}},' . 531 '{selector: "img,table,dl.wp-caption", classes: "alignleft"}' . 532 '],' . 533 'aligncenter: [' . 534 '{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"center"}},' . 535 '{selector: "img,table,dl.wp-caption", classes: "aligncenter"}' . 536 '],' . 537 'alignright: [' . 538 '{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"right"}},' . 539 '{selector: "img,table,dl.wp-caption", classes: "alignright"}' . 540 '],' . 541 'strikethrough: {inline: "del"}' . 542 '}', 543 'relative_urls' => false, 544 'remove_script_host' => false, 545 'convert_urls' => false, 546 'browser_spellcheck' => true, 547 'fix_list_elements' => true, 548 'entities' => '38,amp,60,lt,62,gt', 549 'entity_encoding' => 'raw', 550 'keep_styles' => false, 551 'cache_suffix' => 'wp-mce-' . $tinymce_version, 552 553 // Limit the preview styles in the menu/toolbar 554 'preview_styles' => 'font-family font-size font-weight font-style text-decoration text-transform', 555 556 'end_container_on_empty_block' => true, 557 'wpeditimage_disable_captions' => $no_captions, 558 'wpeditimage_html5_captions' => current_theme_supports( 'html5', 'caption' ), 559 'plugins' => implode( ',', $plugins ), 560 'wp_lang_attr' => get_bloginfo( 'language' ), 561 'wp_shortcut_labels' => wp_json_encode( $shortcut_labels ), 562 ); 514 $settings = self::default_settings(); 515 $settings['plugins'] = implode( ',', $plugins ); 563 516 564 517 if ( ! empty( $mce_external_plugins ) ) { 565 self::$first_init['external_plugins'] = wp_json_encode( $mce_external_plugins );518 $settings['external_plugins'] = wp_json_encode( $mce_external_plugins ); 566 519 } 567 520 568 $suffix = SCRIPT_DEBUG ? '' : '.min'; 569 $version = 'ver=' . get_bloginfo( 'version' ); 570 $dashicons = includes_url( "css/dashicons$suffix.css?$version" ); 571 572 // WordPress default stylesheet and dashicons 573 $mce_css = array( 574 $dashicons, 575 self::$baseurl . '/skins/wordpress/wp-content.css?' . $version 576 ); 521 /** This filter is documented in wp-admin/includes/media.php */ 522 if ( apply_filters( 'disable_captions', '' ) ) { 523 $settings['wpeditimage_disable_captions'] = true; 524 } 577 525 526 $mce_css = $settings['content_css']; 578 527 $editor_styles = get_editor_stylesheets(); 528 579 529 if ( ! empty( $editor_styles ) ) { 580 foreach ( $editor_styles as $style ) { 581 $mce_css[] = $style; 582 } 530 $mce_css .= ',' . implode( ',', $editor_styles ); 583 531 } 584 532 585 533 /** … … public static function editor_settings($editor_id, $set) { 589 537 * 590 538 * @param string $stylesheets Comma-delimited list of stylesheets. 591 539 */ 592 $mce_css = trim( apply_filters( 'mce_css', implode( ',', $mce_css )), ' ,' );540 $mce_css = trim( apply_filters( 'mce_css', $mce_css ), ' ,' ); 593 541 594 if ( ! empty($mce_css) ) 595 self::$first_init['content_css'] = $mce_css; 542 if ( ! empty( $mce_css ) ) { 543 $settings['content_css'] = $mce_css; 544 } else { 545 unset( $settings['content_css'] ); 546 } 547 548 self::$first_init = $settings; 596 549 } 597 550 598 551 if ( $set['teeny'] ) { … … public static function editor_settings($editor_id, $set) { 690 643 691 644 $body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_user_locale() ) ) ); 692 645 693 if ( ! empty($set['tinymce']['body_class']) ) {646 if ( ! empty( $set['tinymce']['body_class'] ) ) { 694 647 $body_class .= ' ' . $set['tinymce']['body_class']; 695 unset( $set['tinymce']['body_class']);648 unset( $set['tinymce']['body_class'] ); 696 649 } 697 650 698 651 $mceInit = array ( 699 652 'selector' => "#$editor_id", 700 'resize' => 'vertical',701 'menubar' => false,702 653 'wpautop' => (bool) $set['wpautop'], 703 654 'indent' => ! $set['wpautop'], 704 'toolbar1' => implode( $mce_buttons, ','),705 'toolbar2' => implode( $mce_buttons_2, ','),706 'toolbar3' => implode( $mce_buttons_3, ','),707 'toolbar4' => implode( $mce_buttons_4, ','),655 'toolbar1' => implode( ',', $mce_buttons ), 656 'toolbar2' => implode( ',', $mce_buttons_2 ), 657 'toolbar3' => implode( ',', $mce_buttons_3 ), 658 'toolbar4' => implode( ',', $mce_buttons_4 ), 708 659 'tabfocus_elements' => $set['tabfocus_elements'], 709 660 'body_class' => $body_class 710 661 ); … … public static function editor_settings($editor_id, $set) { 762 713 * @param array $init 763 714 * @return string 764 715 */ 765 private static function _parse_init( $init) {716 private static function _parse_init( $init ) { 766 717 $options = ''; 767 718 768 foreach ( $init as $k => $v) {769 if ( is_bool( $v) ) {770 $val = $v ? 'true' : 'false';771 $options .= $k . ':' . $val . ',';719 foreach ( $init as $key => $value ) { 720 if ( is_bool( $value ) ) { 721 $val = $value ? 'true' : 'false'; 722 $options .= $key . ':' . $val . ','; 772 723 continue; 773 } elseif ( !empty($v) && is_string($v) && ( ('{' == $v{0} && '}' == $v{strlen($v) - 1}) || ('[' == $v{0} && ']' == $v{strlen($v) - 1}) || preg_match('/^\(?function ?\(/', $v) ) ) { 774 $options .= $k . ':' . $v . ','; 724 } elseif ( ! empty( $value ) && is_string( $value ) && ( 725 ( '{' == $value{0} && '}' == $value{strlen( $value ) - 1} ) || 726 ( '[' == $value{0} && ']' == $value{strlen( $value ) - 1} ) || 727 preg_match( '/^\(?function ?\(/', $value ) ) ) { 728 729 $options .= $key . ':' . $value . ','; 775 730 continue; 776 731 } 777 $options .= $k . ':"' . $v. '",';732 $options .= $key . ':"' . $value . '",'; 778 733 } 779 734 780 735 return '{' . trim( $options, ' ,' ) . '}'; … … private static function _parse_init($init) { 784 739 * 785 740 * @static 786 741 */ 787 public static function enqueue_scripts() { 788 if ( self::$has_tinymce ) 789 wp_enqueue_script('editor'); 742 public static function enqueue_scripts( $default_scripts = false ) { 743 if ( $default_scripts || self::$has_tinymce ) { 744 wp_enqueue_script( 'editor' ); 745 } 790 746 791 if ( self::$has_quicktags ) {747 if ( $default_scripts || self::$has_quicktags ) { 792 748 wp_enqueue_script( 'quicktags' ); 793 749 wp_enqueue_style( 'buttons' ); 794 750 } 795 751 796 if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) ) {797 wp_enqueue_script( 'wplink');752 if ( $default_scripts || in_array( 'wplink', self::$plugins, true ) || in_array( 'link', self::$qt_buttons, true ) ) { 753 wp_enqueue_script( 'wplink' ); 798 754 wp_enqueue_script( 'jquery-ui-autocomplete' ); 799 755 } 800 756 801 757 if ( self::$old_dfw_compat ) { 802 wp_enqueue_script( 'wp-fullscreen-stub');758 wp_enqueue_script( 'wp-fullscreen-stub' ); 803 759 } 804 760 805 761 if ( self::$has_medialib ) { 806 762 add_thickbox(); 807 763 wp_enqueue_script( 'media-upload' ); 808 764 wp_enqueue_script( 'wp-embed' ); 765 } elseif ( $default_scripts ) { 766 wp_enqueue_script( 'media-upload' ); 809 767 } 810 768 811 769 /** … … public static function enqueue_scripts() { 817 775 * and Quicktags are being loaded. 818 776 */ 819 777 do_action( 'wp_enqueue_editor', array( 820 'tinymce' => self::$has_tinymce, 821 'quicktags' => self::$has_quicktags, 778 'tinymce' => ( $default_scripts || self::$has_tinymce ), 779 'quicktags' => ( $default_scripts || self::$has_quicktags ), 780 ) ); 781 } 782 783 /** 784 * Enqueue all editor scripts. 785 * For use when the editor is going to be initialized after page load. 786 * 787 * @since 4.8.0 788 */ 789 public static function enqueue_default_editor() { 790 // We are past the point where scripts can be enqueued properly. 791 if ( did_action( 'wp_enqueue_editor' ) ) { 792 return; 793 } 794 795 self::enqueue_scripts( true ); 796 797 // Also add wp-includes/css/editor.css 798 wp_enqueue_style( 'editor-buttons' ); 799 800 if ( is_admin() ) { 801 add_action( 'admin_print_footer_scripts', array( __CLASS__, 'print_default_editor_scripts' ), 45 ); 802 } else { 803 add_action( 'wp_print_footer_scripts', array( __CLASS__, 'print_default_editor_scripts' ), 45 ); 804 } 805 } 806 807 /** 808 * Print (output) all editor scripts and default settings. 809 * For use when the editor is going to be initialized after page load. 810 * 811 * @since 4.8.0 812 * 813 */ 814 public static function print_default_editor_scripts() { 815 $settings = self::default_settings(); 816 817 $settings['toolbar1'] = 'bold,italic,bullist,numlist,link'; 818 $settings['wpautop'] = false; 819 $settings['indent'] = true; 820 $settings['elementpath'] = false; 821 822 // In production all plugins are loaded (they are in wp-editor.js.gz) 823 // but only these will be initialized by default. 824 $settings['plugins'] = implode( ',', array( 825 'charmap', 826 'colorpicker', 827 'hr', 828 'lists', 829 // 'media', 830 'paste', 831 'tabfocus', 832 'textcolor', 833 'fullscreen', 834 'wordpress', 835 'wpautoresize', 836 'wpeditimage', 837 'wpemoji', 838 'wpgallery', 839 'wplink', 840 // 'wpdialogs', 841 'wptextpattern', 842 // 'wpview', 822 843 ) ); 844 845 $settings = self::_parse_init( $settings ); 846 847 $suffix = SCRIPT_DEBUG ? '' : '.min'; 848 $baseurl = self::get_baseurl(); 849 850 ?> 851 <script type="text/javascript"> 852 window.wp = window.wp || {}; 853 window.wp.editor = window.wp.editor || {}; 854 window.wp.editor.getDefaultSettings = function() { 855 return { 856 tinymce: <?php echo $settings; ?>, 857 quicktags: { 858 buttons: 'strong,em,link,ul,ol,li,code' 859 } 860 }; 861 }; 862 863 var tinyMCEPreInit = { 864 baseURL: "<?php echo $baseurl; ?>", 865 suffix: "<?php echo $suffix; ?>", 866 mceInit: {}, 867 qtInit: {}, 868 load_ext: function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');} 869 }; 870 </script> 871 <?php 872 873 self::print_tinymce_scripts(); 874 875 /** 876 * Fires when the editor scripts are loaded for later initialization, 877 * after all scripts and settings are printed. 878 * 879 * @since 4.8.0 880 */ 881 do_action( 'print_default_editor_scripts' ); 882 883 self::wp_link_dialog(); 884 } 885 886 public static function get_mce_locale() { 887 if ( empty( self::$mce_locale ) ) { 888 $mce_locale = get_user_locale(); 889 self::$mce_locale = empty( $mce_locale ) ? 'en' : strtolower( substr( $mce_locale, 0, 2 ) ); // ISO 639-1 890 } 891 892 return self::$mce_locale; 893 } 894 895 public static function get_baseurl() { 896 if ( empty( self::$baseurl ) ) { 897 self::$baseurl = includes_url( 'js/tinymce' ); 898 } 899 900 return self::$baseurl; 901 } 902 903 /** 904 * Returns the default TinyMCE settings. 905 * Doesn't include plugins, buttons, editor selector. 906 * 907 * @return array 908 */ 909 private static function default_settings() { 910 global $tinymce_version; 911 912 $shortcut_labels = array(); 913 914 foreach ( self::get_translation() as $name => $value ) { 915 if ( is_array( $value ) ) { 916 $shortcut_labels[$name] = $value[1]; 917 } 918 } 919 920 $settings = array( 921 'theme' => 'modern', 922 'skin' => 'lightgray', 923 'language' => self::get_mce_locale(), 924 'formats' => '{' . 925 'alignleft: [' . 926 '{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"left"}},' . 927 '{selector: "img,table,dl.wp-caption", classes: "alignleft"}' . 928 '],' . 929 'aligncenter: [' . 930 '{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"center"}},' . 931 '{selector: "img,table,dl.wp-caption", classes: "aligncenter"}' . 932 '],' . 933 'alignright: [' . 934 '{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"right"}},' . 935 '{selector: "img,table,dl.wp-caption", classes: "alignright"}' . 936 '],' . 937 'strikethrough: {inline: "del"}' . 938 '}', 939 'relative_urls' => false, 940 'remove_script_host' => false, 941 'convert_urls' => false, 942 'browser_spellcheck' => true, 943 'fix_list_elements' => true, 944 'entities' => '38,amp,60,lt,62,gt', 945 'entity_encoding' => 'raw', 946 'keep_styles' => false, 947 'cache_suffix' => 'wp-mce-' . $tinymce_version, 948 'resize' => 'vertical', 949 'menubar' => false, 950 951 // Limit the preview styles in the menu/toolbar 952 'preview_styles' => 'font-family font-size font-weight font-style text-decoration text-transform', 953 954 'end_container_on_empty_block' => true, 955 'wpeditimage_html5_captions' => true, 956 'wp_lang_attr' => get_bloginfo( 'language' ), 957 'wp_shortcut_labels' => wp_json_encode( $shortcut_labels ), 958 ); 959 960 $suffix = SCRIPT_DEBUG ? '' : '.min'; 961 $version = 'ver=' . get_bloginfo( 'version' ); 962 963 // Default stylesheets 964 $settings['content_css'] = includes_url( "css/dashicons$suffix.css?$version" ) . ',' . 965 includes_url( "js/tinymce/skins/wordpress/wp-content.css?$version" ); 966 967 return $settings; 823 968 } 824 969 825 970 private static function get_translation() { … … private static function get_translation() { 1028 1173 1029 1174 /* translators: word count */ 1030 1175 'Words: {0}' => sprintf( __( 'Words: %s' ), '{0}' ), 1031 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' => __( 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' ) . "\n\n" . __( 'If you’re looking to paste rich content from Microsoft Word, try turning this option off. The editor will clean up text pasted from Word automatically.' ), 1032 'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help' => __( 'Rich Text Area. Press Alt-Shift-H for help.' ), 1176 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' => 1177 __( 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' ) . "\n\n" . 1178 __( 'If you’re looking to paste rich content from Microsoft Word, try turning this option off. The editor will clean up text pasted from Word automatically.' ), 1179 'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help' => 1180 __( 'Rich Text Area. Press Alt-Shift-H for help.' ), 1033 1181 'Rich Text Area. Press Control-Option-H for help.' => __( 'Rich Text Area. Press Control-Option-H for help.' ), 1034 'You have unsaved changes are you sure you want to navigate away?' => __( 'The changes you made will be lost if you navigate away from this page.' ), 1035 'Your browser doesn\'t support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.' => __( 'Your browser does not support direct access to the clipboard. Please use keyboard shortcuts or your browser’s edit menu instead.' ), 1182 'You have unsaved changes are you sure you want to navigate away?' => 1183 __( 'The changes you made will be lost if you navigate away from this page.' ), 1184 'Your browser doesn\'t support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.' => 1185 __( 'Your browser does not support direct access to the clipboard. Please use keyboard shortcuts or your browser’s edit menu instead.' ), 1036 1186 1037 1187 // TinyMCE menus 1038 1188 'Insert' => _x( 'Insert', 'TinyMCE menu' ), … … private static function get_translation() { 1055 1205 'Paste URL or type to search' => __( 'Paste URL or type to search' ), // Placeholder for the inline link dialog 1056 1206 'Apply' => __( 'Apply' ), // Tooltip for the 'apply' button in the inline link dialog 1057 1207 'Link options' => __( 'Link options' ), // Tooltip for the 'link options' button in the inline link dialog 1208 'Visual' => __( 'Visual' ), // Editor switch tab label 1209 'Text' => __( 'Text' ), // Editor switch tab label 1058 1210 1059 1211 // Shortcuts help modal 1060 1212 'Keyboard Shortcuts' => array( __( 'Keyboard Shortcuts' ), 'accessH' ), … … private static function get_translation() { 1098 1250 } 1099 1251 1100 1252 /** 1101 * Translates the default TinyMCE strings and returns them as JSON encoded object ready to be loaded with tinymce.addI18n() .1102 * Can be used directly (_WP_Editors::wp_mce_translation()) by passing the same locale as set in the TinyMCE init object.1253 * Translates the default TinyMCE strings and returns them as JSON encoded object ready to be loaded with tinymce.addI18n(), 1254 * or as JS snippet that should run after tinymce.js is loaded. 1103 1255 * 1104 1256 * @static 1105 1257 * @param string $mce_locale The locale used for the editor. … … private static function get_translation() { 1108 1260 */ 1109 1261 public static function wp_mce_translation( $mce_locale = '', $json_only = false ) { 1110 1262 if ( ! $mce_locale ) { 1111 $mce_locale = self:: $mce_locale;1263 $mce_locale = self::get_mce_locale(); 1112 1264 } 1113 1265 1114 1266 $mce_translation = self::get_translation(); 1115 1267 1116 1268 foreach ( $mce_translation as $name => $value ) { 1117 1269 if ( is_array( $value ) ) { 1118 1270 $mce_translation[$name] = $value[0]; … … public static function wp_mce_translation( $mce_locale = '', $json_only = false 1150 1302 return wp_json_encode( $mce_translation ); 1151 1303 } 1152 1304 1153 $baseurl = self:: $baseurl ? self::$baseurl : includes_url( 'js/tinymce');1305 $baseurl = self::get_baseurl(); 1154 1306 1155 1307 return "tinymce.addI18n( '$mce_locale', " . wp_json_encode( $mce_translation ) . ");\n" . 1156 1308 "tinymce.ScriptLoader.markDone( '$baseurl/langs/$mce_locale.js' );\n"; 1157 1309 } 1158 1310 1159 1311 /** 1312 * Print (output) the main TinyMCE scripts. 1313 * 1314 * @since 4.8 1160 1315 * 1161 1316 * @static 1162 1317 * @global string $tinymce_version 1163 1318 * @global bool $concatenate_scripts 1164 1319 * @global bool $compress_scripts 1165 1320 */ 1166 public static function editor_js() {1321 public static function print_tinymce_scripts() { 1167 1322 global $tinymce_version, $concatenate_scripts, $compress_scripts; 1168 1323 1169 /** 1170 * Filters "tiny_mce_version" is deprecated 1171 * 1172 * The tiny_mce_version filter is not needed since external plugins are loaded directly by TinyMCE. 1173 * These plugins can be refreshed by appending query string to the URL passed to "mce_external_plugins" filter. 1174 * If the plugin has a popup dialog, a query string can be added to the button action that opens it (in the plugin's code). 1175 */ 1176 $version = 'ver=' . $tinymce_version; 1177 $tmce_on = !empty(self::$mce_settings); 1324 if ( self::$tinymce_scripts_printed ) { 1325 return; 1326 } 1327 1328 self::$tinymce_scripts_printed = true; 1178 1329 1179 if ( ! isset( $concatenate_scripts) )1330 if ( ! isset( $concatenate_scripts ) ) { 1180 1331 script_concat_settings(); 1332 } 1333 1334 $suffix = SCRIPT_DEBUG ? '' : '.min'; 1335 $version = 'ver=' . $tinymce_version; 1336 $baseurl = self::get_baseurl(); 1181 1337 1182 1338 $compressed = $compress_scripts && $concatenate_scripts && isset($_SERVER['HTTP_ACCEPT_ENCODING']) 1183 1339 && false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'); 1184 1340 1341 // Load tinymce.js when running from /src, else load wp-tinymce.js.gz (production) or tinymce.min.js (SCRIPT_DEBUG) 1342 $mce_suffix = false !== strpos( get_bloginfo( 'version' ), '-src' ) ? '' : '.min'; 1343 1344 if ( $compressed ) { 1345 echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce.php?c=1&$version'></script>\n"; 1346 } else { 1347 echo "<script type='text/javascript' src='{$baseurl}/tinymce{$mce_suffix}.js?$version'></script>\n"; 1348 echo "<script type='text/javascript' src='{$baseurl}/plugins/compat3x/plugin{$suffix}.js?$version'></script>\n"; 1349 } 1350 1351 echo "<script type='text/javascript'>\n" . self::wp_mce_translation() . "</script>\n"; 1352 } 1353 1354 /** 1355 * Print (output) the TinyMCE configuration and initialization scripts. 1356 * 1357 * @static 1358 */ 1359 public static function editor_js() { 1360 global $tinymce_version; 1361 1362 $tmce_on = ! empty( self::$mce_settings ); 1185 1363 $mceInit = $qtInit = ''; 1364 1186 1365 if ( $tmce_on ) { 1187 1366 foreach ( self::$mce_settings as $editor_id => $init ) { 1188 1367 $options = self::_parse_init( $init ); 1189 1368 $mceInit .= "'$editor_id':{$options},"; 1190 1369 } 1191 $mceInit = '{' . trim( $mceInit, ',') . '}';1370 $mceInit = '{' . trim( $mceInit, ',' ) . '}'; 1192 1371 } else { 1193 1372 $mceInit = '{}'; 1194 1373 } 1195 1374 1196 if ( ! empty(self::$qt_settings) ) {1375 if ( ! empty( self::$qt_settings ) ) { 1197 1376 foreach ( self::$qt_settings as $editor_id => $init ) { 1198 1377 $options = self::_parse_init( $init ); 1199 1378 $qtInit .= "'$editor_id':{$options},"; 1200 1379 } 1201 $qtInit = '{' . trim( $qtInit, ',') . '}';1380 $qtInit = '{' . trim( $qtInit, ',' ) . '}'; 1202 1381 } else { 1203 1382 $qtInit = '{}'; 1204 1383 } … … public static function editor_js() { 1210 1389 ); 1211 1390 1212 1391 $suffix = SCRIPT_DEBUG ? '' : '.min'; 1392 $baseurl = self::get_baseurl(); 1393 $version = 'ver=' . $tinymce_version; 1213 1394 1214 1395 /** 1215 1396 * Fires immediately before the TinyMCE settings are printed. … … public static function editor_js() { 1223 1404 1224 1405 <script type="text/javascript"> 1225 1406 tinyMCEPreInit = { 1226 baseURL: "<?php echo self::$baseurl; ?>",1407 baseURL: "<?php echo $baseurl; ?>", 1227 1408 suffix: "<?php echo $suffix; ?>", 1228 1409 <?php 1229 1410 … … public static function editor_js() { 1240 1421 </script> 1241 1422 <?php 1242 1423 1243 $baseurl = self::$baseurl;1244 // Load tinymce.js when running from /src, else load wp-tinymce.js.gz (production) or tinymce.min.js (SCRIPT_DEBUG)1245 $mce_suffix = false !== strpos( get_bloginfo( 'version' ), '-src' ) ? '' : '.min';1246 1247 1424 if ( $tmce_on ) { 1248 if ( $compressed ) { 1249 echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce.php?c=1&$version'></script>\n"; 1250 } else { 1251 echo "<script type='text/javascript' src='{$baseurl}/tinymce{$mce_suffix}.js?$version'></script>\n"; 1252 echo "<script type='text/javascript' src='{$baseurl}/plugins/compat3x/plugin{$suffix}.js?$version'></script>\n"; 1253 } 1254 1255 echo "<script type='text/javascript'>\n" . self::wp_mce_translation() . "</script>\n"; 1425 self::print_tinymce_scripts(); 1256 1426 1257 1427 if ( self::$ext_plugins ) { 1258 1428 // Load the old-format English strings to prevent unsightly labels in old style popups … … public static function wp_link_query( $args = array() ) { 1434 1604 * @static 1435 1605 */ 1436 1606 public static function wp_link_dialog() { 1607 // Run once 1608 if ( self::$link_dialog_printed ) { 1609 return; 1610 } 1611 1612 self::$link_dialog_printed = true; 1613 1437 1614 // display: none is required here, see #WP27605 1438 1615 ?> 1439 1616 <div id="wp-link-backdrop" style="display: none"></div> -
src/wp-includes/class-wp-site.php
diff --git a/src/wp-includes/class-wp-site.php b/src/wp-includes/class-wp-site.php index c16f498..4bca299 100644
a b public function __get( $key ) { 240 240 case 'siteurl': 241 241 case 'post_count': 242 242 case 'home': 243 default: // Custom properties added by 'site_details' filter. 243 244 if ( ! did_action( 'ms_loaded' ) ) { 244 245 return null; 245 246 } 247 246 248 $details = $this->get_details(); 247 return $details->$key; 249 if ( isset( $details->$key ) ) { 250 return $details->$key; 251 } 248 252 } 249 253 250 254 return null; … … public function __isset( $key ) { 275 279 return false; 276 280 } 277 281 return true; 282 default: // Custom properties added by 'site_details' filter. 283 if ( ! did_action( 'ms_loaded' ) ) { 284 return false; 285 } 286 287 $details = $this->get_details(); 288 if ( isset( $details->$key ) ) { 289 return true; 290 } 278 291 } 279 292 280 293 return false; -
src/wp-includes/css/admin-bar.css
diff --git a/src/wp-includes/css/admin-bar.css b/src/wp-includes/css/admin-bar.css index fff096d..523b5f7 100644
a b html:lang(he-il) .rtl #wpadminbar * { 624 624 -moz-osx-font-smoothing: grayscale; 625 625 } 626 626 627 /* The admin bar search field needs to reset many styles that might be inherited from the active Theme CSS. See ticket #40313. */ 627 628 #wpadminbar > #wp-toolbar > #wp-admin-bar-top-secondary > #wp-admin-bar-search #adminbarsearch input.adminbar-input { 629 display: inline-block; 630 float: none; 628 631 position: relative; 629 632 z-index: 30; 630 633 font-size: 13px; 631 634 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; 632 635 line-height: 24px; 636 text-indent: 0; 633 637 height: 24px; 634 638 width: 24px; 635 639 max-width: none; -
src/wp-includes/css/buttons.css
diff --git a/src/wp-includes/css/buttons.css b/src/wp-includes/css/buttons.css index 1a614cb..80ecd07 100644
a b TABLE OF CONTENTS: 242 242 243 243 .wp-core-ui .button-link-delete:hover, 244 244 .wp-core-ui .button-link-delete:focus { 245 color: # f00;245 color: #dc3232; 246 246 } 247 247 248 248 .ie8 .wp-core-ui .button-link:focus { … … TABLE OF CONTENTS: 411 411 vertical-align: inherit; 412 412 } 413 413 414 .media-modal-content .media-toolbar-primary .media-button { 415 margin-top: 10px; 416 margin-left: 5px; 417 } 418 414 419 /* Reset responsive styles on Log in button on iframed login form */ 415 420 416 421 .interim-login .button.button-large { -
src/wp-includes/css/editor.css
diff --git a/src/wp-includes/css/editor.css b/src/wp-includes/css/editor.css index e04317e..ca23b91 100644
a b div.mce-path { 608 608 } 609 609 610 610 /* Menubar */ 611 .mce-menubar {611 div.mce-menubar { 612 612 border-color: #e5e5e5; 613 613 background: #fff; 614 614 border-width: 0px 0px 1px; 615 615 } 616 616 617 .mce-menubar .mce-menubtn {618 margin: 2px;619 }620 621 617 .mce-menubar .mce-menubtn:hover, 622 618 .mce-menubar .mce-menubtn.mce-active, 623 619 .mce-menubar .mce-menubtn:focus { … … i.mce-i-wp_code:before { 1091 1087 1092 1088 .wp-editor-container { 1093 1089 clear: both; 1090 border: 1px solid #e5e5e5; 1094 1091 } 1095 1092 1096 1093 .wp-editor-area { -
src/wp-includes/css/media-views.css
diff --git a/src/wp-includes/css/media-views.css b/src/wp-includes/css/media-views.css index 698ea2d..0c0bd6d 100644
a b 242 242 width: calc(48% - 12px); 243 243 } 244 244 245 .media-modal-content .attachments-browser .media-toolbar-secondary {246 width: 66%;247 }248 249 .media-modal-content .media-toolbar-primary.search-form {250 width: 33%;251 }252 253 245 .media-modal-content .media-toolbar-primary .media-button { 254 246 float: right; 255 247 } … … 279 271 overflow: hidden; 280 272 } 281 273 274 .media-frame-toolbar .media-toolbar { 275 top: initial; 276 bottom: -45px; 277 height: auto; 278 overflow: initial; 279 border-top: 1px solid #ddd; 280 } 281 282 @media screen and (max-width: 782px) { 283 .media-frame-toolbar .media-toolbar { 284 bottom: -48px; 285 } 286 } 287 282 288 .media-toolbar-primary { 283 289 float: right; 284 290 height: 100%; … … 686 692 overflow: auto; 687 693 background: #fff; 688 694 border-top: 1px solid #ddd; 689 border-bottom: 1px solid #ddd;690 695 } 691 696 692 697 .media-frame-toolbar { … … 696 701 bottom: 0; 697 702 height: 60px; 698 703 z-index: 100; 704 bottom: 60px; 705 height: auto; 699 706 } 700 707 701 708 .media-frame.hide-menu .media-frame-title, -
src/wp-includes/customize/class-wp-customize-color-control.php
diff --git a/src/wp-includes/customize/class-wp-customize-color-control.php b/src/wp-includes/customize/class-wp-customize-color-control.php index 7f6a9b5..775a63d 100644
a b public function render_content() {} 92 92 */ 93 93 public function content_template() { 94 94 ?> 95 <# var defaultValue = ' ',95 <# var defaultValue = '#RRGGBB', defaultValueAttr = '', 96 96 isHueSlider = data.mode === 'hue'; 97 97 98 98 if ( data.defaultValue && ! isHueSlider ) { … … public function content_template() { 101 101 } else { 102 102 defaultValue = data.defaultValue; 103 103 } 104 defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically.104 defaultValueAttr = ' data-default-color=' + defaultValue; // Quotes added automatically. 105 105 } #> 106 106 <label> 107 107 <# if ( data.label ) { #> … … public function content_template() { 114 114 <# if ( isHueSlider ) { #> 115 115 <input class="color-picker-hue" type="text" data-type="hue" /> 116 116 <# } else { #> 117 <input class="color-picker-hex" type="text" maxlength="7" placeholder=" <?php esc_attr_e( 'Hex Value' ); ?>" {{ defaultValue}} />117 <input class="color-picker-hex" type="text" maxlength="7" placeholder="{{ defaultValue }}" {{ defaultValueAttr }} /> 118 118 <# } #> 119 119 </div> 120 120 </label> -
src/wp-includes/general-template.php
diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 04df698..2930c54 100644
a b function wp_editor( $content, $editor_id, $settings = array() ) { 3057 3057 } 3058 3058 3059 3059 /** 3060 * Outputs the editor scripts, stylesheets, and default settings. 3061 * 3062 * The editor can be initialized when needed after page load. 3063 * See wp.editor.initialize() in wp-admin/js/editor.js for initialization options. 3064 * 3065 * @uses _WP_Editors 3066 * @since 4.8.0 3067 */ 3068 function wp_enqueue_editor() { 3069 if ( ! class_exists( '_WP_Editors', false ) ) { 3070 require( ABSPATH . WPINC . '/class-wp-editor.php' ); 3071 } 3072 3073 _WP_Editors::enqueue_default_editor(); 3074 } 3075 3076 /** 3060 3077 * Retrieves the contents of the search WordPress query variable. 3061 3078 * 3062 3079 * The search query string is passed through esc_attr() to ensure that it is safe -
src/wp-includes/js/mce-view.js
diff --git a/src/wp-includes/js/mce-view.js b/src/wp-includes/js/mce-view.js index 21b2c87..397af63 100644
a b 729 729 $( node ).data( 'rendered', false ); 730 730 editor.dom.setAttrib( node, 'data-wpview-text', encodeURIComponent( text ) ); 731 731 wp.mce.views.createInstance( type, text, match.options, force ).render(); 732 733 editor.selection.select( node ); 734 editor.nodeChanged(); 732 735 editor.focus(); 733 736 734 737 return true; -
src/wp-includes/js/swfupload/handlers.js
diff --git a/src/wp-includes/js/swfupload/handlers.js b/src/wp-includes/js/swfupload/handlers.js index e27bd37..8251f05 100644
a b function cancelUpload() { 356 356 357 357 // remember the last used image size, alignment and url 358 358 jQuery(document).ready(function($){ 359 $( 'input[type="radio"]', '#media-items').live('click', function(){359 $( 'input[type="radio"]', '#media-items' ).on( 'click', function(){ 360 360 var tr = $(this).closest('tr'); 361 361 362 362 if ( $(tr).hasClass('align') ) … … jQuery(document).ready(function($){ 365 365 setUserSetting('imgsize', $(this).val()); 366 366 }); 367 367 368 $( 'button.button', '#media-items').live('click', function(){368 $( 'button.button', '#media-items' ).on( 'click', function(){ 369 369 var c = this.className || ''; 370 370 c = c.match(/url([^ '"]+)/); 371 371 if ( c && c[1] ) { -
src/wp-includes/js/tinymce/plugins/wordpress/plugin.js
diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js b/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js index 20cdcd4..08e3cf7 100644
a b tinymce.PluginManager.add( 'wordpress', function( editor ) { 992 992 993 993 function hide( event ) { 994 994 if ( activeToolbar ) { 995 if ( activeToolbar.tempHide || event.type === 'hide' ) {995 if ( activeToolbar.tempHide || event.type === 'hide' || event.type === 'blur' ) { 996 996 activeToolbar.hide(); 997 997 activeToolbar = false; 998 998 } else if ( ( -
src/wp-includes/js/wp-a11y.js
diff --git a/src/wp-includes/js/wp-a11y.js b/src/wp-includes/js/wp-a11y.js index 2507cbc..7ccdd75 100644
a b window.wp = window.wp || {}; 4 4 'use strict'; 5 5 6 6 var $containerPolite, 7 $containerAssertive; 7 $containerAssertive, 8 previousMessage = ''; 8 9 9 10 /** 10 11 * Update the ARIA live notification area text node. … … window.wp = window.wp || {}; 23 24 // Ensure only text is sent to screen readers. 24 25 message = $( '<p>' ).html( message ).text(); 25 26 27 /* 28 * Safari 10+VoiceOver don't announce repeated, identical strings. We use 29 * a `no-break space` to force them to think identical strings are different. 30 * See ticket #36853. 31 */ 32 if ( previousMessage === message ) { 33 message = message + '\u00A0'; 34 } 35 36 previousMessage = message; 37 26 38 if ( $containerAssertive && 'assertive' === ariaLive ) { 27 39 $containerAssertive.text( message ); 28 40 } else if ( $containerPolite ) { -
src/wp-includes/media.php
diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index 195d0f9..6253bd5 100644
a b function wp_enqueue_media( $args = array() ) { 3324 3324 /** 3325 3325 * Allows showing or hiding the "Create Audio Playlist" button in the media library. 3326 3326 * 3327 * By default (if this filter returns `null`), a query will be run to 3328 * determine whether the media library contains any audio items. This 3329 * query is expensive for large media libraries, so it may be desirable for 3330 * sites to override this behavior. 3327 * By default, the "Create Audio Playlist" button will always be shown in 3328 * the media library. If this filter returns `null`, a query will be run 3329 * to determine whether the media library contains any audio items. This 3330 * was the default behavior prior to version 4.8.0, but this query is 3331 * expensive for large media libraries. 3331 3332 * 3332 3333 * @since 4.7.4 3334 * @since 4.8.0 The filter's default value is `true` rather than `null`. 3333 3335 * 3334 3336 * @link https://core.trac.wordpress.org/ticket/31071 3335 3337 * 3336 * @return bool|null Whether to show the button, or `null` for default behavior. 3338 * @param bool|null Whether to show the button, or `null` to decide based 3339 * on whether any audio files exist in the media library. 3337 3340 */ 3338 $ has_audio = apply_filters( 'media_has_audio', null);3339 if ( is_null( $has_audio )) {3340 $ has_audio= $wpdb->get_var( "3341 $show_audio_playlist = apply_filters( 'media_library_show_audio_playlist', true ); 3342 if ( null === $show_audio_playlist ) { 3343 $show_audio_playlist = $wpdb->get_var( " 3341 3344 SELECT ID 3342 3345 FROM $wpdb->posts 3343 3346 WHERE post_type = 'attachment' … … function wp_enqueue_media( $args = array() ) { 3349 3352 /** 3350 3353 * Allows showing or hiding the "Create Video Playlist" button in the media library. 3351 3354 * 3352 * By default (if this filter returns `null`), a query will be run to 3353 * determine whether the media library contains any video items. This 3354 * query is expensive for large media libraries, so it may be desirable for 3355 * sites to override this behavior. 3355 * By default, the "Create Video Playlist" button will always be shown in 3356 * the media library. If this filter returns `null`, a query will be run 3357 * to determine whether the media library contains any video items. This 3358 * was the default behavior prior to version 4.8.0, but this query is 3359 * expensive for large media libraries. 3356 3360 * 3357 3361 * @since 4.7.4 3362 * @since 4.8.0 The filter's default value is `true` rather than `null`. 3358 3363 * 3359 3364 * @link https://core.trac.wordpress.org/ticket/31071 3360 3365 * 3361 * @return bool|null Whether to show the button, or `null` for default behavior. 3366 * @param bool|null Whether to show the button, or `null` to decide based 3367 * on whether any video files exist in the media library. 3362 3368 */ 3363 $ has_video = apply_filters( 'media_has_video', null);3364 if ( is_null( $has_video )) {3365 $ has_video= $wpdb->get_var( "3369 $show_video_playlist = apply_filters( 'media_library_show_video_playlist', true ); 3370 if ( null === $show_video_playlist ) { 3371 $show_video_playlist = $wpdb->get_var( " 3366 3372 SELECT ID 3367 3373 FROM $wpdb->posts 3368 3374 WHERE post_type = 'attachment' … … function wp_enqueue_media( $args = array() ) { 3383 3389 * 3384 3390 * @link https://core.trac.wordpress.org/ticket/31071 3385 3391 * 3386 * @ returnarray|null An array of objects with `month` and `year`3387 * 3388 * 3392 * @param array|null An array of objects with `month` and `year` 3393 * properties, or `null` (or any other non-array value) 3394 * for default behavior. 3389 3395 */ 3390 $months = apply_filters( 'media_ months', null );3396 $months = apply_filters( 'media_library_months_with_files', null ); 3391 3397 if ( ! is_array( $months ) ) { 3392 3398 $months = $wpdb->get_results( $wpdb->prepare( " 3393 3399 SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month … … function wp_enqueue_media( $args = array() ) { 3414 3420 ), 3415 3421 'defaultProps' => $props, 3416 3422 'attachmentCounts' => array( 3417 'audio' => ( $ has_audio) ? 1 : 0,3418 'video' => ( $ has_video ) ? 1 : 03423 'audio' => ( $show_audio_playlist ) ? 1 : 0, 3424 'video' => ( $show_video_playlist ) ? 1 : 0, 3419 3425 ), 3420 3426 'embedExts' => $exts, 3421 3427 'embedMimes' => $ext_mimes, 3422 3428 'contentWidth' => $content_width, 3423 3429 'months' => $months, 3424 'mediaTrash' => MEDIA_TRASH ? 1 : 0 3430 'mediaTrash' => MEDIA_TRASH ? 1 : 0, 3425 3431 ); 3426 3432 3427 3433 $post = null; -
src/wp-includes/ms-functions.php
diff --git a/src/wp-includes/ms-functions.php b/src/wp-includes/ms-functions.php index 9df86cf..d209435 100644
a b function wp_schedule_update_network_counts() { 2274 2274 * Update the network-wide counts for the current network. 2275 2275 * 2276 2276 * @since 3.1.0 2277 * @since 4.8.0 The $network_id parameter has been added. 2278 * 2279 * @param int|null $network_id ID of the network. Default is the current network. 2277 2280 */ 2278 function wp_update_network_counts( ) {2279 wp_update_network_user_counts( );2280 wp_update_network_site_counts( );2281 function wp_update_network_counts( $network_id = null ) { 2282 wp_update_network_user_counts( $network_id ); 2283 wp_update_network_site_counts( $network_id ); 2281 2284 } 2282 2285 2283 2286 /** … … function wp_maybe_update_network_user_counts() { 2329 2332 * Update the network-wide site count. 2330 2333 * 2331 2334 * @since 3.7.0 2335 * @since 4.8.0 The $network_id parameter has been added. 2332 2336 * 2333 * @ global wpdb $wpdb WordPress database abstraction object.2337 * @param int|null $network_id ID of the network. Default is the current network. 2334 2338 */ 2335 function wp_update_network_site_counts() { 2336 global $wpdb; 2339 function wp_update_network_site_counts( $network_id = null ) { 2340 $network_id = (int) $network_id; 2341 if ( ! $network_id ) { 2342 $network_id = get_current_network_id(); 2343 } 2337 2344 2338 2345 $count = get_sites( array( 2339 'network_id' => $ wpdb->siteid,2346 'network_id' => $network_id, 2340 2347 'spam' => 0, 2341 2348 'deleted' => 0, 2342 2349 'archived' => 0, 2343 2350 'count' => true, 2344 2351 ) ); 2345 2352 2346 update_ site_option('blog_count', $count );2353 update_network_option( $network_id, 'blog_count', $count ); 2347 2354 } 2348 2355 2349 2356 /** 2350 2357 * Update the network-wide user count. 2351 2358 * 2352 2359 * @since 3.7.0 2360 * @since 4.8.0 The $network_id parameter has been added. 2353 2361 * 2354 2362 * @global wpdb $wpdb WordPress database abstraction object. 2363 * 2364 * @param int|null $network_id ID of the network. Default is the current network. 2355 2365 */ 2356 function wp_update_network_user_counts( ) {2366 function wp_update_network_user_counts( $network_id = null ) { 2357 2367 global $wpdb; 2358 2368 2359 2369 $count = $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" ); 2360 update_ site_option('user_count', $count );2370 update_network_option( $network_id, 'user_count', $count ); 2361 2371 } 2362 2372 2363 2373 /** -
src/wp-includes/option.php
diff --git a/src/wp-includes/option.php b/src/wp-includes/option.php index d58ae69..8bc8edc 100644
a b function get_site_transient( $transient ) { 1641 1641 * @see set_transient() 1642 1642 * 1643 1643 * @param string $transient Transient name. Expected to not be SQL-escaped. Must be 1644 * 40characters or fewer in length.1644 * 167 characters or fewer in length. 1645 1645 * @param mixed $value Transient value. Expected to not be SQL-escaped. 1646 1646 * @param int $expiration Optional. Time until expiration in seconds. Default 0 (no expiration). 1647 1647 * @return bool False if value was not set and true if value was set. -
src/wp-includes/post.php
diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index a33236c..0d62400 100644
a b function register_post_status( $post_status, $args = array() ) { 815 815 $args->label = $post_status; 816 816 817 817 if ( false === $args->label_count ) 818 $args->label_count = array( $args->label, $args->label );818 $args->label_count = _n_noop( $args->label, $args->label ); 819 819 820 820 $wp_post_statuses[$post_status] = $args; 821 821 … … function wp_untrash_post_comments( $post = null ) { 2800 2800 * 2801 2801 * @param int $post_id Optional. The Post ID. Does not default to the ID of the 2802 2802 * global $post. Default 0. 2803 * @param array $args Optional. Category arguments. See wp_get_object_terms(). Default empty. 2804 * @return array List of categories. If the `$fields` argument passed via `$args` is 'all' or 2805 * 'all_with_object_id', an array of WP_Term objects will be returned. If `$fields` 2806 * is 'ids', an array of category ids. If `$fields` is 'names', an array of category names. 2803 * @param array $args Optional. Category query parameters. Default empty array. 2804 * See WP_Term_Query::__construct() for supported arguments. 2805 * @return array|WP_Error List of categories. If the `$fields` argument passed via `$args` is 'all' or 2806 * 'all_with_object_id', an array of WP_Term objects will be returned. If `$fields` 2807 * is 'ids', an array of category ids. If `$fields` is 'names', an array of category names. 2808 * WP_Error object if 'category' taxonomy doesn't exist. 2807 2809 */ 2808 2810 function wp_get_post_categories( $post_id = 0, $args = array() ) { 2809 2811 $post_id = (int) $post_id; … … function wp_get_post_categories( $post_id = 0, $args = array() ) { 2826 2828 * 2827 2829 * @param int $post_id Optional. The Post ID. Does not default to the ID of the 2828 2830 * global $post. Default 0. 2829 * @param array $args Optional. Overwrite the defaults 2830 * @return array List of post tags. 2831 * @param array $args Optional. Tag query parameters. Default empty array. 2832 * See WP_Term_Query::__construct() for supported arguments. 2833 * @return array|WP_Error Array of WP_Term objects on success or empty array if no tags were found. 2834 * WP_Error object if 'post_tag' taxonomy doesn't exist. 2831 2835 */ 2832 2836 function wp_get_post_tags( $post_id = 0, $args = array() ) { 2833 2837 return wp_get_post_terms( $post_id, 'post_tag', $args); … … function wp_get_post_tags( $post_id = 0, $args = array() ) { 2845 2849 * @param int $post_id Optional. The Post ID. Does not default to the ID of the 2846 2850 * global $post. Default 0. 2847 2851 * @param string $taxonomy Optional. The taxonomy for which to retrieve terms. Default 'post_tag'. 2848 * @param array $args Optional. wp_get_object_terms() arguments. Default empty array. 2849 * @return array|WP_Error List of post terms or empty array if no terms were found. WP_Error object 2850 * if `$taxonomy` doesn't exist. 2852 * @param array $args Optional. Term query parameters. Default empty array. 2853 * See WP_Term_Query::__construct() for supported arguments. 2854 * @return array|WP_Error Array of WP_Term objects on success or empty array if no terms were found. 2855 * WP_Error object if `$taxonomy` doesn't exist. 2851 2856 */ 2852 2857 function wp_get_post_terms( $post_id = 0, $taxonomy = 'post_tag', $args = array() ) { 2853 2858 $post_id = (int) $post_id; -
src/wp-includes/taxonomy.php
diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php index 94f3668..f1c1bce 100644
a b function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { 1841 1841 1842 1842 $args = wp_parse_args( $args ); 1843 1843 1844 /* 1845 * When one or more queried taxonomies is registered with an 'args' array, 1846 * those params override the `$args` passed to this function. 1847 */ 1848 $terms = array(); 1849 if ( count( $taxonomies ) > 1 ) { 1850 foreach ( $taxonomies as $index => $taxonomy ) { 1851 $t = get_taxonomy( $taxonomy ); 1852 if ( isset( $t->args ) && is_array( $t->args ) && $args != array_merge( $args, $t->args ) ) { 1853 unset( $taxonomies[ $index ] ); 1854 $terms = array_merge( $terms, wp_get_object_terms( $object_ids, $taxonomy, array_merge( $args, $t->args ) ) ); 1855 } 1856 } 1857 } else { 1858 $t = get_taxonomy( $taxonomies[0] ); 1859 if ( isset( $t->args ) && is_array( $t->args ) ) { 1860 $args = array_merge( $args, $t->args ); 1861 } 1862 } 1863 1844 1864 $args['taxonomy'] = $taxonomies; 1845 1865 $args['object_ids'] = $object_ids; 1846 1866 1847 $terms = get_terms( $args);1867 $terms = array_merge( $terms, get_terms( $args ) ); 1848 1868 1849 1869 /** 1850 1870 * Filters the terms for a given object or objects. -
src/wp-includes/user.php
diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index dcd1026..2bb4e05 100644
a b function count_users($strategy = 'time') { 857 857 $select_count = implode(', ', $select_count); 858 858 859 859 // Add the meta_value index to the selection list, then run the query. 860 $row = $wpdb->get_row( "SELECT $select_count, COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'", ARRAY_N ); 860 $row = $wpdb->get_row( " 861 SELECT {$select_count}, COUNT(*) 862 FROM {$wpdb->usermeta} 863 INNER JOIN {$wpdb->users} ON user_id = ID 864 WHERE meta_key = '{$blog_prefix}capabilities' 865 ", ARRAY_N ); 861 866 862 867 // Run the previous loop again to associate results with role names. 863 868 $col = 0; … … function count_users($strategy = 'time') { 881 886 'none' => 0, 882 887 ); 883 888 884 $users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" ); 889 $users_of_blog = $wpdb->get_col( " 890 SELECT meta_value 891 FROM {$wpdb->usermeta} 892 INNER JOIN {$wpdb->users} ON user_id = ID 893 WHERE meta_key = '{$blog_prefix}capabilities' 894 " ); 885 895 886 896 foreach ( $users_of_blog as $caps_meta ) { 887 897 $b_roles = maybe_unserialize($caps_meta); -
tests/phpunit/includes/bootstrap.php
diff --git a/tests/phpunit/includes/bootstrap.php b/tests/phpunit/includes/bootstrap.php index b462e70..1450736 100644
a b 3 3 * Installs WordPress for running the tests and loads WordPress and the test libraries 4 4 */ 5 5 6 /** 7 * Compatibility with PHPUnit 6+ 8 */ 9 if ( class_exists( 'PHPUnit\Runner\Version' ) ) { 10 require_once dirname( __FILE__ ) . '/phpunit6-compat.php'; 11 } 6 12 7 13 $config_file_path = dirname( dirname( __FILE__ ) ); 8 14 if ( ! file_exists( $config_file_path . '/wp-tests-config.php' ) ) { -
new file tests/phpunit/includes/object-cache.php
diff --git a/tests/phpunit/includes/object-cache.php b/tests/phpunit/includes/object-cache.php new file mode 100644 index 0000000..51f3e91
- + 1 <?php 2 /** 3 * Adds a value to cache. 4 * 5 * If the specified key already exists, the value is not stored and the function 6 * returns false. 7 * 8 * @link http://www.php.net/manual/en/memcached.add.php 9 * 10 * @param string $key The key under which to store the value. 11 * @param mixed $value The value to store. 12 * @param string $group The group value appended to the $key. 13 * @param int $expiration The expiration time, defaults to 0. 14 * @return bool Returns TRUE on success or FALSE on failure. 15 */ 16 function wp_cache_add( $key, $value, $group = '', $expiration = 0 ) { 17 global $wp_object_cache; 18 return $wp_object_cache->add( $key, $value, $group, $expiration ); 19 } 20 21 /** 22 * Adds a value to cache on a specific server. 23 * 24 * Using a server_key value, the object can be stored on a specified server as opposed 25 * to a random server in the stack. Note that this method will add the key/value to the 26 * _cache object as part of the runtime cache. It will add it to an array for the 27 * specified server_key. 28 * 29 * @link http://www.php.net/manual/en/memcached.addbykey.php 30 * 31 * @param string $server_key The key identifying the server to store the value on. 32 * @param string $key The key under which to store the value. 33 * @param mixed $value The value to store. 34 * @param string $group The group value appended to the $key. 35 * @param int $expiration The expiration time, defaults to 0. 36 * @return bool Returns TRUE on success or FALSE on failure. 37 */ 38 function wp_cache_add_by_key( $server_key, $key, $value, $group = '', $expiration = 0 ) { 39 global $wp_object_cache; 40 return $wp_object_cache->addByKey( $server_key, $key, $value, $group, $expiration ); 41 } 42 43 /** 44 * Add a single server to the list of Memcached servers. 45 * 46 * @link http://www.php.net/manual/en/memcached.addserver.php 47 * 48 * @param string $host The hostname of the memcache server. 49 * @param int $port The port on which memcache is running. 50 * @param int $weight The weight of the server relative to the total weight of all the servers in the pool. 51 * @return bool Returns TRUE on success or FALSE on failure. 52 */ 53 function wp_cache_add_server( $host, $port, $weight = 0 ) { 54 global $wp_object_cache; 55 return $wp_object_cache->addServer( $host, $port, $weight ); 56 } 57 58 /** 59 * Adds an array of servers to the pool. 60 * 61 * Each individual server in the array must include a domain and port, with an optional 62 * weight value: $servers = array( array( '127.0.0.1', 11211, 0 ) ); 63 * 64 * @link http://www.php.net/manual/en/memcached.addservers.php 65 * 66 * @param array $servers Array of server to register. 67 * @return bool True on success; false on failure. 68 */ 69 function wp_cache_add_servers( $servers ) { 70 global $wp_object_cache; 71 return $wp_object_cache->addServers( $servers ); 72 } 73 74 /** 75 * Append data to an existing item. 76 * 77 * This method should throw an error if it is used with compressed data. This 78 * is an expected behavior. Memcached casts the value to be appended to the initial value to the 79 * type of the initial value. Be careful as this leads to unexpected behavior at times. Due to 80 * how memcached treats types, the behavior has been mimicked in the internal cache to produce 81 * similar results and improve consistency. It is recommend that appends only occur with data of 82 * the same type. 83 * 84 * @link http://www.php.net/manual/en/memcached.append.php 85 * 86 * @param string $key The key under which to store the value. 87 * @param mixed $value Must be string as appending mixed values is not well-defined 88 * @param string $group The group value appended to the $key. 89 * @return bool Returns TRUE on success or FALSE on failure. 90 */ 91 function wp_cache_append( $key, $value, $group = '' ) { 92 global $wp_object_cache; 93 return $wp_object_cache->append( $key, $value, $group ); 94 } 95 96 /** 97 * Append data to an existing item by server key. 98 * 99 * This method should throw an error if it is used with compressed data. This 100 * is an expected behavior. Memcached casts the value to be appended to the initial value to the 101 * type of the initial value. Be careful as this leads to unexpected behavior at times. Due to 102 * how memcached treats types, the behavior has been mimicked in the internal cache to produce 103 * similar results and improve consistency. It is recommend that appends only occur with data of 104 * the same type. 105 * 106 * @link http://www.php.net/manual/en/memcached.appendbykey.php 107 * 108 * @param string $server_key The key identifying the server to store the value on. 109 * @param string $key The key under which to store the value. 110 * @param mixed $value Must be string as appending mixed values is not well-defined 111 * @param string $group The group value appended to the $key. 112 * @return bool Returns TRUE on success or FALSE on failure. 113 */ 114 function wp_cache_append_by_key( $server_key, $key, $value, $group = '' ) { 115 global $wp_object_cache; 116 return $wp_object_cache->appendByKey( $server_key, $key, $value, $group ); 117 } 118 119 /** 120 * Performs a "check and set" to store data. 121 * 122 * The set will be successful only if the no other request has updated the value since it was fetched by 123 * this request. 124 * 125 * @link http://www.php.net/manual/en/memcached.cas.php 126 * 127 * @param float $cas_token Unique value associated with the existing item. Generated by memcached. 128 * @param string $key The key under which to store the value. 129 * @param mixed $value The value to store. 130 * @param string $group The group value appended to the $key. 131 * @param int $expiration The expiration time, defaults to 0. 132 * @return bool Returns TRUE on success or FALSE on failure. 133 */ 134 function wp_cache_cas( $cas_token, $key, $value, $group = '', $expiration = 0 ) { 135 global $wp_object_cache; 136 return $wp_object_cache->cas( $cas_token, $key, $value, $group, $expiration ); 137 } 138 139 /** 140 * Performs a "check and set" to store data with a server key. 141 * 142 * The set will be successful only if the no other request has updated the value since it was fetched by 143 * this request. 144 * 145 * @link http://www.php.net/manual/en/memcached.casbykey.php 146 * 147 * @param string $server_key The key identifying the server to store the value on. 148 * @param float $cas_token Unique value associated with the existing item. Generated by memcached. 149 * @param string $key The key under which to store the value. 150 * @param mixed $value The value to store. 151 * @param string $group The group value appended to the $key. 152 * @param int $expiration The expiration time, defaults to 0. 153 * @return bool Returns TRUE on success or FALSE on failure. 154 */ 155 function wp_cache_cas_by_key( $cas_token, $server_key, $key, $value, $group = '', $expiration = 0 ) { 156 global $wp_object_cache; 157 return $wp_object_cache->casByKey( $cas_token, $server_key, $key, $value, $group, $expiration ); 158 } 159 160 /** 161 * Closes the cache. 162 * 163 * This function has ceased to do anything since WordPress 2.5. The 164 * functionality was removed along with the rest of the persistent cache. This 165 * does not mean that plugins can't implement this function when they need to 166 * make sure that the cache is cleaned up after WordPress no longer needs it. 167 * 168 * @since 2.0.0 169 * 170 * @return bool Always returns True 171 */ 172 function wp_cache_close() { 173 return true; 174 } 175 176 /** 177 * Decrement a numeric item's value. 178 * 179 * @link http://www.php.net/manual/en/memcached.decrement.php 180 * 181 * @param string $key The key under which to store the value. 182 * @param int $offset The amount by which to decrement the item's value. 183 * @param string $group The group value appended to the $key. 184 * @return int|bool Returns item's new value on success or FALSE on failure. 185 */ 186 function wp_cache_decrement( $key, $offset = 1, $group = '' ) { 187 global $wp_object_cache; 188 return $wp_object_cache->decrement( $key, $offset, $group ); 189 } 190 191 /** 192 * Decrement a numeric item's value. 193 * 194 * Same as wp_cache_decrement. Original WordPress caching backends use wp_cache_decr. I 195 * want both spellings to work. 196 * 197 * @link http://www.php.net/manual/en/memcached.decrement.php 198 * 199 * @param string $key The key under which to store the value. 200 * @param int $offset The amount by which to decrement the item's value. 201 * @param string $group The group value appended to the $key. 202 * @return int|bool Returns item's new value on success or FALSE on failure. 203 */ 204 function wp_cache_decr( $key, $offset = 1, $group = '' ) { 205 return wp_cache_decrement( $key, $offset, $group ); 206 } 207 208 /** 209 * Remove the item from the cache. 210 * 211 * Remove an item from memcached with identified by $key after $time seconds. The 212 * $time parameter allows an object to be queued for deletion without immediately 213 * deleting. Between the time that it is queued and the time it's deleted, add, 214 * replace, and get will fail, but set will succeed. 215 * 216 * @link http://www.php.net/manual/en/memcached.delete.php 217 * 218 * @param string $key The key under which to store the value. 219 * @param string $group The group value appended to the $key. 220 * @param int $time The amount of time the server will wait to delete the item in seconds. 221 * @return bool Returns TRUE on success or FALSE on failure. 222 */ 223 function wp_cache_delete( $key, $group = '', $time = 0 ) { 224 global $wp_object_cache; 225 return $wp_object_cache->delete( $key, $group, $time ); 226 } 227 228 /** 229 * Remove the item from the cache by server key. 230 * 231 * Remove an item from memcached with identified by $key after $time seconds. The 232 * $time parameter allows an object to be queued for deletion without immediately 233 * deleting. Between the time that it is queued and the time it's deleted, add, 234 * replace, and get will fail, but set will succeed. 235 * 236 * @link http://www.php.net/manual/en/memcached.deletebykey.php 237 * 238 * @param string $server_key The key identifying the server to store the value on. 239 * @param string $key The key under which to store the value. 240 * @param string $group The group value appended to the $key. 241 * @param int $time The amount of time the server will wait to delete the item in seconds. 242 * @return bool Returns TRUE on success or FALSE on failure. 243 */ 244 function wp_cache_delete_by_key( $server_key, $key, $group = '', $time = 0 ) { 245 global $wp_object_cache; 246 return $wp_object_cache->deleteByKey( $server_key, $key, $group, $time ); 247 } 248 249 /** 250 * Fetch the next result. 251 * 252 * @link http://www.php.net/manual/en/memcached.fetch.php 253 * 254 * @return array|bool Returns the next result or FALSE otherwise. 255 */ 256 function wp_cache_fetch() { 257 global $wp_object_cache; 258 return $wp_object_cache->fetch(); 259 } 260 261 /** 262 * Fetch all remaining results from the last request. 263 * 264 * @link http://www.php.net/manual/en/memcached.fetchall.php 265 * 266 * @return array|bool Returns the results or FALSE on failure. 267 */ 268 function wp_cache_fetch_all() { 269 global $wp_object_cache; 270 return $wp_object_cache->fetchAll(); 271 } 272 273 /** 274 * Invalidate all items in the cache. 275 * 276 * @link http://www.php.net/manual/en/memcached.flush.php 277 * 278 * @param int $delay Number of seconds to wait before invalidating the items. 279 * @return bool Returns TRUE on success or FALSE on failure. 280 */ 281 function wp_cache_flush( $delay = 0 ) { 282 global $wp_object_cache; 283 return $wp_object_cache->flush( $delay ); 284 } 285 286 /** 287 * Retrieve object from cache. 288 * 289 * Gets an object from cache based on $key and $group. In order to fully support the $cache_cb and $cas_token 290 * parameters, the runtime cache is ignored by this function if either of those values are set. If either of 291 * those values are set, the request is made directly to the memcached server for proper handling of the 292 * callback and/or token. 293 * 294 * Note that the $deprecated and $found args are only here for compatibility with the native wp_cache_get function. 295 * 296 * @link http://www.php.net/manual/en/memcached.get.php 297 * 298 * @param string $key The key under which to store the value. 299 * @param string $group The group value appended to the $key. 300 * @param bool $force Whether or not to force a cache invalidation. 301 * @param null|bool $found Variable passed by reference to determine if the value was found or not. 302 * @param null|string $cache_cb Read-through caching callback. 303 * @param null|float $cas_token The variable to store the CAS token in. 304 * @return bool|mixed Cached object value. 305 */ 306 function wp_cache_get( $key, $group = '', $force = false, &$found = null, $cache_cb = null, &$cas_token = null ) { 307 global $wp_object_cache; 308 309 if ( func_num_args() > 4 ) 310 return $wp_object_cache->get( $key, $group, $force, $found, '', false, $cache_cb, $cas_token ); 311 else 312 return $wp_object_cache->get( $key, $group, $force, $found ); 313 } 314 315 /** 316 * Retrieve object from cache from specified server. 317 * 318 * Gets an object from cache based on $key, $group and $server_key. In order to fully support the $cache_cb and $cas_token 319 * parameters, the runtime cache is ignored by this function if either of those values are set. If either of 320 * those values are set, the request is made directly to the memcached server for proper handling of the 321 * callback and/or token. 322 * 323 * @link http://www.php.net/manual/en/memcached.getbykey.php 324 * 325 * @param string $server_key The key identifying the server to store the value on. 326 * @param string $key The key under which to store the value. 327 * @param string $group The group value appended to the $key. 328 * @param bool $force Whether or not to force a cache invalidation. 329 * @param null|bool $found Variable passed by reference to determine if the value was found or not. 330 * @param null|string $cache_cb Read-through caching callback. 331 * @param null|float $cas_token The variable to store the CAS token in. 332 * @return bool|mixed Cached object value. 333 */ 334 function wp_cache_get_by_key( $server_key, $key, $group = '', $force = false, &$found = null, $cache_cb = NULL, &$cas_token = NULL ) { 335 global $wp_object_cache; 336 337 if ( func_num_args() > 5 ) 338 return $wp_object_cache->getByKey( $server_key, $key, $group, $force, $found, $cache_cb, $cas_token ); 339 else 340 return $wp_object_cache->getByKey( $server_key, $key, $group, $force, $found ); 341 } 342 343 /** 344 * Request multiple keys without blocking. 345 * 346 * @link http://www.php.net/manual/en/memcached.getdelayed.php 347 * 348 * @param string|array $keys Array or string of key(s) to request. 349 * @param string|array $groups Array or string of group(s) for the key(s). See buildKeys for more on how these are handled. 350 * @param bool $with_cas Whether to request CAS token values also. 351 * @param null $value_cb The result callback or NULL. 352 * @return bool Returns TRUE on success or FALSE on failure. 353 */ 354 function wp_cache_get_delayed( $keys, $groups = '', $with_cas = false, $value_cb = NULL ) { 355 global $wp_object_cache; 356 return $wp_object_cache->getDelayed( $keys, $groups, $with_cas, $value_cb ); 357 } 358 359 /** 360 * Request multiple keys without blocking from a specified server. 361 * 362 * @link http://www.php.net/manual/en/memcached.getdelayed.php 363 * 364 * @param string $server_key The key identifying the server to store the value on. 365 * @param string|array $keys Array or string of key(s) to request. 366 * @param string|array $groups Array or string of group(s) for the key(s). See buildKeys for more on how these are handled. 367 * @param bool $with_cas Whether to request CAS token values also. 368 * @param null $value_cb The result callback or NULL. 369 * @return bool Returns TRUE on success or FALSE on failure. 370 */ 371 function wp_cache_get_delayed_by_key( $server_key, $keys, $groups = '', $with_cas = false, $value_cb = NULL ) { 372 global $wp_object_cache; 373 return $wp_object_cache->getDelayedByKey( $server_key, $keys, $groups, $with_cas, $value_cb ); 374 } 375 376 /** 377 * Gets multiple values from memcached in one request. 378 * 379 * See the buildKeys method definition to understand the $keys/$groups parameters. 380 * 381 * @link http://www.php.net/manual/en/memcached.getmulti.php 382 * 383 * @param array $keys Array of keys to retrieve. 384 * @param string|array $groups If string, used for all keys. If arrays, corresponds with the $keys array. 385 * @param null|array $cas_tokens The variable to store the CAS tokens for the found items. 386 * @param int $flags The flags for the get operation. 387 * @return bool|array Returns the array of found items or FALSE on failure. 388 */ 389 function wp_cache_get_multi( $keys, $groups = '', &$cas_tokens = NULL, $flags = NULL ) { 390 global $wp_object_cache; 391 392 if ( func_num_args() > 2 ) 393 return $wp_object_cache->getMulti( $keys, $groups, '', $cas_tokens, $flags ); 394 else 395 return $wp_object_cache->getMulti( $keys, $groups ); 396 } 397 398 /** 399 * Gets multiple values from memcached in one request by specified server key. 400 * 401 * See the buildKeys method definition to understand the $keys/$groups parameters. 402 * 403 * @link http://www.php.net/manual/en/memcached.getmultibykey.php 404 * 405 * @param string $server_key The key identifying the server to store the value on. 406 * @param array $keys Array of keys to retrieve. 407 * @param string|array $groups If string, used for all keys. If arrays, corresponds with the $keys array. 408 * @param null|array $cas_tokens The variable to store the CAS tokens for the found items. 409 * @param int $flags The flags for the get operation. 410 * @return bool|array Returns the array of found items or FALSE on failure. 411 */ 412 function wp_cache_get_multi_by_key( $server_key, $keys, $groups = '', &$cas_tokens = NULL, $flags = NULL ) { 413 global $wp_object_cache; 414 415 if ( func_num_args() > 3 ) 416 return $wp_object_cache->getMultiByKey( $server_key, $keys, $groups, $cas_tokens, $flags ); 417 else 418 return $wp_object_cache->getMultiByKey( $server_key, $keys, $groups ); 419 } 420 421 /** 422 * Retrieve a Memcached option value. 423 * 424 * @link http://www.php.net/manual/en/memcached.getoption.php 425 * 426 * @param int $option One of the Memcached::OPT_* constants. 427 * @return mixed Returns the value of the requested option, or FALSE on error. 428 */ 429 function wp_cache_get_option( $option ) { 430 global $wp_object_cache; 431 return $wp_object_cache->getOption( $option ); 432 } 433 434 /** 435 * Return the result code of the last option. 436 * 437 * @link http://www.php.net/manual/en/memcached.getresultcode.php 438 * 439 * @return int Result code of the last Memcached operation. 440 */ 441 function wp_cache_get_result_code() { 442 global $wp_object_cache; 443 return $wp_object_cache->getResultCode(); 444 } 445 446 /** 447 * Return the message describing the result of the last operation. 448 * 449 * @link http://www.php.net/manual/en/memcached.getresultmessage.php 450 * 451 * @return string Message describing the result of the last Memcached operation. 452 */ 453 function wp_cache_get_result_message() { 454 global $wp_object_cache; 455 return $wp_object_cache->getResultMessage(); 456 } 457 458 /** 459 * Get server information by key. 460 * 461 * @link http://www.php.net/manual/en/memcached.getserverbykey.php 462 * 463 * @param string $server_key The key identifying the server to store the value on. 464 * @return array Array with host, post, and weight on success, FALSE on failure. 465 */ 466 function wp_cache_get_server_by_key( $server_key ) { 467 global $wp_object_cache; 468 return $wp_object_cache->getServerByKey( $server_key ); 469 } 470 471 /** 472 * Get the list of servers in the pool. 473 * 474 * @link http://www.php.net/manual/en/memcached.getserverlist.php 475 * 476 * @return array The list of all servers in the server pool. 477 */ 478 function wp_cache_get_server_list() { 479 global $wp_object_cache; 480 return $wp_object_cache->getServerList(); 481 } 482 483 /** 484 * Get server pool statistics. 485 * 486 * @link http://www.php.net/manual/en/memcached.getstats.php 487 * 488 * @return array Array of server statistics, one entry per server. 489 */ 490 function wp_cache_get_stats() { 491 global $wp_object_cache; 492 return $wp_object_cache->getStats(); 493 } 494 495 /** 496 * Get server pool memcached version information. 497 * 498 * @link http://www.php.net/manual/en/memcached.getversion.php 499 * 500 * @return array Array of server versions, one entry per server. 501 */ 502 function wp_cache_get_version() { 503 global $wp_object_cache; 504 return $wp_object_cache->getVersion(); 505 } 506 507 /** 508 * Increment a numeric item's value. 509 * 510 * @link http://www.php.net/manual/en/memcached.increment.php 511 * 512 * @param string $key The key under which to store the value. 513 * @param int $offset The amount by which to increment the item's value. 514 * @param string $group The group value appended to the $key. 515 * @return int|bool Returns item's new value on success or FALSE on failure. 516 */ 517 function wp_cache_increment( $key, $offset = 1, $group = '' ) { 518 global $wp_object_cache; 519 return $wp_object_cache->increment( $key, $offset, $group ); 520 } 521 522 /** 523 * Increment a numeric item's value. 524 * 525 * This is the same as wp_cache_increment, but kept for back compatibility. The original 526 * WordPress caching backends use wp_cache_incr. I want both to work. 527 * 528 * @link http://www.php.net/manual/en/memcached.increment.php 529 * 530 * @param string $key The key under which to store the value. 531 * @param int $offset The amount by which to increment the item's value. 532 * @param string $group The group value appended to the $key. 533 * @return int|bool Returns item's new value on success or FALSE on failure. 534 */ 535 function wp_cache_incr( $key, $offset = 1, $group = '' ) { 536 return wp_cache_increment( $key, $offset, $group ); 537 } 538 539 /** 540 * Prepend data to an existing item. 541 * 542 * This method should throw an error if it is used with compressed data. This is an expected behavior. 543 * Memcached casts the value to be prepended to the initial value to the type of the initial value. Be 544 * careful as this leads to unexpected behavior at times. For instance, prepending (float) 45.23 to 545 * (int) 23 will result in 45, because the value is first combined (45.2323) then cast to "integer" 546 * (the original value), which will be (int) 45. Due to how memcached treats types, the behavior has been 547 * mimicked in the internal cache to produce similar results and improve consistency. It is recommend 548 * that prepends only occur with data of the same type. 549 * 550 * @link http://www.php.net/manual/en/memcached.prepend.php 551 * 552 * @param string $key The key under which to store the value. 553 * @param string $value Must be string as prepending mixed values is not well-defined. 554 * @param string $group The group value prepended to the $key. 555 * @return bool Returns TRUE on success or FALSE on failure. 556 */ 557 function wp_cache_prepend( $key, $value, $group = '' ) { 558 global $wp_object_cache; 559 return $wp_object_cache->prepend( $key, $value, $group ); 560 } 561 562 /** 563 * Append data to an existing item by server key. 564 * 565 * This method should throw an error if it is used with compressed data. This is an expected behavior. 566 * Memcached casts the value to be prepended to the initial value to the type of the initial value. Be 567 * careful as this leads to unexpected behavior at times. For instance, prepending (float) 45.23 to 568 * (int) 23 will result in 45, because the value is first combined (45.2323) then cast to "integer" 569 * (the original value), which will be (int) 45. Due to how memcached treats types, the behavior has been 570 * mimicked in the internal cache to produce similar results and improve consistency. It is recommend 571 * that prepends only occur with data of the same type. 572 * 573 * @link http://www.php.net/manual/en/memcached.prependbykey.php 574 * 575 * @param string $server_key The key identifying the server to store the value on. 576 * @param string $key The key under which to store the value. 577 * @param string $value Must be string as prepending mixed values is not well-defined. 578 * @param string $group The group value prepended to the $key. 579 * @return bool Returns TRUE on success or FALSE on failure. 580 */ 581 function wp_cache_prepend_by_key( $server_key, $key, $value, $group = '' ) { 582 global $wp_object_cache; 583 return $wp_object_cache->prependByKey( $server_key, $key, $value, $group ); 584 } 585 586 /** 587 * Replaces a value in cache. 588 * 589 * This method is similar to "add"; however, is does not successfully set a value if 590 * the object's key is not already set in cache. 591 * 592 * @link http://www.php.net/manual/en/memcached.replace.php 593 * 594 * @param string $key The key under which to store the value. 595 * @param mixed $value The value to store. 596 * @param string $group The group value appended to the $key. 597 * @param int $expiration The expiration time, defaults to 0. 598 * @return bool Returns TRUE on success or FALSE on failure. 599 */ 600 function wp_cache_replace( $key, $value, $group = '', $expiration = 0 ) { 601 global $wp_object_cache; 602 return $wp_object_cache->replace( $key, $value, $group, $expiration ); 603 } 604 605 /** 606 * Replaces a value in cache on a specific server. 607 * 608 * This method is similar to "addByKey"; however, is does not successfully set a value if 609 * the object's key is not already set in cache. 610 * 611 * @link http://www.php.net/manual/en/memcached.addbykey.php 612 * 613 * @param string $server_key The key identifying the server to store the value on. 614 * @param string $key The key under which to store the value. 615 * @param mixed $value The value to store. 616 * @param string $group The group value appended to the $key. 617 * @param int $expiration The expiration time, defaults to 0. 618 * @return bool Returns TRUE on success or FALSE on failure. 619 */ 620 function wp_cache_replace_by_key( $server_key, $key, $value, $group = '', $expiration = 0 ) { 621 global $wp_object_cache; 622 return $wp_object_cache->replaceByKey( $server_key, $key, $value, $group, $expiration ); 623 } 624 625 /** 626 * Sets a value in cache. 627 * 628 * The value is set whether or not this key already exists in memcached. 629 * 630 * @link http://www.php.net/manual/en/memcached.set.php 631 * 632 * @param string $key The key under which to store the value. 633 * @param mixed $value The value to store. 634 * @param string $group The group value appended to the $key. 635 * @param int $expiration The expiration time, defaults to 0. 636 * @return bool Returns TRUE on success or FALSE on failure. 637 */ 638 function wp_cache_set( $key, $value, $group = '', $expiration = 0 ) { 639 global $wp_object_cache; 640 return $wp_object_cache->set( $key, $value, $group, $expiration ); 641 } 642 643 /** 644 * Sets a value in cache. 645 * 646 * The value is set whether or not this key already exists in memcached. 647 * 648 * @link http://www.php.net/manual/en/memcached.set.php 649 * 650 * @param string $server_key The key identifying the server to store the value on. 651 * @param string $key The key under which to store the value. 652 * @param mixed $value The value to store. 653 * @param string $group The group value appended to the $key. 654 * @param int $expiration The expiration time, defaults to 0. 655 * @return bool Returns TRUE on success or FALSE on failure. 656 */ 657 function wp_cache_set_by_key( $server_key, $key, $value, $group = '', $expiration = 0 ) { 658 global $wp_object_cache; 659 return $wp_object_cache->setByKey( $server_key, $key, $value, $group, $expiration ); 660 } 661 662 /** 663 * Set multiple values to cache at once. 664 * 665 * By sending an array of $items to this function, all values are saved at once to 666 * memcached, reducing the need for multiple requests to memcached. The $items array 667 * keys and values are what are stored to memcached. The keys in the $items array 668 * are merged with the $groups array/string value via buildKeys to determine the 669 * final key for the object. 670 * 671 * @param array $items An array of key/value pairs to store on the server. 672 * @param string|array $groups Group(s) to merge with key(s) in $items. 673 * @param int $expiration The expiration time, defaults to 0. 674 * @return bool Returns TRUE on success or FALSE on failure. 675 */ 676 function wp_cache_set_multi( $items, $groups = '', $expiration = 0 ) { 677 global $wp_object_cache; 678 return $wp_object_cache->setMulti( $items, $groups, $expiration ); 679 } 680 681 /** 682 * Set multiple values to cache at once on specified server. 683 * 684 * By sending an array of $items to this function, all values are saved at once to 685 * memcached, reducing the need for multiple requests to memcached. The $items array 686 * keys and values are what are stored to memcached. The keys in the $items array 687 * are merged with the $groups array/string value via buildKeys to determine the 688 * final key for the object. 689 * 690 * @param string $server_key The key identifying the server to store the value on. 691 * @param array $items An array of key/value pairs to store on the server. 692 * @param string|array $groups Group(s) to merge with key(s) in $items. 693 * @param int $expiration The expiration time, defaults to 0. 694 * @return bool Returns TRUE on success or FALSE on failure. 695 */ 696 function wp_cache_set_multi_by_key( $server_key, $items, $groups = 'default', $expiration = 0 ) { 697 global $wp_object_cache; 698 return $wp_object_cache->setMultiByKey( $server_key, $items, $groups, $expiration ); 699 } 700 701 /** 702 * Set a Memcached option. 703 * 704 * @link http://www.php.net/manual/en/memcached.setoption.php 705 * 706 * @param int $option Option name. 707 * @param mixed $value Option value. 708 * @return bool Returns TRUE on success or FALSE on failure. 709 */ 710 function wp_cache_set_option( $option, $value ) { 711 global $wp_object_cache; 712 return $wp_object_cache->setOption( $option, $value ); 713 } 714 715 /** 716 * Switch blog prefix, which changes the cache that is accessed. 717 * 718 * @param int $blog_id Blog to switch to. 719 * @return void 720 */ 721 function wp_cache_switch_to_blog( $blog_id ) { 722 global $wp_object_cache; 723 return $wp_object_cache->switch_to_blog( $blog_id ); 724 } 725 726 727 /** 728 * Sets up Object Cache Global and assigns it. 729 * 730 * @global WP_Object_Cache $wp_object_cache WordPress Object Cache 731 * @return void 732 */ 733 function wp_cache_init() { 734 global $wp_object_cache; 735 $wp_object_cache = new WP_Object_Cache(); 736 } 737 738 /** 739 * Adds a group or set of groups to the list of non-persistent groups. 740 * 741 * @param string|array $groups A group or an array of groups to add. 742 * @return void 743 */ 744 function wp_cache_add_global_groups( $groups ) { 745 global $wp_object_cache; 746 $wp_object_cache->add_global_groups( $groups ); 747 } 748 749 /** 750 * Adds a group or set of groups to the list of non-Memcached groups. 751 * 752 * @param string|array $groups A group or an array of groups to add. 753 * @return void 754 */ 755 function wp_cache_add_non_persistent_groups( $groups ) { 756 global $wp_object_cache; 757 $wp_object_cache->add_non_persistent_groups( $groups ); 758 } 759 760 class WP_Object_Cache { 761 762 /** 763 * Holds the Memcached object. 764 * 765 * @var Memcached 766 */ 767 public $m; 768 769 /** 770 * Hold the Memcached server details. 771 * 772 * @var array 773 */ 774 public $servers; 775 776 /** 777 * Holds the non-Memcached objects. 778 * 779 * @var array 780 */ 781 public $cache = array(); 782 783 /** 784 * List of global groups. 785 * 786 * @var array 787 */ 788 public $global_groups = array( 'users', 'userlogins', 'usermeta', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss' ); 789 790 /** 791 * List of groups not saved to Memcached. 792 * 793 * @var array 794 */ 795 public $no_mc_groups = array( 'comment', 'counts' ); 796 797 /** 798 * Prefix used for global groups. 799 * 800 * @var string 801 */ 802 public $global_prefix = ''; 803 804 /** 805 * Prefix used for non-global groups. 806 * 807 * @var string 808 */ 809 public $blog_prefix = ''; 810 811 /** 812 * Instantiate the Memcached class. 813 * 814 * Instantiates the Memcached class and returns adds the servers specified 815 * in the $memcached_servers global array. 816 * 817 * @link http://www.php.net/manual/en/memcached.construct.php 818 * 819 * @param null $persistent_id To create an instance that persists between requests, use persistent_id to specify a unique ID for the instance. 820 */ 821 public function __construct( $persistent_id = NULL ) { 822 global $memcached_servers, $blog_id, $table_prefix; 823 824 if ( is_null( $persistent_id ) || ! is_string( $persistent_id ) ) 825 $this->m = new Memcached(); 826 else 827 $this->m = new Memcached( $persistent_id ); 828 829 if ( isset( $memcached_servers ) ) 830 $this->servers = $memcached_servers; 831 else 832 $this->servers = array( array( '127.0.0.1', 11211 ) ); 833 834 $this->addServers( $this->servers ); 835 836 /** 837 * This approach is borrowed from Sivel and Boren. Use the salt for easy cache invalidation and for 838 * multi single WP installs on the same server. 839 */ 840 if ( ! defined( 'WP_CACHE_KEY_SALT' ) ) 841 define( 'WP_CACHE_KEY_SALT', '' ); 842 843 // Assign global and blog prefixes for use with keys 844 if ( function_exists( 'is_multisite' ) ) { 845 $this->global_prefix = ( is_multisite() || defined( 'CUSTOM_USER_TABLE' ) && defined( 'CUSTOM_USER_META_TABLE' ) ) ? '' : $table_prefix; 846 $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ) . ':'; 847 } 848 849 // Setup cacheable values for handling expiration times 850 $this->thirty_days = 60 * 60 * 24 * 30; 851 $this->now = time(); 852 } 853 854 /** 855 * Adds a value to cache. 856 * 857 * If the specified key already exists, the value is not stored and the function 858 * returns false. 859 * 860 * @link http://www.php.net/manual/en/memcached.add.php 861 * 862 * @param string $key The key under which to store the value. 863 * @param mixed $value The value to store. 864 * @param string $group The group value appended to the $key. 865 * @param int $expiration The expiration time, defaults to 0. 866 * @param string $server_key The key identifying the server to store the value on. 867 * @param bool $byKey True to store in internal cache by key; false to not store by key 868 * @return bool Returns TRUE on success or FALSE on failure. 869 */ 870 public function add( $key, $value, $group = 'default', $expiration = 0, $server_key = '', $byKey = false ) { 871 /* 872 * Ensuring that wp_suspend_cache_addition is defined before calling, because sometimes an advanced-cache.php 873 * file will load object-cache.php before wp-includes/functions.php is loaded. In those cases, if wp_cache_add 874 * is called in advanced-cache.php before any more of WordPress is loaded, we get a fatal error because 875 * wp_suspend_cache_addition will not be defined until wp-includes/functions.php is loaded. 876 */ 877 if ( function_exists( 'wp_suspend_cache_addition' ) && wp_suspend_cache_addition() ) { 878 return false; 879 } 880 881 $derived_key = $this->buildKey( $key, $group ); 882 $expiration = $this->sanitize_expiration( $expiration ); 883 884 // If group is a non-Memcached group, save to runtime cache, not Memcached 885 if ( in_array( $group, $this->no_mc_groups ) ) { 886 887 // Add does not set the value if the key exists; mimic that here 888 if ( isset( $this->cache[$derived_key] ) ) 889 return false; 890 891 $this->add_to_internal_cache( $derived_key, $value ); 892 893 return true; 894 } 895 896 // Save to Memcached 897 if ( $byKey ) 898 $result = $this->m->addByKey( $server_key, $derived_key, $value, $expiration ); 899 else 900 $result = $this->m->add( $derived_key, $value, $expiration ); 901 902 // Store in runtime cache if add was successful 903 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) 904 $this->add_to_internal_cache( $derived_key, $value ); 905 906 return $result; 907 } 908 909 /** 910 * Adds a value to cache on a specific server. 911 * 912 * Using a server_key value, the object can be stored on a specified server as opposed 913 * to a random server in the stack. Note that this method will add the key/value to the 914 * _cache object as part of the runtime cache. It will add it to an array for the 915 * specified server_key. 916 * 917 * @link http://www.php.net/manual/en/memcached.addbykey.php 918 * 919 * @param string $server_key The key identifying the server to store the value on. 920 * @param string $key The key under which to store the value. 921 * @param mixed $value The value to store. 922 * @param string $group The group value appended to the $key. 923 * @param int $expiration The expiration time, defaults to 0. 924 * @return bool Returns TRUE on success or FALSE on failure. 925 */ 926 public function addByKey( $server_key, $key, $value, $group = 'default', $expiration = 0 ) { 927 return $this->add( $key, $value, $group, $expiration, $server_key, true ); 928 } 929 930 /** 931 * Add a single server to the list of Memcached servers. 932 * 933 * @link http://www.php.net/manual/en/memcached.addserver.php 934 * 935 * @param string $host The hostname of the memcache server. 936 * @param int $port The port on which memcache is running. 937 * @param int $weight The weight of the server relative to the total weight of all the servers in the pool. 938 * @return bool Returns TRUE on success or FALSE on failure. 939 */ 940 public function addServer( $host, $port, $weight = 0 ) { 941 $host = is_string( $host ) ? $host : '127.0.0.1'; 942 $port = is_numeric( $port ) && $port > 0 ? $port : 11211; 943 $weight = is_numeric( $weight ) && $weight > 0 ? $weight : 1; 944 945 return $this->m->addServer( $host, $port, $weight ); 946 } 947 948 /** 949 * Adds an array of servers to the pool. 950 * 951 * Each individual server in the array must include a domain and port, with an optional 952 * weight value: $servers = array( array( '127.0.0.1', 11211, 0 ) ); 953 * 954 * @link http://www.php.net/manual/en/memcached.addservers.php 955 * 956 * @param array $servers Array of server to register. 957 * @return bool True on success; false on failure. 958 */ 959 public function addServers( $servers ) { 960 if ( ! is_object( $this->m ) ) 961 return false; 962 963 return $this->m->addServers( $servers ); 964 } 965 966 /** 967 * Append data to an existing item. 968 * 969 * This method should throw an error if it is used with compressed data. This 970 * is an expected behavior. Memcached casts the value to be appended to the initial value to the 971 * type of the initial value. Be careful as this leads to unexpected behavior at times. Due to 972 * how memcached treats types, the behavior has been mimicked in the internal cache to produce 973 * similar results and improve consistency. It is recommend that appends only occur with data of 974 * the same type. 975 * 976 * @link http://www.php.net/manual/en/memcached.append.php 977 * 978 * @param string $key The key under which to store the value. 979 * @param mixed $value Must be string as appending mixed values is not well-defined. 980 * @param string $group The group value appended to the $key. 981 * @param string $server_key The key identifying the server to store the value on. 982 * @param bool $byKey True to store in internal cache by key; false to not store by key 983 * @return bool Returns TRUE on success or FALSE on failure. 984 */ 985 public function append( $key, $value, $group = 'default', $server_key = '', $byKey = false ) { 986 if ( ! is_string( $value ) && ! is_int( $value ) && ! is_float( $value ) ) 987 return false; 988 989 $derived_key = $this->buildKey( $key, $group ); 990 991 // If group is a non-Memcached group, append to runtime cache value, not Memcached 992 if ( in_array( $group, $this->no_mc_groups ) ) { 993 if ( ! isset( $this->cache[$derived_key] ) ) 994 return false; 995 996 $combined = $this->combine_values( $this->cache[$derived_key], $value, 'app' ); 997 $this->add_to_internal_cache( $derived_key, $combined ); 998 return true; 999 } 1000 1001 // Append to Memcached value 1002 if ( $byKey ) 1003 $result = $this->m->appendByKey( $server_key, $derived_key, $value ); 1004 else 1005 $result = $this->m->append( $derived_key, $value ); 1006 1007 // Store in runtime cache if add was successful 1008 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) { 1009 $combined = $this->combine_values( $this->cache[$derived_key], $value, 'app' ); 1010 $this->add_to_internal_cache( $derived_key, $combined ); 1011 } 1012 1013 return $result; 1014 } 1015 1016 /** 1017 * Append data to an existing item by server key. 1018 * 1019 * This method should throw an error if it is used with compressed data. This 1020 * is an expected behavior. Memcached casts the value to be appended to the initial value to the 1021 * type of the initial value. Be careful as this leads to unexpected behavior at times. Due to 1022 * how memcached treats types, the behavior has been mimicked in the internal cache to produce 1023 * similar results and improve consistency. It is recommend that appends only occur with data of 1024 * the same type. 1025 * 1026 * @link http://www.php.net/manual/en/memcached.appendbykey.php 1027 * 1028 * @param string $server_key The key identifying the server to store the value on. 1029 * @param string $key The key under which to store the value. 1030 * @param mixed $value Must be string as appending mixed values is not well-defined 1031 * @param string $group The group value appended to the $key. 1032 * @return bool Returns TRUE on success or FALSE on failure. 1033 */ 1034 public function appendByKey( $server_key, $key, $value, $group = 'default' ) { 1035 return $this->append( $key, $value, $group, $server_key, true ); 1036 } 1037 1038 /** 1039 * Performs a "check and set" to store data. 1040 * 1041 * The set will be successful only if the no other request has updated the value since it was fetched since 1042 * this request. 1043 * 1044 * @link http://www.php.net/manual/en/memcached.cas.php 1045 * 1046 * @param float $cas_token Unique value associated with the existing item. Generated by memcached. 1047 * @param string $key The key under which to store the value. 1048 * @param mixed $value The value to store. 1049 * @param string $group The group value appended to the $key. 1050 * @param int $expiration The expiration time, defaults to 0. 1051 * @param string $server_key The key identifying the server to store the value on. 1052 * @param bool $byKey True to store in internal cache by key; false to not store by key 1053 * @return bool Returns TRUE on success or FALSE on failure. 1054 */ 1055 public function cas( $cas_token, $key, $value, $group = 'default', $expiration = 0, $server_key = '', $byKey = false ) { 1056 $derived_key = $this->buildKey( $key, $group ); 1057 $expiration = $this->sanitize_expiration( $expiration ); 1058 1059 /** 1060 * If group is a non-Memcached group, save to runtime cache, not Memcached. Note 1061 * that since check and set cannot be emulated in the run time cache, this value 1062 * operation is treated as a normal "add" for no_mc_groups. 1063 */ 1064 if ( in_array( $group, $this->no_mc_groups ) ) { 1065 $this->add_to_internal_cache( $derived_key, $value ); 1066 return true; 1067 } 1068 1069 // Save to Memcached 1070 if ( $byKey ) 1071 $result = $this->m->casByKey( $cas_token, $server_key, $derived_key, $value, $expiration ); 1072 else 1073 $result = $this->m->cas( $cas_token, $derived_key, $value, $expiration ); 1074 1075 // Store in runtime cache if cas was successful 1076 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) 1077 $this->add_to_internal_cache( $derived_key, $value ); 1078 1079 return $result; 1080 } 1081 1082 /** 1083 * Performs a "check and set" to store data with a server key. 1084 * 1085 * The set will be successful only if the no other request has updated the value since it was fetched by 1086 * this request. 1087 * 1088 * @link http://www.php.net/manual/en/memcached.casbykey.php 1089 * 1090 * @param string $server_key The key identifying the server to store the value on. 1091 * @param float $cas_token Unique value associated with the existing item. Generated by memcached. 1092 * @param string $key The key under which to store the value. 1093 * @param mixed $value The value to store. 1094 * @param string $group The group value appended to the $key. 1095 * @param int $expiration The expiration time, defaults to 0. 1096 * @return bool Returns TRUE on success or FALSE on failure. 1097 */ 1098 public function casByKey( $cas_token, $server_key, $key, $value, $group = 'default', $expiration = 0 ) { 1099 return $this->cas( $cas_token, $key, $value, $group, $expiration, $server_key, true ); 1100 } 1101 1102 /** 1103 * Decrement a numeric item's value. 1104 * 1105 * @link http://www.php.net/manual/en/memcached.decrement.php 1106 * 1107 * @param string $key The key under which to store the value. 1108 * @param int $offset The amount by which to decrement the item's value. 1109 * @param string $group The group value appended to the $key. 1110 * @return int|bool Returns item's new value on success or FALSE on failure. 1111 */ 1112 public function decrement( $key, $offset = 1, $group = 'default' ) { 1113 $derived_key = $this->buildKey( $key, $group ); 1114 1115 // Decrement values in no_mc_groups 1116 if ( in_array( $group, $this->no_mc_groups ) ) { 1117 1118 // Only decrement if the key already exists and value is 0 or greater (mimics memcached behavior) 1119 if ( isset( $this->cache[$derived_key] ) && $this->cache[$derived_key] >= 0 ) { 1120 1121 // If numeric, subtract; otherwise, consider it 0 and do nothing 1122 if ( is_numeric( $this->cache[$derived_key] ) ) 1123 $this->cache[$derived_key] -= (int) $offset; 1124 else 1125 $this->cache[$derived_key] = 0; 1126 1127 // Returned value cannot be less than 0 1128 if ( $this->cache[$derived_key] < 0 ) 1129 $this->cache[$derived_key] = 0; 1130 1131 return $this->cache[$derived_key]; 1132 } else { 1133 return false; 1134 } 1135 } 1136 1137 $result = $this->m->decrement( $derived_key, $offset ); 1138 1139 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) 1140 $this->add_to_internal_cache( $derived_key, $result ); 1141 1142 return $result; 1143 } 1144 1145 /** 1146 * Decrement a numeric item's value. 1147 * 1148 * Alias for $this->decrement. Other caching backends use this abbreviated form of the function. It *may* cause 1149 * breakage somewhere, so it is nice to have. This function will also allow the core unit tests to pass. 1150 * 1151 * @param string $key The key under which to store the value. 1152 * @param int $offset The amount by which to decrement the item's value. 1153 * @param string $group The group value appended to the $key. 1154 * @return int|bool Returns item's new value on success or FALSE on failure. 1155 */ 1156 public function decr( $key, $offset = 1, $group = 'default' ) { 1157 return $this->decrement( $key, $offset, $group ); 1158 } 1159 1160 /** 1161 * Remove the item from the cache. 1162 * 1163 * Remove an item from memcached with identified by $key after $time seconds. The 1164 * $time parameter allows an object to be queued for deletion without immediately 1165 * deleting. Between the time that it is queued and the time it's deleted, add, 1166 * replace, and get will fail, but set will succeed. 1167 * 1168 * @link http://www.php.net/manual/en/memcached.delete.php 1169 * 1170 * @param string $key The key under which to store the value. 1171 * @param string $group The group value appended to the $key. 1172 * @param int $time The amount of time the server will wait to delete the item in seconds. 1173 * @param string $server_key The key identifying the server to store the value on. 1174 * @param bool $byKey True to store in internal cache by key; false to not store by key 1175 * @return bool Returns TRUE on success or FALSE on failure. 1176 */ 1177 public function delete( $key, $group = 'default', $time = 0, $server_key = '', $byKey = false ) { 1178 $derived_key = $this->buildKey( $key, $group ); 1179 1180 // Remove from no_mc_groups array 1181 if ( in_array( $group, $this->no_mc_groups ) ) { 1182 if ( isset( $this->cache[$derived_key] ) ) 1183 unset( $this->cache[$derived_key] ); 1184 1185 return true; 1186 } 1187 1188 if ( $byKey ) 1189 $result = $this->m->deleteByKey( $server_key, $derived_key, $time ); 1190 else 1191 $result = $this->m->delete( $derived_key, $time ); 1192 1193 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) 1194 unset( $this->cache[$derived_key] ); 1195 1196 return $result; 1197 } 1198 1199 /** 1200 * Remove the item from the cache by server key. 1201 * 1202 * Remove an item from memcached with identified by $key after $time seconds. The 1203 * $time parameter allows an object to be queued for deletion without immediately 1204 * deleting. Between the time that it is queued and the time it's deleted, add, 1205 * replace, and get will fail, but set will succeed. 1206 * 1207 * @link http://www.php.net/manual/en/memcached.deletebykey.php 1208 * 1209 * @param string $server_key The key identifying the server to store the value on. 1210 * @param string $key The key under which to store the value. 1211 * @param string $group The group value appended to the $key. 1212 * @param int $time The amount of time the server will wait to delete the item in seconds. 1213 * @return bool Returns TRUE on success or FALSE on failure. 1214 */ 1215 public function deleteByKey( $server_key, $key, $group = 'default', $time = 0 ) { 1216 return $this->delete( $key, $group, $time, $server_key, true ); 1217 } 1218 1219 /** 1220 * Fetch the next result. 1221 * 1222 * @link http://www.php.net/manual/en/memcached.fetch.php 1223 * 1224 * @return array|bool Returns the next result or FALSE on failure. 1225 */ 1226 public function fetch() { 1227 return $this->m->fetch(); 1228 } 1229 1230 /** 1231 * Fetch all remaining results from the last request. 1232 * 1233 * @link http://www.php.net/manual/en/memcached.fetchall.php 1234 * 1235 * @return array|bool Returns the results or FALSE on failure. 1236 */ 1237 public function fetchAll() { 1238 return $this->m->fetchAll(); 1239 } 1240 1241 /** 1242 * Invalidate all items in the cache. 1243 * 1244 * @link http://www.php.net/manual/en/memcached.flush.php 1245 * 1246 * @param int $delay Number of seconds to wait before invalidating the items. 1247 * @return bool Returns TRUE on success or FALSE on failure. 1248 */ 1249 public function flush( $delay = 0 ) { 1250 $result = $this->m->flush( $delay ); 1251 1252 // Only reset the runtime cache if memcached was properly flushed 1253 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) 1254 $this->cache = array(); 1255 1256 return $result; 1257 } 1258 1259 /** 1260 * Retrieve object from cache. 1261 * 1262 * Gets an object from cache based on $key and $group. In order to fully support the $cache_cb and $cas_token 1263 * parameters, the runtime cache is ignored by this function if either of those values are set. If either of 1264 * those values are set, the request is made directly to the memcached server for proper handling of the 1265 * callback and/or token. Note that the $cas_token variable cannot be directly passed to the function. The 1266 * variable need to be first defined with a non null value. 1267 * 1268 * If using the $cache_cb argument, the new value will always have an expiration of time of 0 (forever). This 1269 * is a limitation of the Memcached PECL extension. 1270 * 1271 * @link http://www.php.net/manual/en/memcached.get.php 1272 * 1273 * @param string $key The key under which to store the value. 1274 * @param string $group The group value appended to the $key. 1275 * @param bool $force Whether or not to force a cache invalidation. 1276 * @param null|bool $found Variable passed by reference to determine if the value was found or not. 1277 * @param string $server_key The key identifying the server to store the value on. 1278 * @param bool $byKey True to store in internal cache by key; false to not store by key 1279 * @param null|callable $cache_cb Read-through caching callback. 1280 * @param null|float $cas_token The variable to store the CAS token in. 1281 * @return bool|mixed Cached object value. 1282 */ 1283 public function get( $key, $group = 'default', $force = false, &$found = null, $server_key = '', $byKey = false, $cache_cb = NULL, &$cas_token = NULL ) { 1284 $derived_key = $this->buildKey( $key, $group ); 1285 1286 // Assume object is not found 1287 $found = false; 1288 1289 // If either $cache_db, or $cas_token is set, must hit Memcached and bypass runtime cache 1290 if ( func_num_args() > 6 && ! in_array( $group, $this->no_mc_groups ) ) { 1291 if ( $byKey ) 1292 $value = $this->m->getByKey( $server_key, $derived_key, $cache_cb, $cas_token ); 1293 else 1294 $value = $this->m->get( $derived_key, $cache_cb, $cas_token ); 1295 } else { 1296 if ( isset( $this->cache[$derived_key] ) ) { 1297 $found = true; 1298 return is_object( $this->cache[$derived_key] ) ? clone $this->cache[$derived_key] : $this->cache[$derived_key]; 1299 } elseif ( in_array( $group, $this->no_mc_groups ) ) { 1300 return false; 1301 } else { 1302 if ( $byKey ) 1303 $value = $this->m->getByKey( $server_key, $derived_key ); 1304 else 1305 $value = $this->m->get( $derived_key ); 1306 } 1307 } 1308 1309 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) { 1310 $this->add_to_internal_cache( $derived_key, $value ); 1311 $found = true; 1312 } 1313 1314 return is_object( $value ) ? clone $value : $value; 1315 } 1316 1317 /** 1318 * Retrieve object from cache from specified server. 1319 * 1320 * Gets an object from cache based on $key, $group and $server_key. In order to fully support the $cache_cb and $cas_token 1321 * parameters, the runtime cache is ignored by this function if either of those values are set. If either of 1322 * those values are set, the request is made directly to the memcached server for proper handling of the 1323 * callback and/or token. Note that the $cas_token variable cannot be directly passed to the function. The 1324 * variable need to be first defined with a non null value. 1325 * 1326 * If using the $cache_cb argument, the new value will always have an expiration of time of 0 (forever). This 1327 * is a limitation of the Memcached PECL extension. 1328 * 1329 * @link http://www.php.net/manual/en/memcached.getbykey.php 1330 * 1331 * @param string $server_key The key identifying the server to store the value on. 1332 * @param string $key The key under which to store the value. 1333 * @param string $group The group value appended to the $key. 1334 * @param bool $force Whether or not to force a cache invalidation. 1335 * @param null|bool $found Variable passed by reference to determine if the value was found or not. 1336 * @param null|string $cache_cb Read-through caching callback. 1337 * @param null|float $cas_token The variable to store the CAS token in. 1338 * @return bool|mixed Cached object value. 1339 */ 1340 public function getByKey( $server_key, $key, $group = 'default', $force = false, &$found = null, $cache_cb = NULL, &$cas_token = NULL ) { 1341 /** 1342 * Need to be careful how "get" is called. If you send $cache_cb, and $cas_token, it will hit memcached. 1343 * Only send those args if they were sent to this function. 1344 */ 1345 if ( func_num_args() > 5 ) 1346 return $this->get( $key, $group, $force, $found, $server_key, true, $cache_cb, $cas_token ); 1347 else 1348 return $this->get( $key, $group, $force, $found, $server_key, true ); 1349 } 1350 1351 /** 1352 * Request multiple keys without blocking. 1353 * 1354 * @link http://www.php.net/manual/en/memcached.getdelayed.php 1355 * 1356 * @param string|array $keys Array or string of key(s) to request. 1357 * @param string|array $groups Array or string of group(s) for the key(s). See buildKeys for more on how these are handled. 1358 * @param bool $with_cas Whether to request CAS token values also. 1359 * @param null $value_cb The result callback or NULL. 1360 * @return bool Returns TRUE on success or FALSE on failure. 1361 */ 1362 public function getDelayed( $keys, $groups = 'default', $with_cas = false, $value_cb = NULL ) { 1363 $derived_keys = $this->buildKeys( $keys, $groups ); 1364 return $this->m->getDelayed( $derived_keys, $with_cas, $value_cb ); 1365 } 1366 1367 /** 1368 * Request multiple keys without blocking from a specified server. 1369 * 1370 * @link http://www.php.net/manual/en/memcached.getdelayed.php 1371 * 1372 * @param string $server_key The key identifying the server to store the value on. 1373 * @param string|array $keys Array or string of key(s) to request. 1374 * @param string|array $groups Array or string of group(s) for the key(s). See buildKeys for more on how these are handled. 1375 * @param bool $with_cas Whether to request CAS token values also. 1376 * @param null $value_cb The result callback or NULL. 1377 * @return bool Returns TRUE on success or FALSE on failure. 1378 */ 1379 public function getDelayedByKey( $server_key, $keys, $groups = 'default', $with_cas = false, $value_cb = NULL ) { 1380 $derived_keys = $this->buildKeys( $keys, $groups ); 1381 return $this->m->getDelayedByKey( $server_key, $derived_keys, $with_cas, $value_cb ); 1382 } 1383 1384 /** 1385 * Gets multiple values from memcached in one request. 1386 * 1387 * See the buildKeys method definition to understand the $keys/$groups parameters. 1388 * 1389 * @link http://www.php.net/manual/en/memcached.getmulti.php 1390 * 1391 * @param array $keys Array of keys to retrieve. 1392 * @param string|array $groups If string, used for all keys. If arrays, corresponds with the $keys array. 1393 * @param string $server_key The key identifying the server to store the value on. 1394 * @param null|array $cas_tokens The variable to store the CAS tokens for the found items. 1395 * @param int $flags The flags for the get operation. 1396 * @return bool|array Returns the array of found items or FALSE on failure. 1397 */ 1398 public function getMulti( $keys, $groups = 'default', $server_key = '', &$cas_tokens = NULL, $flags = NULL ) { 1399 $derived_keys = $this->buildKeys( $keys, $groups ); 1400 1401 /** 1402 * If either $cas_tokens, or $flags is set, must hit Memcached and bypass runtime cache. Note that 1403 * this will purposely ignore no_mc_groups values as they cannot handle CAS tokens or the special 1404 * flags; however, if the groups of groups contains a no_mc_group, this is bypassed. 1405 */ 1406 if ( func_num_args() > 3 && ! $this->contains_no_mc_group( $groups ) ) { 1407 if ( ! empty( $server_key ) ) 1408 $values = $this->m->getMultiByKey( $server_key, $derived_keys, $cas_tokens, $flags ); 1409 else 1410 $values = $this->m->getMulti( $derived_keys, $cas_tokens, $flags ); 1411 } else { 1412 $values = array(); 1413 $need_to_get = array(); 1414 1415 // Pull out values from runtime cache, or mark for retrieval 1416 foreach ( $derived_keys as $key ) { 1417 if ( isset( $this->cache[$key] ) ) 1418 $values[$key] = $this->cache[$key]; 1419 else 1420 $need_to_get[$key] = $key; 1421 } 1422 1423 // Get those keys not found in the runtime cache 1424 if ( ! empty( $need_to_get ) ) { 1425 if ( ! empty( $server_key ) ) 1426 $result = $this->m->getMultiByKey( $server_key, array_keys( $need_to_get ) ); 1427 else 1428 $result = $this->m->getMulti( array_keys( $need_to_get ) ); 1429 } 1430 1431 // Merge with values found in runtime cache 1432 if ( isset( $result ) && Memcached::RES_SUCCESS === $this->getResultCode() ) 1433 $values = array_merge( $values, $result ); 1434 1435 // If order should be preserved, reorder now 1436 if ( ! empty( $need_to_get ) && $flags === Memcached::GET_PRESERVE_ORDER ) { 1437 $ordered_values = array(); 1438 1439 foreach ( $derived_keys as $key ) { 1440 if ( isset( $values[$key] ) ) 1441 $ordered_values[$key] = $values[$key]; 1442 } 1443 1444 $values = $ordered_values; 1445 unset( $ordered_values ); 1446 } 1447 } 1448 1449 // Add the values to the runtime cache 1450 $this->cache = array_merge( $this->cache, $values ); 1451 1452 return $values; 1453 } 1454 1455 /** 1456 * Gets multiple values from memcached in one request by specified server key. 1457 * 1458 * See the buildKeys method definition to understand the $keys/$groups parameters. 1459 * 1460 * @link http://www.php.net/manual/en/memcached.getmultibykey.php 1461 * 1462 * @param string $server_key The key identifying the server to store the value on. 1463 * @param array $keys Array of keys to retrieve. 1464 * @param string|array $groups If string, used for all keys. If arrays, corresponds with the $keys array. 1465 * @param null|array $cas_tokens The variable to store the CAS tokens for the found items. 1466 * @param int $flags The flags for the get operation. 1467 * @return bool|array Returns the array of found items or FALSE on failure. 1468 */ 1469 public function getMultiByKey( $server_key, $keys, $groups = 'default', &$cas_tokens = NULL, $flags = NULL ) { 1470 /** 1471 * Need to be careful how "getMulti" is called. If you send $cache_cb, and $cas_token, it will hit memcached. 1472 * Only send those args if they were sent to this function. 1473 */ 1474 if ( func_num_args() > 3 ) 1475 return $this->getMulti( $keys, $groups, $server_key, $cas_tokens, $flags ); 1476 else 1477 return $this->getMulti( $keys, $groups, $server_key ); 1478 } 1479 1480 /** 1481 * Retrieve a Memcached option value. 1482 * 1483 * @link http://www.php.net/manual/en/memcached.getoption.php 1484 * 1485 * @param int $option One of the Memcached::OPT_* constants. 1486 * @return mixed Returns the value of the requested option, or FALSE on error. 1487 */ 1488 public function getOption( $option ) { 1489 return $this->m->getOption( $option ); 1490 } 1491 1492 /** 1493 * Return the result code of the last option. 1494 * 1495 * @link http://www.php.net/manual/en/memcached.getresultcode.php 1496 * 1497 * @return int Result code of the last Memcached operation. 1498 */ 1499 public function getResultCode() { 1500 return $this->m->getResultCode(); 1501 } 1502 1503 /** 1504 * Return the message describing the result of the last operation. 1505 * 1506 * @link http://www.php.net/manual/en/memcached.getresultmessage.php 1507 * 1508 * @return string Message describing the result of the last Memcached operation. 1509 */ 1510 public function getResultMessage() { 1511 return $this->m->getResultMessage(); 1512 } 1513 1514 /** 1515 * Get server information by key. 1516 * 1517 * @link http://www.php.net/manual/en/memcached.getserverbykey.php 1518 * 1519 * @param string $server_key The key identifying the server to store the value on. 1520 * @return array Array with host, post, and weight on success, FALSE on failure. 1521 */ 1522 public function getServerByKey( $server_key ) { 1523 return $this->m->getServerByKey( $server_key ); 1524 } 1525 1526 /** 1527 * Get the list of servers in the pool. 1528 * 1529 * @link http://www.php.net/manual/en/memcached.getserverlist.php 1530 * 1531 * @return array The list of all servers in the server pool. 1532 */ 1533 public function getServerList() { 1534 return $this->m->getServerList(); 1535 } 1536 1537 /** 1538 * Get server pool statistics. 1539 * 1540 * @link http://www.php.net/manual/en/memcached.getstats.php 1541 * 1542 * @return array Array of server statistics, one entry per server. 1543 */ 1544 public function getStats() { 1545 return $this->m->getStats(); 1546 } 1547 1548 /** 1549 * Get server pool memcached version information. 1550 * 1551 * @link http://www.php.net/manual/en/memcached.getversion.php 1552 * 1553 * @return array Array of server versions, one entry per server. 1554 */ 1555 public function getVersion() { 1556 return $this->m->getVersion(); 1557 } 1558 1559 /** 1560 * Increment a numeric item's value. 1561 * 1562 * @link http://www.php.net/manual/en/memcached.increment.php 1563 * 1564 * @param string $key The key under which to store the value. 1565 * @param int $offset The amount by which to increment the item's value. 1566 * @param string $group The group value appended to the $key. 1567 * @return int|bool Returns item's new value on success or FALSE on failure. 1568 */ 1569 public function increment( $key, $offset = 1, $group = 'default' ) { 1570 $derived_key = $this->buildKey( $key, $group ); 1571 1572 // Increment values in no_mc_groups 1573 if ( in_array( $group, $this->no_mc_groups ) ) { 1574 1575 // Only increment if the key already exists and the number is currently 0 or greater (mimics memcached behavior) 1576 if ( isset( $this->cache[$derived_key] ) && $this->cache[$derived_key] >= 0 ) { 1577 1578 // If numeric, add; otherwise, consider it 0 and do nothing 1579 if ( is_numeric( $this->cache[$derived_key] ) ) 1580 $this->cache[$derived_key] += (int) $offset; 1581 else 1582 $this->cache[$derived_key] = 0; 1583 1584 // Returned value cannot be less than 0 1585 if ( $this->cache[$derived_key] < 0 ) 1586 $this->cache[$derived_key] = 0; 1587 1588 return $this->cache[$derived_key]; 1589 } else { 1590 return false; 1591 } 1592 } 1593 1594 $result = $this->m->increment( $derived_key, $offset ); 1595 1596 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) 1597 $this->add_to_internal_cache( $derived_key, $result ); 1598 1599 return $result; 1600 } 1601 1602 /** 1603 * Synonymous with $this->incr. 1604 * 1605 * Certain plugins expect an "incr" method on the $wp_object_cache object (e.g., Batcache). Since the original 1606 * version of this library matched names to the memcached methods, the "incr" method was missing. Adding this 1607 * method restores compatibility with plugins expecting an "incr" method. 1608 * 1609 * @param string $key The key under which to store the value. 1610 * @param int $offset The amount by which to increment the item's value. 1611 * @param string $group The group value appended to the $key. 1612 * @return int|bool Returns item's new value on success or FALSE on failure. 1613 */ 1614 public function incr( $key, $offset = 1, $group = 'default' ) { 1615 return $this->increment( $key, $offset, $group ); 1616 } 1617 1618 /** 1619 * Prepend data to an existing item. 1620 * 1621 * This method should throw an error if it is used with compressed data. This is an expected behavior. 1622 * Memcached casts the value to be prepended to the initial value to the type of the initial value. Be 1623 * careful as this leads to unexpected behavior at times. For instance, prepending (float) 45.23 to 1624 * (int) 23 will result in 45, because the value is first combined (45.2323) then cast to "integer" 1625 * (the original value), which will be (int) 45. Due to how memcached treats types, the behavior has been 1626 * mimicked in the internal cache to produce similar results and improve consistency. It is recommend 1627 * that prepends only occur with data of the same type. 1628 * 1629 * @link http://www.php.net/manual/en/memcached.prepend.php 1630 * 1631 * @param string $key The key under which to store the value. 1632 * @param string $value Must be string as prepending mixed values is not well-defined. 1633 * @param string $group The group value prepended to the $key. 1634 * @param string $server_key The key identifying the server to store the value on. 1635 * @param bool $byKey True to store in internal cache by key; false to not store by key 1636 * @return bool Returns TRUE on success or FALSE on failure. 1637 */ 1638 public function prepend( $key, $value, $group = 'default', $server_key = '', $byKey = false ) { 1639 if ( ! is_string( $value ) && ! is_int( $value ) && ! is_float( $value ) ) 1640 return false; 1641 1642 $derived_key = $this->buildKey( $key, $group ); 1643 1644 // If group is a non-Memcached group, prepend to runtime cache value, not Memcached 1645 if ( in_array( $group, $this->no_mc_groups ) ) { 1646 if ( ! isset( $this->cache[$derived_key] ) ) 1647 return false; 1648 1649 $combined = $this->combine_values( $this->cache[$derived_key], $value, 'pre' ); 1650 $this->add_to_internal_cache( $derived_key, $combined ); 1651 return true; 1652 } 1653 1654 // Append to Memcached value 1655 if ( $byKey ) 1656 $result = $this->m->prependByKey( $server_key, $derived_key, $value ); 1657 else 1658 $result = $this->m->prepend( $derived_key, $value ); 1659 1660 // Store in runtime cache if add was successful 1661 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) { 1662 $combined = $this->combine_values( $this->cache[$derived_key], $value, 'pre' ); 1663 $this->add_to_internal_cache( $derived_key, $combined ); 1664 } 1665 1666 return $result; 1667 } 1668 1669 /** 1670 * Append data to an existing item by server key. 1671 * 1672 * This method should throw an error if it is used with compressed data. This is an expected behavior. 1673 * Memcached casts the value to be prepended to the initial value to the type of the initial value. Be 1674 * careful as this leads to unexpected behavior at times. For instance, prepending (float) 45.23 to 1675 * (int) 23 will result in 45, because the value is first combined (45.2323) then cast to "integer" 1676 * (the original value), which will be (int) 45. Due to how memcached treats types, the behavior has been 1677 * mimicked in the internal cache to produce similar results and improve consistency. It is recommend 1678 * that prepends only occur with data of the same type. 1679 * 1680 * @link http://www.php.net/manual/en/memcached.prependbykey.php 1681 * 1682 * @param string $server_key The key identifying the server to store the value on. 1683 * @param string $key The key under which to store the value. 1684 * @param string $value Must be string as prepending mixed values is not well-defined. 1685 * @param string $group The group value prepended to the $key. 1686 * @return bool Returns TRUE on success or FALSE on failure. 1687 */ 1688 public function prependByKey( $server_key, $key, $value, $group = 'default' ) { 1689 return $this->prepend( $key, $value, $group, $server_key, true ); 1690 } 1691 1692 /** 1693 * Replaces a value in cache. 1694 * 1695 * This method is similar to "add"; however, is does not successfully set a value if 1696 * the object's key is not already set in cache. 1697 * 1698 * @link http://www.php.net/manual/en/memcached.replace.php 1699 * 1700 * @param string $server_key The key identifying the server to store the value on. 1701 * @param string $key The key under which to store the value. 1702 * @param mixed $value The value to store. 1703 * @param string $group The group value appended to the $key. 1704 * @param bool $byKey True to store in internal cache by key; false to not store by key 1705 * @param int $expiration The expiration time, defaults to 0. 1706 * @return bool Returns TRUE on success or FALSE on failure. 1707 */ 1708 public function replace( $key, $value, $group = 'default', $expiration = 0, $server_key = '', $byKey = false ) { 1709 $derived_key = $this->buildKey( $key, $group ); 1710 $expiration = $this->sanitize_expiration( $expiration ); 1711 1712 // If group is a non-Memcached group, save to runtime cache, not Memcached 1713 if ( in_array( $group, $this->no_mc_groups ) ) { 1714 1715 // Replace won't save unless the key already exists; mimic this behavior here 1716 if ( ! isset( $this->cache[$derived_key] ) ) 1717 return false; 1718 1719 $this->cache[$derived_key] = $value; 1720 return true; 1721 } 1722 1723 // Save to Memcached 1724 if ( $byKey ) 1725 $result = $this->m->replaceByKey( $server_key, $derived_key, $value, $expiration ); 1726 else 1727 $result = $this->m->replace( $derived_key, $value, $expiration ); 1728 1729 // Store in runtime cache if add was successful 1730 if ( Memcached::RES_SUCCESS === $this->getResultCode() ) 1731 $this->add_to_internal_cache( $derived_key, $value ); 1732 1733 return $result; 1734 } 1735 1736 /** 1737 * Replaces a value in cache on a specific server. 1738 * 1739 * This method is similar to "addByKey"; however, is does not successfully set a value if 1740 * the object's key is not already set in cache. 1741 * 1742 * @link http://www.php.net/manual/en/memcached.addbykey.php 1743 * 1744 * @param string $server_key The key identifying the server to store the value on. 1745 * @param string $key The key under which to store the value. 1746 * @param mixed $value The value to store. 1747 * @param string $group The group value appended to the $key. 1748 * @param int $expiration The expiration time, defaults to 0. 1749 * @return bool Returns TRUE on success or FALSE on failure. 1750 */ 1751 public function replaceByKey( $server_key, $key, $value, $group = 'default', $expiration = 0 ) { 1752 return $this->replace( $key, $value, $group, $expiration, $server_key, true ); 1753 } 1754 1755 /** 1756 * Sets a value in cache. 1757 * 1758 * The value is set whether or not this key already exists in memcached. 1759 * 1760 * @link http://www.php.net/manual/en/memcached.set.php 1761 * 1762 * @param string&nbs